The logging library

Overview

This is the logging library reference. The logging library exports a single module named “logging”.

Quick Start

Log to stdout:

define constant $log
  = make(<log>,
         name: "my-app",
         formatter: "%{millis} %{level} [%{thread}] - %{message}");
add-target($log, $stdout-log-target);
log-info($log, "My-app starting with args %s", application-arguments());

The above results in log lines like this:

12345 INFO [Main Thread] - My-app starting with args blah

Make another log for debugging server requests:

define constant $request-log
  = make(<log>, name: "my-app.debug.request");

There are several things to notice about the above setup:

  • Logs have no log targets by default. The simplest way to add a target is to add a pre-existing target such as $stdout-log-target or $stderr-log-target using add-target.

  • Different logs are associated by name. In this example the log named "my-app" is an ancestor of the one named "my-app.debug.request" because the first dotted name component matches.

  • No targets were added to the my-app.debug.request log. Since all log messages sent to a child are also sent to its ancestors (but see log-additive?-setter), anything logged to the my-app.debug.request log will be passed along to the my-app log.

    So what’s the benefit of having both logs? You can enable/disable them separately at runtime. Also, if for example you wanted to log debug messages to a separate file you could add a target to the my-app.debug log.

Log to a file:

add-target($log, make(<rolling-file-log-target>,
                      pathname: "/var/log/my-app.log"));

The log file will be rolled immediately if it exists and is not zero length. If you don’t want it to be rolled on startup, pass roll: #f to make in the above call.

Logs may be disabled with log-enabled?(log) := #f. When disabled, no messages will be logged to the log’s local targets, but the value of log-additive? will still be respected. In other words, logging to a disabled log will still log to ancestor logs if they are themselves enabled.

Errors

If there is an error when parsing a <log-formatter> format control string or in finding a <log> object by name, a <logging-error> will be signaled.

<logging-error> Open Class
Superclasses:<error>, <simple-condition>

Log Levels

There are five log levels which may be used to affect the way logs are formatted and to include/exclude logs of different severity levels. When configuring logging, set the log level to the least severe level you want to see. “Trace” logs are the least severe (or most verbose). “Error” logs are the most severe. The distinctions are somewhat arbitrary, but it is hoped that five levels is enough for even the most compulsive taxonomists.

<log-level> Open Primary Abstract Class

Each of the log level constants documented below is an instance of this class.

Superclasses:

<object>

Init-Keywords:
  • name – The name used to display this log level. For example, “INFO”, “DEBUG”, etc.
$trace-level Constant

The most verbose log level. Generally use this to generate an absurd amount of debug output that you would never want generated by (for example) a production server.

$debug-level Constant

For debug messages. Usually for messages that are expected to be temporary, while debugging a particular problem.

$info-level Constant

For messages about relatively important events in the normal operation of a program.

$warn-level Constant

For out-of-the-ordinary events that may warrant extra attention, but don’t indicate an error.

$error-level Constant

For errors.

level-name Generic function
Signature:

level-name (level) => (name)

Parameters:
Values:

Logging Functions

