MyNixOS website logo
Description

A flexible logging system utilizing the monad-effect effect system.

A flexible logging system utilizing the `monad-effect` effect system, it gives you very fine control over the logging behavior, including custom categories, separation of log generation and rendering, pure logging effect, compatibility with monad-logger, trace-id support, etc.

Flexible Logging with Monad-Effect

monad-effect-logging is a pure structured logging library for the monad-effect ecosystem.

The current API is centered on one unified message payload LogDoc.

Highlights

  • You build one LogDoc value and decide at the boundary how to render it:

    • plain text
    • ANSI colored text
    • different Show strategies
    • custom logger pipelines
  • Color stays semantic until rendering time. A file logger can ignore color while a console logger can emit ANSI codes from the exact same log event.

  • Excellent TraceId support

  • Open log categories, extensible

  • Easy JSON logging by tagging loggerJson

This enables you to easily add JSON logging to your files while keeping the console output colorful and readable: you can write no-color json logging to a file while use pSho and color constructors to display stuff on the screen at the same time.

Core types

  • LogEvent for the event envelope
  • LogWithSourceMeta for source-location metadata
  • LogDoc for the structured log message
  • Logger for the sink
  • LogEffect for the installed effect
data LogEvent a = LogEvent
  { logEventCats :: [LogCat]
  , logEventPayload :: a
  }

data LogWithSourceMeta a = LogWithSourceMeta
  { logMetaLoc :: Maybe Loc
  , logMetaSource :: Maybe LogSource
  , logMetaDoc :: a
  }

newtype Logger m a = Logger
  { runLogger :: LogEvent a -> m ()
  }

data LogEffect m a

data LogDoc

The default installed logging effect is:

type Logging = LogEffect IO LogDoc

Building messages

String literals work through IsString, and deferred values use logShow.

import Module.Logging

example :: (Monad m, In (LogEffect m LogDoc) mods) => EffT mods es m ()
example = do
  $(logTH Info) $ "starting request " <> logShow (42 :: Int)
  $(logTH Warn) $ logFg Yellow "slow query: " <> toLog ("SELECT ..." :: String)

Useful helpers:

  • logRaw
  • logShow
  • logFg
  • logBg
  • logBold
  • toLog

Literal strings can be directly typed in using IsString class, no need to convert using helpers.

Rendering and base loggers

Most applications should use one options-based helper from Module.Logging.Logger:

import Module.Logging
import Module.Logging.Logger

runApp :: EffT '[LogEffect IO LogDoc] NoError IO () -> IO ()
runApp app = do
  stdoutBase <- createSimpleConcurrentStdoutBaseLogger
  fileBase <- createFileLogger "app.log"

  let stdoutLogger = makeLoggerFromBase ( buildLoggerStyle loggerUseAnsi                ) stdoutBase
  let fileLogger   = makeLoggerFromBase ( buildLoggerStyle (loggerJson . loggerNoStyle) ) fileBase

  runEffT00 $ withLoggerCleanup (stdoutLogger <> fileLogger) app

Here each style is a builder function LoggerOptions -> LoggerOptions, and the buildLoggerStyle function is just a composition of them on the defaultLoggerStyle.

For custom pipelines, use the lower-level building blocks:

  • renderLogEvent
  • loggerFromRenderer
  • your own Logger

Styles compose as normal functions:

verboseConsole :: LoggerOptions
verboseConsole =
  buildLoggerStyle
    $ loggerUseAnsi
    . loggerOrder [LogTimeChunk, LogCatChunk, LogLocChunk, LogDocChunk]

Categories

Categories are open and extensible:

data ProxyLog = Bytes | Logic deriving (Lift)
-- The `Lift` class is only necessary if you want to use them inside `logTH` template haskell
-- utilities, otherwise you can remove it.

instance IsLogCat ProxyLog where
  severity Bytes = severity Debug
  severity Logic = severity Info
  logTypeName Bytes = "BYTES"
  logTypeName Logic = "LOGIC"

You can add local categories with effAddLogCat, and filter them with the existing combinators.

MonadLogger compatibility

MonadLogger and MonadLoggerIO are implemented for LogEffect m LogDoc.

Incoming monad-logger messages are wrapped as logRaw, so compatibility fits directly into the unified payload model.

TraceId

This library also provides a super convenient TraceId mechanism that can attach scoped trace IDs to log events. TraceId is just a log category. Use withTraceId or one of the provided generators from Module.Logging.TraceId.

Status

This release presents the library around LogDoc, options-based logger construction, open categories, and boundary-driven rendering.

Metadata

Version

0.3.0.0

Platforms (80)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    uefi
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-uefi
  • aarch64-windows
  • aarch64_be-none
  • arc-linux
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • sh4-linux
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-uefi
  • x86_64-windows