Title here
Summary here
Here’s the translation of the Go logging example to Haskell:
Our logging example demonstrates how to use various logging techniques in Haskell. We’ll use the monad-logger
library for structured logging.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
import Control.Monad.Logger
import System.Log.FastLogger (fromLogStr)
import Data.Time.Clock (getCurrentTime)
import qualified Data.ByteString.Char8 as BS
main :: IO ()
main = runStdoutLoggingT $ do
-- Simple logging
$(logInfo) "standard logger"
-- Logging with timestamp
time <- liftIO getCurrentTime
$(logInfo) $ "with time: " <> showLogTime time
-- Logging with source location
$logInfo "with file/line"
-- Custom logger with prefix
let mylog msg = $(logInfo) $ "my: " <> msg
mylog "from mylog"
-- Changing prefix
let ohmylog msg = $(logInfo) $ "ohmy: " <> msg
ohmylog "from mylog"
-- Logging to a custom target (in this case, a ByteString)
let buflog msg = do
let logStr = fromLogStr $ "buf: " <> msg <> "\n"
liftIO $ BS.putStr logStr
buflog "hello"
-- Structured logging
$(logInfo) $ "hi there" :# []
$(logInfo) $ "hello again" :# ["key" .= ("val" :: String), "age" .= (25 :: Int)]
showLogTime :: Show a => a -> LogStr
showLogTime = toLogStr . show
To run this program, you’ll need to install the necessary libraries and compile the code:
$ stack build monad-logger fast-logger
$ stack ghc -- -O2 logging.hs
$ ./logging
Sample output (the date and time emitted will depend on when the example ran):
[Info] standard logger
[Info] with time: 2023-08-22 10:45:16.904141 UTC
[Info] logging.hs:22:5: with file/line
[Info] my: from mylog
[Info] ohmy: from mylog
buf: hello
[Info] hi there
[Info] hello again @(key = "val", age = 25)
In this Haskell version:
monad-logger
library for structured logging.OverloadedStrings
and TemplateHaskell
language extensions are used to enable string literals and logging macros.BS.putStr
.:# []
syntax for key-value pairs.Note that Haskell’s logging ecosystem is different from Go’s, so we’ve adapted the concepts to fit Haskell’s paradigms while maintaining the spirit of the original example.