logging

This module implements a simple logger. It has been designed to be as simple as possible to avoid bloat, if this library does not fulfill your needs, write your own.

Format strings support the following variables which must be prefixed with the dollar operator ($, see example below):

OperatorOutput
$dateCurrent date
$timeCurrent time
$datetime$dateT$time
$appos.getAppFilename()
$appnamebase name of $app
$appdirdirectory name of $app
$levelidfirst letter of log level
$levelnamelog level name

The following example demonstrates logging to three different handlers simultaneously:

var L = newConsoleLogger()
var fL = newFileLogger("test.log", fmtStr = verboseFmtStr)
var rL = newRollingFileLogger("rolling.log", fmtStr = verboseFmtStr)
addHandler(L)
addHandler(fL)
addHandler(rL)
info("920410:52 accepted")
warn("4 8 15 16 23 4-- Error")
error("922044:16 SYSTEM FAILURE")
fatal("SYSTEM FAILURE SYSTEM FAILURE")
# Using the aformetioned operator
var opL = newConsoleLogger(fmtStr = "$datetime :: ")
addHandler(opL)
info("Starting web server...")
# Will print something like 2018-12-17T19:28:05 :: Starting web server...

Warning: The global list of handlers is a thread var, this means that the handlers must be re-added in each thread. Warning: When logging on disk or console, only error and fatal messages are flushed out immediately. Use flushFile() where needed.

Types

Level = enum
  lvlAll,                     ## all levels active
  lvlDebug,                   ## debug level (and any above) active
  lvlInfo,                    ## info level (and any above) active
  lvlNotice,                  ## info notice (and any above) active
  lvlWarn,                    ## warn level (and any above) active
  lvlError,                   ## error level (and any above) active
  lvlFatal,                   ## fatal level (and any above) active
  lvlNone                     ## no levels active
logging level   Source Edit
Logger = ref object of RootObj
  levelThreshold*: Level       ## only messages of level >= levelThreshold
                       ## should be processed
  fmtStr*: string              ## = defaultFmtStr by default, see substituteLog for $date etc.
  
abstract logger; the base type of all loggers   Source Edit
ConsoleLogger = ref object of Logger
  useStderr*: bool             ## will send logs into Stderr if set 
  
logger that writes the messages to the console   Source Edit
FileLogger = ref object of Logger
  file*: File                  ## the wrapped file.
  
logger that writes the messages to a file   Source Edit
RollingFileLogger = ref object of FileLogger
  maxLines: int
  curLine: int
  baseName: string
  baseMode: FileMode
  logFiles: int
  bufSize: int
logger that writes the messages to a file and performs log rotation   Source Edit

Consts

LevelNames: array[Level, string] = ["DEBUG", "DEBUG", "INFO", "NOTICE", "WARN", "ERROR",
                                "FATAL", "NONE"]
  Source Edit
defaultFmtStr = "$levelname "
default format string   Source Edit
verboseFmtStr = "$levelid, [$datetime] -- $appname: "
  Source Edit

Procs

proc substituteLog(frmt: string; level: Level; args: varargs[string, `$`]): string {...}{.
    raises: [], tags: [ReadIOEffect, TimeEffect].}
Format a log message using the frmt format string, level and varargs. See the module documentation for the format string syntax.   Source Edit
proc newConsoleLogger(levelThreshold = lvlAll; fmtStr = defaultFmtStr;
                     useStderr = false): ConsoleLogger {...}{.raises: [], tags: [].}
Creates a new console logger. This logger logs to the console.   Source Edit
proc defaultFilename(): string {...}{.raises: [], tags: [ReadIOEffect].}
Returns the default filename for a logger.   Source Edit
proc newFileLogger(file: File; levelThreshold = lvlAll; fmtStr = defaultFmtStr): FileLogger {...}{.
    raises: [], tags: [].}
