never executed always true always false
1 module PureClaw.Handles.Log
2 ( -- * Handle type
3 LogHandle (..)
4 -- * Implementations
5 , mkStderrLogHandle
6 , mkNoOpLogHandle
7 ) where
8
9 import Data.Text (Text)
10 import Data.Text.IO qualified as TIO
11 import Data.Text qualified as T
12 import Data.Time
13 import System.IO
14
15 -- | Logging capability. Functions that only receive a 'LogHandle' cannot
16 -- shell out, read files, or access the network — they can only log.
17 data LogHandle = LogHandle
18 { _lh_logInfo :: Text -> IO ()
19 , _lh_logWarn :: Text -> IO ()
20 , _lh_logError :: Text -> IO ()
21 , _lh_logDebug :: Text -> IO ()
22 }
23
24 -- | Log to stderr with ISO 8601 timestamps and level prefixes.
25 mkStderrLogHandle :: LogHandle
26 mkStderrLogHandle = LogHandle
27 { _lh_logInfo = logWithLevel "INFO"
28 , _lh_logWarn = logWithLevel "WARN"
29 , _lh_logError = logWithLevel "ERROR"
30 , _lh_logDebug = logWithLevel "DEBUG"
31 }
32 where
33 logWithLevel :: Text -> Text -> IO ()
34 logWithLevel level msg = do
35 now <- getCurrentTime
36 let timestamp = T.pack (formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S" now)
37 TIO.hPutStrLn stderr $ "[" <> timestamp <> "] [" <> level <> "] " <> msg
38
39 -- | No-op log handle. All operations silently succeed.
40 mkNoOpLogHandle :: LogHandle
41 mkNoOpLogHandle = LogHandle
42 { _lh_logInfo = \_ -> pure ()
43 , _lh_logWarn = \_ -> pure ()
44 , _lh_logError = \_ -> pure ()
45 , _lh_logDebug = \_ -> pure ()
46 }