The logging Library¶
Overview¶
The logging library provides a traditional file-based logging facility. It exports a single module named “logging”.
Quick Start¶
The simplest use case is to use completely default logging:
log-info("I did a thing");
log-debug("got to here");
// also: log-error, log-warning, log-trace
By default all logging goes to standard error.
To do something more sophisticated, such as logging to the network or to a
rolling log file, store a different <log>
instance in the *log*
global variable. For example:
let target = make(<rolling-file-log-target>,
pathname: "/tmp/my-app.log");
*log* := make(<log>,
name: "my-app",
formatter: "%{millis} %{level} [%{thread}] - %{message}",
targets: list(target));
log-info("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 specifically for debugging server requests:
define constant $request-log
= make(<log>, name: "my-app.debug.request");
Log to a specific log object instead of to *log*
. This isn’t expected to
be the common case so it’s more verbose. Create shorthand functions if
necessary.
log-message($debug-level, $request-log, "request = %s", request);
There are several things to notice about $request-log
above:
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
usingadd-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 seelog-additive?-setter
), anything logged to themy-app.debug.request
log will be passed along to themy-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.
Logs may be disabled with log-enabled?(log) := #f
. When
disabled, no messages are logged to the log’s local targets, but the value of
log-additive?
is still respected. In other words, logging to a disabled
log still logs 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.
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
- 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
level – An instance of
<log-level>
.
- Values
name – An instance of
<string>
.
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, *log*, ...)
See
log-message
.
-
log-warning
Function¶ - Equivalent
log-message($log-warn, *log*, ...)
See
log-message
.
-
log-info
Function¶ - Equivalent
log-message($log-info, *log*, ...)
See
log-message
.
-
log-debug
Function¶ - Equivalent
log-message($log-debug, *log*, ...)
See
log-message
.
-
log-debug-if
Function¶ - Signature
log-debug-if (test log object #rest args) => ()
- Equivalent
if (test) log-message($log-debug, *log*, ...) end
See
log-message
.
-
log-trace
Function¶ - Equivalent
log-message($log-trace, *log*, ...)
See
log-message
.
-
log-level-applicable?
Generic function¶ - Signature
log-level-applicable? (given-level log-level) => (applicable?)
- Parameters
given-level – An instance of
<log-level>
.log-level – An instance of
<log-level>
.
- Values
applicable? – An instance of
<boolean>
.
Logs¶
-
<abstract-log>
Abstract Class¶ - Superclasses
- 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
- Init-Keywords
formatter – An instance of
<log-formatter>
.level – An instance of
<log-level>
.targets – A collection of
<log-target>
objects, each of which receives log messages sent to this log.
-
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
log – An instance of
<abstract-log>
or#f
.
-
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
level – An instance of
<log-level>
.
-
log-level-setter
Generic function¶ - Signature
log-level-setter (new-level log) => (new-level)
- Parameters
new-value – An instance of
<log-level>
.log – An instance of
<log>
.
- Values
new-value – An instance of
<log-level>
.
-
log-targets
Generic function¶ - Signature
log-targets (log) => (targets)
- Parameters
log – An instance of
<log>
.
- Values
targets – An instance of
<stretchy-vector>
.
-
log-additive?
Generic function¶
-
log-additive?-setter
Generic function¶
-
log-enabled?
Generic function¶
-
log-enabled?-setter
Generic function¶
-
log-name
Generic function¶
-
add-target
Generic function¶ - Signature
add-target (log target) => ()
- Parameters
log – An instance of
<log>
.target – An instance of
<log-target>
.
-
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 – An instance of
<log>
.target – An instance of
<log-target>
.
-
log-formatter
Generic function¶ - Signature
log-formatter (log) => (formatter)
- Parameters
log – An instance of
<log>
.
- Values
formatter – An instance of
<log-formatter>
.
-
log-formatter-setter
Generic function¶ - Signature
log-formatter-setter (formatter log) => (formatter)
- Parameters
formatter – An instance of
<log-formatter>
.log – An instance of
<log>
.
- Values
formatter – An instance of
<log-formatter>
.
Log Targets¶
-
<log-target>
Open Abstract Class¶ - Superclasses
<closable-object>
-
<null-log-target>
Class¶ - Superclasses
A log target that discards all messages.
-
<file-log-target>
Class¶ - Superclasses
- 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
target – An instance of
<file-log-target>
.
- Values
pathname – An instance of
<pathname>
.
-
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
stream – An instance of
<stream>
.
-
<rolling-file-log-target>
Class¶ - Superclasses
- 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
- Init-Keywords
stream – (required) An instance of
<stream>
.
-
target-stream
Generic function¶ - Signature
target-stream (target) => (stream)
- Parameters
target – An instance of
<stream-log-target>
.
- Values
stream – An instance of
<stream>
.
-
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
target – An instance of
<log-target>
.level – An instance of
<log-level>
.formatter – An instance of
<log-formatter>
.object – An instance of
<object>
.args – An instance of
<sequence>
.
-
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
target – An instance of
<log-target>
.object – An instance of
<object>
.args – An instance of
<sequence>
.
-
$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 |
%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.