extensible-effects-concurrent 0.21.0 → 0.21.1
raw patch · 8 files changed
+125/−96 lines, 8 filesdep +networkdep −socketdep −socket-unixPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: network
Dependencies removed: socket, socket-unix
API changes (from Hackage documentation)
- Control.Eff.Concurrent: fromServer :: forall api_aTEg api_aTNG. Iso (Server api_aTEg) (Server api_aTNG) ProcessId ProcessId
+ Control.Eff.Concurrent: fromServer :: forall api_aTEM api_aTOc. Iso (Server api_aTEM) (Server api_aTOc) ProcessId ProcessId
- Control.Eff.Concurrent.Api: fromServer :: forall api_aTEg api_aTNG. Iso (Server api_aTEg) (Server api_aTNG) ProcessId ProcessId
+ Control.Eff.Concurrent.Api: fromServer :: forall api_aTEM api_aTOc. Iso (Server api_aTEM) (Server api_aTOc) ProcessId ProcessId
- Control.Eff.LogWriter.UDP: withUDPLogWriter :: (Lifted IO e, LogsTo IO e, MonadBaseControl IO (Eff e), HasCallStack) => (LogMessage -> Text) -> Text -> Text -> Eff e b -> Eff e b
+ Control.Eff.LogWriter.UDP: withUDPLogWriter :: (Lifted IO e, LogsTo IO e, MonadBaseControl IO (Eff e), HasCallStack) => (LogMessage -> Text) -> String -> String -> Eff e b -> Eff e b
- Control.Eff.LogWriter.UDP: withUDPLogging :: (HasCallStack, MonadBaseControl IO (Eff e), Lifted IO e) => (LogMessage -> Text) -> Text -> Text -> Text -> Facility -> LogPredicate -> Eff (Logs : (LogWriterReader IO : e)) a -> Eff e a
+ Control.Eff.LogWriter.UDP: withUDPLogging :: (HasCallStack, MonadBaseControl IO (Eff e), Lifted IO e) => (LogMessage -> Text) -> String -> String -> Text -> Facility -> LogPredicate -> Eff (Logs : (LogWriterReader IO : e)) a -> Eff e a
Files
- ChangeLog.md +10/−0
- extensible-effects-concurrent.cabal +3/−4
- src/Control/Eff/Log.hs +56/−22
- src/Control/Eff/Log/Handler.hs +6/−20
- src/Control/Eff/Log/Message.hs +2/−2
- src/Control/Eff/LogWriter/UDP.hs +20/−27
- src/Control/Eff/LogWriter/UnixSocket.hs +28/−19
- stack.yaml +0/−2
ChangeLog.md view
@@ -1,5 +1,15 @@ # Changelog for extensible-effects-concurrent +## 0.21.1++- Remove dependency to the `socket` and `socket-unix` packages+ - they are marked as *broken* by in NixOS+ - the code based on `network` is much shorter++- Rewrite the UDP log writer to use `network`++- Rewrite the UnixSocket log writer to use `network`+ ## 0.21.0 - Add more log message renderers
extensible-effects-concurrent.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: extensible-effects-concurrent-version: 0.21.0+version: 0.21.1 description: Please see the README on GitHub at <https://github.com/sheyll/extensible-effects-concurrent#readme> synopsis: Message passing concurrency as extensible-effect homepage: https://github.com/sheyll/extensible-effects-concurrent#readme@@ -59,9 +59,8 @@ extensible-effects >= 5 && < 6, stm >= 2.4.5 && <2.6, transformers-base >= 0.4 && < 0.5,- socket >= 0.8 && < 0.9,- socket-unix >= 0.2 && < 0.3,- text >= 1.2 && < 1.3+ text >= 1.2 && < 1.3,+ network >=2 && <4 autogen-modules: Paths_extensible_effects_concurrent exposed-modules: Control.Eff.Loop,
src/Control/Eff/Log.hs view
@@ -1,26 +1,16 @@--- | A logging effect.+-- | Logging via @extensible-effects@ ----- There is just one log message type: 'LogMessage' and it is written using 'logMsg' and--- the functions built on top of it.+-- Logging consist of __two__ effects: ----- The 'Logs' effect is tightly coupled with the 'LogWriterReader' effect.--- When using the 'Control.Monad.Trans.ControlMonadBaseControl' instance, the underlying monad of the 'LogWriter',--- that is expected to be present through the respective 'LogWriterReader', is--- constrained to be the base monad itself, e.g. 'IO'.+-- * __Receiving__ log messages sent by the code using e.g. 'logInfo'; this also include deep evaluation and+-- dropping messages not satisfying the current 'LogPredicate'. ----- The log message type is fixed to 'LogMessage', and there is a type class for--- converting to that, call 'ToLogMessage'.+-- * __Writing__ log message to disk, network, ... etc; this also includes rendering log messages and setting+-- fields like the hostname, timestamp, etc ----- There is a single global 'LogPredicate' that can be used to suppress logs directly--- at the point where they are sent, in the 'logMsg' function.+-- == Example ----- Note that all logging is eventually done via 'logMsg'; 'logMsg' is the __only__ place where--- log filtering should happen. ----- Also, 'LogMessage's are evaluated using 'Control.DeepSeq.deepseq', __after__ they pass the 'LogPredicate', also inside 'logMsg'.------ Example:--- -- > exampleLogging :: IO () -- > exampleLogging = -- > runLift@@ -38,16 +28,47 @@ -- > logWarning "test 2.2" -- > logCritical "test 1.3" ----- == Asynchronous Logging+-- == Log Message Data Type ----- Logging in a 'Control.Concurrent.Async.withAsync' spawned thread is done using 'withAsyncLogging'.+-- A singular /logging event/ is contained in a __'LogMessage's__ value. ----- == 'LogPredicate's+-- The 'LogMessage' is modelled along RFC-5424. ----- See "Control.Eff.Log.Handler#LogPredicate"+-- There is the 'ToLogMessage' class for converting to 'LogMessage'.+-- /Although the author is not clear on how to pursue the approach./+--+-- == Receiving and Filtering+--+-- 'LogMessage's are sent using 'logMsg' and friends, see "Control.Eff.Log#SendingLogs"+--+-- === Log Message Predicates+--+-- There is a single global 'LogPredicate' that can be used to suppress logs before+-- they are passed to any 'LogWriter'.+--+-- This is done by the 'logMsg' function.+--+-- Also, 'LogMessage's are evaluated using 'Control.DeepSeq.deepseq', __after__ they pass the 'LogPredicate',+-- also inside 'logMsg'.+--+-- See "Control.Eff.Log#LogPredicate"+--+-- == Writing and Rendering+--+-- Writing is done through a 'LogWriter'; the current 'LogWriter' value to use is held by the+-- 'LogWriterReader' effect.+--+-- === Log Message Rendering+--+-- Message are rendered by 'LogMessageRenderer's found in the "Control.Eff.Log.MessageRenderer".+--+-- === 'LogWriter's+--+-- * Logging in a 'Control.Concurrent.Async.withAsync' spawned thread is done using 'withAsyncLogging'.+ module Control.Eff.Log ( -- * Logging API- -- ** Sending Log Messages+ -- ** Sending Log Messages #SendingLogs# logMsg , logWithSeverity , logWithSeverity'@@ -119,3 +140,16 @@ import Control.Eff.Log.Message import Control.Eff.Log.MessageRenderer import Control.Eff.Log.Writer++-- $LogPredicate+--+-- Ways to change the 'LogPredicate' are:+--+-- * 'setLogPredicate'.+-- * 'modifyLogPredicate'.+-- * 'includeLogMessages'+-- * 'excludeLogMessages'+--+-- The current predicate is retrieved via 'askLogPredicate'.+--+-- Some pre-defined 'LogPredicate's can be found here: "Control.Eff.Log.Message#PredefinedPredicates"
src/Control/Eff/Log/Handler.hs view
@@ -28,7 +28,6 @@ , logDebug' -- ** Log Message Pre-Filtering #LogPredicate#- -- $LogPredicate , includeLogMessages , excludeLogMessages , setLogPredicate@@ -90,7 +89,7 @@ -- | This effect sends 'LogMessage's and is a reader for a 'LogPredicate'. -- -- Logs are sent via 'logMsg';--- for more information about log predicates, see "Control.Eff.Log.Handler#LogPredicate"+-- for more information about log predicates, see "Control.Eff.Log#LogPredicate" -- -- This effect is handled via 'withLogging'. data Logs v where@@ -434,22 +433,9 @@ -> Eff e () logDebug' = withFrozenCallStack (logWithSeverity' debugSeverity) --- $LogPredicate------ Ways to change the 'LogPredicate' are:------ * 'setLogPredicate'.--- * 'modifyLogPredicate'.--- * 'includeLogMessages'--- * 'excludeLogMessages'------ The current predicate is retrieved via 'askLogPredicate'.------ Some pre-defined 'LogPredicate's can be found here: "Control.Eff.Log.Message#PredefinedPredicates"- -- | Get the current 'Logs' filter/transformer function. ----- See "Control.Eff.Log.Handler#LogPredicate"+-- See "Control.Eff.Log#LogPredicate" askLogPredicate :: forall e . (Member Logs e) => Eff e LogPredicate askLogPredicate = send @Logs AskLogFilter @@ -471,7 +457,7 @@ -- -- In order to also delegate to the previous predicate, use 'modifyLogPredicate' ----- See "Control.Eff.Log.Handler#LogPredicate"+-- See "Control.Eff.Log#LogPredicate" setLogPredicate :: forall r b . (Member Logs r, HasCallStack)@@ -493,7 +479,7 @@ -- logMsg "this message might be logged") -- @ ----- See "Control.Eff.Log.Handler#LogPredicate"+-- See "Control.Eff.Log#LogPredicate" modifyLogPredicate :: forall e b . (Member Logs e, HasCallStack)@@ -516,7 +502,7 @@ -- Although it is enough if the previous predicate holds. -- See 'excludeLogMessages' and 'modifyLogPredicate'. ----- See "Control.Eff.Log.Handler#LogPredicate"+-- See "Control.Eff.Log#LogPredicate" includeLogMessages :: forall e a . (Member Logs e) => LogPredicate -> Eff e a -> Eff e a@@ -530,7 +516,7 @@ -- message to be logged. -- See 'excludeLogMessages' and 'modifyLogPredicate'. ----- See "Control.Eff.Log.Handler#LogPredicate"+-- See "Control.Eff.Log#LogPredicate" excludeLogMessages :: forall e a . (Member Logs e) => LogPredicate -> Eff e a -> Eff e a
src/Control/Eff/Log/Message.hs view
@@ -537,12 +537,12 @@ -- * 'discriminateByAppName' -- -- To find out how to use these predicates,--- goto "Control.Eff.Log.Handler#LogPredicate"+-- goto "Control.Eff.Log#LogPredicate" -- | The filter predicate for message that shall be logged. ----- See "Control.Eff.Log.Handler#LogPredicate"+-- See "Control.Eff.Log#LogPredicate" type LogPredicate = LogMessage -> Bool -- | All messages.
src/Control/Eff/LogWriter/UDP.hs view
@@ -7,10 +7,8 @@ import Control.Eff as Eff import Control.Eff.Log-import Control.Eff.LogWriter.Console import Control.Eff.LogWriter.IO import Data.Text as T-import Data.Text.IO as T import Data.Text.Encoding as T import qualified Control.Exception.Safe as Safe import Control.Monad ( void )@@ -19,10 +17,8 @@ , liftBaseOp ) import GHC.Stack-import qualified System.Socket as Socket-import System.Socket.Type.Datagram as Socket-import System.Socket.Family.Inet as Socket-import qualified System.Socket.Protocol.UDP as Socket+import Network.Socket hiding ( sendTo )+import Network.Socket.ByteString -- | Enable logging to a remote host via __UDP__, with some 'LogMessage' fields preset -- as in 'withIoLogging'.@@ -31,8 +27,8 @@ withUDPLogging :: (HasCallStack, MonadBaseControl IO (Eff e), Lifted IO e) => (LogMessage -> Text) -- ^ 'LogMessage' rendering function- -> Text -- ^ Hostname or IP- -> Text -- ^ Port e.g. @"514"@+ -> String -- ^ Hostname or IP+ -> String -- ^ Port e.g. @"514"@ -> Text -- ^ The default application name to put into the 'lmAppName' field. -> Facility -- ^ The default RFC-5424 facility to put into the 'lmFacility' field. -> LogPredicate -- ^ The inital predicate for log messages, there are some pre-defined in "Control.Eff.Log.Message#PredefinedPredicates"@@ -49,8 +45,8 @@ withUDPLogWriter :: (Lifted IO e, LogsTo IO e, MonadBaseControl IO (Eff e), HasCallStack) => (LogMessage -> Text) -- ^ 'LogMessage' rendering function- -> Text -- ^ Hostname or IP- -> Text -- ^ Port e.g. @"514"@+ -> String -- ^ Hostname or IP+ -> String -- ^ Port e.g. @"514"@ -> Eff e b -> Eff e b withUDPLogWriter render hostname port e =@@ -60,28 +56,25 @@ withUDPSocket :: HasCallStack => (LogMessage -> Text) -- ^ 'LogMessage' rendering function- -> Text -- ^ Hostname or IP- -> Text -- ^ Port e.g. @"514"@+ -> String -- ^ Hostname or IP+ -> String -- ^ Port e.g. @"514"@ -> (LogWriter IO -> IO a) -> IO a withUDPSocket render hostname port ioE = Safe.bracket- (Socket.socket :: IO (Socket.Socket Inet Datagram Socket.UDP))- (Safe.try @IO @Catch.SomeException . Socket.close)- (\s -> do- ai <- Socket.getAddressInfo (Just (T.encodeUtf8 hostname))- (Just (T.encodeUtf8 port))- mempty- case ai :: [Socket.AddressInfo Inet Datagram Socket.UDP] of- (a : _) -> do- let addr = Socket.socketAddress a+ (do+ let hints = defaultHints { addrSocketType = Datagram }+ addr : _ <- getAddrInfo (Just hints) (Just hostname) (Just port)+ s <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)+ return (addr, s)+ )+ (Safe.try @IO @Catch.SomeException . close . snd)+ (\(a, s) ->+ let addr = addrAddress a+ in ioE (mkLogWriterIO- (\lmStr -> void- $ Socket.sendTo s (T.encodeUtf8 (render lmStr)) Socket.msgNoSignal addr+ (\lmStr ->+ void $ sendTo s (T.encodeUtf8 (render lmStr)) addr ) )-- [] -> do- T.putStrLn ("could not resolve UDP syslog server: " <> hostname)- ioE consoleLogWriter )
src/Control/Eff/LogWriter/UnixSocket.hs view
@@ -19,11 +19,8 @@ , liftBaseOp ) import GHC.Stack-import qualified System.Socket as Socket-import System.Socket.Type.Datagram as Socket-import System.Socket.Family.Unix as Socket-import qualified System.Socket.Protocol.Default- as Socket+import Network.Socket hiding ( sendTo )+import Network.Socket.ByteString -- | Enable logging to a /unix domain socket/, with some 'LogMessage' fields preset -- as in 'withIoLogging'.@@ -61,19 +58,31 @@ -> (LogWriter IO -> IO a) -> IO a withUnixSocketSocket render socketPath ioE = Safe.bracket- (Socket.socket :: IO (Socket.Socket Unix Datagram Socket.Default))- (Safe.try @IO @Catch.SomeException . Socket.close)- (\s -> case socketAddressUnixPath (T.encodeUtf8 (T.pack socketPath)) of- Just addr -> do- Socket.connect s addr- ioE- (mkLogWriterIO- (\lmStr -> void- $ Socket.send s (T.encodeUtf8 (render lmStr)) Socket.msgNoSignal+ (socket AF_UNIX Datagram defaultProtocol)+ (Safe.try @IO @Catch.SomeException . close)+ (\s ->+ let addr = SockAddrUnix socketPath+ in+ ioE+ (mkLogWriterIO+ (\lmStr ->+ void $ sendTo s (T.encodeUtf8 (render lmStr)) addr+ ) )- )-- Nothing -> do- T.putStrLn $ "could not open unix domain socket: " <> T.pack socketPath- ioE consoleLogWriter )+ -- (Socket.socket :: IO (Socket.Socket Unix Datagram Socket.Default))+ -- (Safe.try @IO @Catch.SomeException . Socket.close)+ -- (\s -> case socketAddressUnixPath (T.encodeUtf8 (T.pack socketPath)) of+ -- Just addr -> do+ -- Socket.connect s addr+ -- ioE+ -- (mkLogWriterIO+ -- (\lmStr -> void+ -- $ Socket.send s (T.encodeUtf8 (render lmStr)) Socket.msgNoSignal+ -- )+ -- )++ -- Nothing -> do+ -- T.putStrLn $ "could not open unix domain socket: " <> T.pack socketPath+ -- ioE consoleLogWriter+ -- )
stack.yaml view
@@ -41,8 +41,6 @@ # (e.g., acme-missiles-0.3) extra-deps: - extensible-effects-5.0.0.1- - socket-unix-0.2.0.0- - socket-0.8.2.0 # Override default flag values for local packages and extra-deps # flags: {}