Creates a new file logger. This logger logs to file.   Source Edit
proc newFileLogger(filename = defaultFilename(); mode: FileMode = fmAppend;
                  levelThreshold = lvlAll; fmtStr = defaultFmtStr; bufSize: int = -1): FileLogger {...}{.
    raises: [IOError], tags: [].}
Creates a new file logger. This logger logs to a file, specified by fileName. Use bufSize as size of the output buffer when writing the file (-1: use system defaults, 0: unbuffered, >0: fixed buffer size).   Source Edit
proc newRollingFileLogger(filename = defaultFilename();
                         mode: FileMode = fmReadWrite; levelThreshold = lvlAll;
                         fmtStr = defaultFmtStr; maxLines = 1000; bufSize: int = -1): RollingFileLogger {...}{.
    raises: [IOError], tags: [ReadDirEffect, ReadIOEffect].}
Creates a new rolling file logger. Once a file reaches maxLines lines a new log file will be started and the old will be renamed. Use bufSize as size of the output buffer when writing the file (-1: use system defaults, 0: unbuffered, >0: fixed buffer size).   Source Edit
proc addHandler(handler: Logger) {...}{.raises: [], tags: [].}
Adds handler to the list of handlers.   Source Edit
proc getHandlers(): seq[Logger] {...}{.raises: [], tags: [].}
Returns a list of all the registered handlers.   Source Edit
proc setLogFilter(lvl: Level) {...}{.raises: [], tags: [].}
Sets the global log filter.   Source Edit
proc getLogFilter(): Level {...}{.raises: [], tags: [].}
Gets the global log filter.   Source Edit

Methods

method log(logger: Logger; level: Level; args: varargs[string, `$`]) {...}{.
    raises: [Exception], gcsafe, tags: [TimeEffect, WriteIOEffect, ReadIOEffect], base.}
Override this method in custom loggers. Default implementation does nothing.   Source Edit
method log(logger: ConsoleLogger; level: Level; args: varargs[string, `$`]) {...}{.
    raises: [], tags: [ReadIOEffect, TimeEffect, WriteIOEffect].}
Logs to the console using logger only.   Source Edit
method log(logger: FileLogger; level: Level; args: varargs[string, `$`]) {...}{.
    raises: [IOError], tags: [WriteIOEffect, ReadIOEffect, TimeEffect].}
Logs to a file using logger only.   Source Edit
method log(logger: RollingFileLogger; level: Level; args: varargs[string, `$`]) {...}{.
    raises: [OSError, Exception, IOError],
    tags: [ReadIOEffect, WriteIOEffect, TimeEffect].}
Logs to a file using rolling logger only.   Source Edit

Templates

template log(level: Level; args: varargs[string, `$`])
Logs a message to all registered handlers at the given level.   Source Edit
template debug(args: varargs[string, `$`])

Logs a debug message to all registered handlers.

Messages that are useful to the application developer only and are usually turned off in release.

  Source Edit
template info(args: varargs[string, `$`])

Logs an info message to all registered handlers.

Messages that are generated during the normal operation of an application and are of no particular importance. Useful to aggregate for potential later analysis.

  Source Edit
template notice(args: varargs[string, `$`])

Logs an notice message to all registered handlers.

Semantically very similar to info, but meant to be messages you want to be actively notified about (depending on your application). These could be, for example, grouped by hour and mailed out.

  Source Edit
template warn(args: varargs[string, `$`])

Logs a warning message to all registered handlers.

A non-error message that may indicate a potential problem rising or impacted performance.

  Source Edit
template error(args: varargs[string, `$`])

Logs an error message to all registered handlers.

A application-level error condition. For example, some user input generated an exception. The application will continue to run, but functionality or data was impacted, possibly visible to users.

  Source Edit
template fatal(args: varargs[string, `$`])

Logs a fatal error message to all registered handlers.

A application-level fatal condition. FATAL usually means that the application cannot go on and will exit (but this logging event will not do that for you).

  Source Edit