Z-IO- Simple and high performance IO toolkit for Haskell
Copyright(c) Dong Han 2017-2018
Safe HaskellNone



Simple, high performance logger. The design choice of this logger is biased towards simplicity instead of generlization:

  • All log functions live in IO.
  • By default this logger is connected to stderr, use setDefaultLogger to customize.
  • When logging each thread will build log Builders into a small Bytes with line buffer instead of leaving all Builders to the flushing thread:

    • Logger won't keep heap data for too long simply because they're referenced by log's Builder.
    • Each logging thread only need perform a CAS to prepend log Bytes into a list, which reduces contention.
    • Each log call is atomic, Logging order is preserved under concurrent settings.

Flushing is automatic and throttled for debug, info, warning to boost performance, but a fatal and critical log will always flush logger's buffer. This could lead to a problem that if main thread exits too early logs may missed, to add a flushing when program exits, use withDefaultLogger like:

import Z.IO.Logger

main :: IO ()
main = withDefaultLogger $ do
    debug "..."   -- So that this log won't be missed

A simple Logger type

data Logger Source #

Extensible logger type.

data LoggerConfig Source #

Logger config type used in this module.




defaultLoggerConfig :: LoggerConfig Source #

A default logger config with

  • 0.1s minimal flush interval
  • line buffer size 240 bytes
  • show everything by default
  • defaultFmt

defaultJSONLoggerConfig :: LoggerConfig Source #

A default logger config with

  • 0.5s minimal flush interval
  • line buffer size 1000 bytes
  • show everything by default
  • defaultJSONFmt

setDefaultLogger :: Logger -> IO () Source #

Change the global logger.

getDefaultLogger :: IO Logger Source #

Get the global logger.

This is a logger connected to stderr, if stderr is connect to TTY, then use defaultColoredFmt, otherwise use defaultFmt.

flushDefaultLogger :: IO () Source #

Manually flush global logger.

withDefaultLogger :: IO () -> IO () Source #

Flush global logger when program exits.

Create a new logger

newLogger :: LoggerConfig -> MVar BufferedOutput -> IO Logger Source #

Make a new logger with given write device.

newStdLogger :: LoggerConfig -> IO Logger Source #

Make a new logger write to stderrBuf.

newFileLogger :: LoggerConfig -> CBytes -> IO Logger Source #

Make a new file based logger with defaultFmt.

The file will be opened in append mode.

logging functions

otherLevel Source #


:: HasCallStack 
=> Level

log level

-> Bool

flush immediately?

-> Builder ()

log content

-> IO () 

logging functions with specific logger

otherLevelTo Source #


:: HasCallStack 
=> Logger 
-> Level

log level

-> Bool

flush immediately?

-> Builder ()

log content

-> IO () 

Helpers to write new log formatter

type LogFormatter Source #


 = Builder ()

data/time string(second precision)

-> Level

log level

-> Builder ()

log content

-> CallStack

call stack trace

-> ThreadId

logging thread id

-> Builder () 

defaultFmt :: LogFormatter Source #

A default log formatter


defaultColoredFmt :: LogFormatter Source #

A default colored log formatter

DEBUG level is Cyan, WARNING level is Yellow, FATAL and CRITICAL level are Red.

defaultJSONFmt :: LogFormatter Source #

A default JSON log formatter.


defaultFmtCallStack :: CallStack -> Builder () Source #

Default stack formatter which fetch the logging source and location.

defaultLevelFmt :: Level -> Builder () Source #

Format DEBUG to DEBUG, etc.

Level other than built-in ones, are formatted in decimal numeric format, i.e. defaultLevelFmt 60 == LEVEL60



type Level = Int Source #

Logging Levels

We following the Python logging levels, for details, see: https://docs.python.org/3/howto/logging.html#logging-levels

LevelNumeric value

pattern DEBUG :: Level Source #

pattern INFO :: Level Source #

pattern WARNING :: Level Source #

pattern FATAL :: Level Source #

pattern CRITICAL :: Level Source #

pattern NOTSET :: Level Source #