{- | Generate JSON logs compatible with LogZ.io. `logMsgJs` and `formatMsgJs` are both re-exported, so it should not be necessary to import this module directly. TODO: Rename this to LogZ since it generates fields specific to that service. -} {-# LANGUAGE OverloadedStrings #-} module LuminescentDreams.Logger.JSON ( logMsgJs, formatMsgJs ) where import Data.Monoid import qualified Data.Aeson as Aeson import qualified Data.Map as M import Data.String import qualified Data.Text.Format as TF import qualified Data.Text.Lazy.Encoding as TEnc import qualified Data.Time as Time import qualified Data.Text.Lazy as T import LuminescentDreams.Logger.Internal {- | Log a message in LogZ format. This uses `formatMsgJs` to generate the actual format string. -} logMsgJs :: Logger -> LogLevel -> [(String, Aeson.Value)] -> IO () logMsgJs (Logger writer pri) lvl msg = if lvl >= pri then do t <- Time.getCurrentTime writer $ formatMsgJs t lvl msg else return () {- | Format a message for LogZ JSON format. -} formatMsgJs :: Time.UTCTime -> LogLevel -> [(String, Aeson.Value)] -> T.Text formatMsgJs time level msg = let msg_ = msg <> [ ("@timestamp", fromString $ Time.formatTime Time.defaultTimeLocale "%Y-%m-%dT%H:%M:%S" time) , ("@level", Aeson.String $ T.toStrict $ TF.format "{}" (TF.Only level)) ] in TEnc.decodeUtf8 $ Aeson.encode $ M.fromList msg_