log-message Generic function
Signature:log-message (level log object #rest args) => ()

This is the most basic logging function. All of the logging functions below simply call this with a specific <log-level> object.

Parameters:
  • level – An instance of <log-level>.
  • log – An instance of <log>.
  • object – An instance of <object>. Normally this is a format control string, but it is also possible (for example) to log objects to a database back-end.
  • args (#rest) – Instances of <object>. These are normally format arguments to be interpolated into the above format control string.
log-error Function
Equivalent:log-message($log-error, ...)

See log-message.

log-warning Function
Equivalent:log-message($log-warn, ...)

See log-message.

log-info Function
Equivalent:log-message($log-info, ...)

See log-message.

log-debug Function
Equivalent:log-message($log-debug, ...)

See log-message.

log-debug-if Function
Signature:

log-debug-if (test log object #rest args) => ()

Equivalent:
if (test)
  log-message($log-debug, ...)
end

See log-message.

log-trace Function
Equivalent:log-message($log-trace, ...)

See log-message.

log-level-applicable? Generic function
Signature:

log-level-applicable? (given-level log-level) => (applicable?)

Parameters:
Values:

Logs

<abstract-log> Abstract Class
Superclasses:

<object>

Init-Keywords:
  • name(required) The dotted name of this log. A <string>.
  • additive? – A <boolean> specifying whether log messages sent to this log should be passed along to its parent log. The default is #t.
  • children – A <sequence> of <log> objects.
  • enabled?<boolean> specifying whether this log is enabled. Note that the value of additive? will be respected even if the log is disabled. The default is #t.
  • parent – The parent of this log.
<log> Open Class
Superclasses:

<abstract-log>

Init-Keywords:
get-log Generic function
Signature:

get-log (name) => (abstract-log or #f)

Parameters:
  • name – An instance of <string>. This is normally a dotted path name like “http.server.queries”.
Values:
get-root-log Generic function
Signature:

get-root-log () => (log)

Values:
  • log – An instance of <log>.
log-level Generic function
Signature:

log-level (log) => (level)

Parameters:
  • log – An instance of <log>.
Values:
log-level-setter Generic function
Signature:

log-level-setter (new-level log) => (new-level)

Parameters:
Values:
log-targets Generic function
Signature:

log-targets (log) => (targets)

Parameters:
  • log – An instance of <log>.
Values:
log-additive? Generic function
Signature:

log-additive? (log) => (additive?)

Parameters:
  • log – An instance of <log>.
Values:
log-additive?-setter Generic function
Signature:

log-additive?-setter (new-value log) => (new-value)

Parameters:
  • new-value – An instance of <boolean>.
  • log – An instance of <log>.
Values:
log-enabled? Generic function
Signature:

log-enabled? (log) => (enabled?)

Parameters:
  • log – An instance of <log>.
Values:
log-enabled?-setter Generic function
Signature:

log-enabled?-setter (new-value log) => (new-value)

Parameters:
  • new-value – An instance of <boolean>.
  • log – An instance of <log>.
Values:
log-name Generic function
Signature:

log-name (log) => (name)

Parameters:
  • log – An instance of <log>.
Values:
add-target Generic function
Signature:

add-target (log target) => ()

Parameters:
remove-all-targets Generic function
Signature:

remove-all-targets (log) => ()

Parameters:
  • log – An instance of <log>.
remove-target Generic function
Signature:

remove-target (log target) => ()

Parameters:
log-formatter Generic function
Signature:

log-formatter (log) => (formatter)

Parameters:
  • log – An instance of <log>.
Values:
log-formatter-setter Generic function
Signature:

log-formatter-setter (formatter log) => (formatter)

Parameters:
Values:

Log Targets

<log-target> Open Abstract Class
Superclasses:<closable-object>
<null-log-target> Class
Superclasses:<log-target>

A log target that discards all messages.

<file-log-target> Class
Superclasses:

<log-target>

Init-Keywords:
  • pathname(required) An instance of <pathname>.

A log target that logs to a single, monolithic file. You probably want <rolling-file-log-target> instead.

target-pathname Generic function
Signature:

target-pathname (file-log-target) => (pathname)

Parameters:
Values:
open-target-stream Open Generic function

This should not be called except by the logging library itself. Implementers of new log target classes may override it.

Signature:

open-target-stream (target) => (stream)

Parameters:
  • target – An instance of <file-log-target>.
Values:
<rolling-file-log-target> Class
Superclasses:

<file-log-target>

Init-Keywords:
  • max-size – An <integer>. The size in bytes at which to roll the file. The default size is 100MB. Note that the actual size of the file when it rolls may be slightly larger, depending on the size of the last message logged.
  • roll – A <boolean> specifying whether to roll the log file at the time this log target is created, if it already exists and is not empty.
<stream-log-target> Open Class

A log target that sends all messages to a stream.

Superclasses:

<log-target>

Init-Keywords:
  • stream(required) An instance of <stream>.
target-stream Generic function
Signature:

target-stream (target) => (stream)

Parameters:
Values:
log-to-target Open Generic function

This should not be called except by the logging library itself. Implementers of new log target classes may override it.

Signature:

log-to-target (target level formatter object args) => ()

Parameters:
write-message Open Generic function

This should not be called except by the logging library itself. Implementers of new log target classes may override it.

Signature:

write-message (target object args) => ()

Parameters:
$null-log-target Constant

An predefined instance of <null-log-target>.

$stderr-log-target Constant

An predefined instance of <stream-log-target> that sends log messages to *standard-error*.

$stdout-log-target Constant

An predefined instance of <stream-log-target> that sends log messages to *standard-output*.

Log Formatting

Each <log> has a <log-formatter> that determines how to format each log message. Make one like this:

make(<log-formatter>, pattern: "...");

The log formatter pattern is similar to a format control string except it has a short and long form for each format directive. Here are the defined format directives:

Short Long Description
%d %{date:fmt} Current date. In the long form, fmt is any string acceptable as the first argument to format-date.
%l %{level} Log level. e.g., INFO, DEBUG, ERROR, etc
%m %{message} Log message, as passed to log-info, log-debug etc., with format arguments already interpolated.
%p %{pid} Current process ID. (Not yet implemented.)
%r %{millis} Milliseconds since application started.
%t %{thread} Current thread name.
%% None The % character.

All format directives, in either short or long form, accept a numeric argument immediately following the % character. If provided, the numeric argument specifies the minimum width of the field. If the numeric argument is positive then the displayed value will be left justified and padded with spaces on the right if necessary. If negative, the displayed value will be right justified and padded with spaces on the left if needed.

$default-log-formatter Constant

Formatter used if none is specified when a <log> is created. Has this pattern:

"%{date:%Y-%m-%dT%H:%M:%S.%F%z} %-5L [%t] %m"
<log-formatter> Open Class
Superclasses:

<object>

Init-Keywords: