Advanced structured logging framework for Nim with optionally threadsafe writers, filters, formatters, ...
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
.gitignore
CHANGELOG.md
LICENSE.txt
README.md
omnilog.nimble

README.md

omnilog

Omnilog is an advanced logging library for the Nim language.

It supports plain text and structured logging with multiple, pluggable writers which can be seperately filtered and formatted.

Documentation is still lacking a lot of info. Will improve soon.

Install

Omnilog is best installed with Nimble, Nims package manager.

nimble install omnilog

Getting started

This is a simple example showing how to use omnilog with the global logger.

By default, a global logger is setup up that will write to stdout with a simple format for debugging.

You can also retrieve a named sub-logger for a facility.

import omnilog

# Plain log message.
info("Msg")

# Message with interpolation.
error("Msg $1 - $2", 33, 55.55)

# Log fields.
logFields((f1: "x", f2: 11)).warning("Msg")

# Facility.
var appLogger = getLogger("myfacility")

# Limit custom logger to messages of INFO and higher.
appLogger.setSeverity(Severity.INFO)

appLogger.critical("Msg $1", [1, 2, 3])
appLogger.withField("x", 55).debug("Msg") # Will be ignored, since severity is set to INFO.
appLogger.withFields((a: 1, b: "x")).info("msg")

# Nested logger.
appLogger.getLogger("subfacility").warning("Warn")

Concepts

This section explains how omnilog is structured, and how you can customize it.

You can create an arbitrary amount of nested, named loggers.

Each logger has a facility, which is just a string name. This usually corresponds to specific parts of your program.

Each log message has a severity. By default, the syslog severities are supported (see additional information). But you can register your own, custom severities.

Each logger can have multiple formatters, which transform the log message. They can add fields, change the log message, or even change the severity.

Each logger can have multiple filters, which decide whether the log message should be ignored.

Each logger can have multiple writers, which handle the log entry. Included writers are:

  • NilWriter: discards all messages, useful for stubbing.
  • FileWriter: writes to files, also used for stdout.
  • SocketWriter: sends structured log data to log aggregators like graylog.
  • ChannelWriter: allows to use any other writer in a thread-safe manner.

Each writer can again have it's own filters and formatters.

Log Entry

Log entries are represented as an object. Formatters and writers receive that object and can handle it as they whish.

Entry* = object
  facility*: string
  severity*: Severity
  customSeverity*: string
  time*: times.TimeInfo
  msg*: string
  fields*: ValueMap

Additional Information

Log levels

By default, omnilog supports the log severities specified in the syslog RFC syslog. You can also configure custom levels.

Severity Numerical value
emergency 1
alert 2
critical 3
error 4
warning 5
notice 6
info 7
debug 8
trace 9
custom 10

Time format

While you may change the time format used, it is highly recommended to stick to the default specified by RFC3339.

Todo

  • More tests.
  • Finish writing documentation.
  • Thread-safe memory writer.
  • Rolling file writer.

Versioning

This project follows SemVer.

License.

This project is under the LGPL 3 license.