Files
simple-log/scrbl/simple-log.scrbl
2026-04-09 14:07:47 +02:00

155 lines
3.7 KiB
Racket
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#lang scribble/manual
@(require (for-label racket/base))
@title{simple-log}
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
A small logging layer on top of Rackets logger system. A log definition
creates a logger plus five convenience procedures. Messages are formatted
with @racket[format], timestamped, and dispatched asynchronously to the
registered callbacks.
@section{API}
@defmodule["simple-log"]
@defform*[((sl-def-log id)
(sl-def-log id name)
(sl-def-log id name parent))]{
Defines a logger with topic @racket['id] and creates:
@itemlist[#:style 'compact
@item{@racket[dbg-id]}
@item{@racket[info-id]}
@item{@racket[warn-id]}
@item{@racket[err-id]}
@item{@racket[fatal-id]}
]
Note. If name is given, id @racket[dbg-prefix], etc. will be generated instead of @racket[dbg-id], etc.
Each procedure has shape:
@racketblock[
(proc msg arg ...)
]
The message is formatted via @racket[format] and emitted with a timestamp
(@litchar{YYYY-MM-DDTHH:MM:SS}) and topic @racket['id].
If @racket[parent] is omitted, the @racket[#f] is used as "parent logger".
A background thread is started that receives log events and forwards them
to the registered callbacks.
}
@defform[(sl-log-to name callback)]{
Registers @racket[callback] under the symbolic name derived from
@racket[name].
@racket[name] is an identifier (not a runtime value). It is converted at
macro expansion time to a symbol and used as key in the callback registry.
Invocation shape:
@racketblock[
(callback topic level timestamp message)
]
with:
@itemlist[#:style 'compact
@item{@racket[topic] logger topic (symbol)}
@item{@racket[level] level (symbol)}
@item{@racket[timestamp] @litchar{YYYY-MM-DDTHH:MM:SS}}
@item{@racket[message] formatted string}
]
An existing callback with the same name is replaced.
}
@defproc[(sl-log-to-file [filename path-string?]) void?]{
Registers a callback that writes log lines to @racket[filename]. The file
is opened with @racket['replace].
Format:
@racketblock[
"<topic>:<level>:<timestamp>:<message>"
]
}
@defproc[(sl-log-to-display) void?]{
Registers a callback that writes log lines to the current output port
using @racket[displayln].
Format:
@racketblock[
"<topic>:<level>:<timestamp>:<message>"
]
}
@defproc[(sl-log-to-file&display [filename path-string?]) void?]{
Equivalent to combining @racket[sl-log-to-display] and
@racket[sl-log-to-file].
}
@defproc[(sl-set-log-level
[l (or/c 'debug 'dbg
'info
'warning 'warn
'error 'err
'fatal)])
symbol?]{
Sets the module-wide log level and returns the normalized symbol.
Aliases:
@itemlist[#:style 'compact
@item{@racket['dbg] @racket['debug]}
@item{@racket['warn] @racket['warning]}
@item{@racket['err] @racket['error]}
]
Other values raise an exception.
Note: this value is stored globally. The receiver installed by
@racket[sl-def-log] itself operates at level @racket['debug].
}
@defproc[(sl-log-level) symbol?]{
Returns the current module-wide log level (default @racket['debug]).
}
@section{Generated procedures}
A call to @racket[sl-def-log] creates five procedures. For example:
@racketblock[
(sl-def-log my-module)
]
creates:
@defproc[#:link-target? #f
(dbg-my-module [msg string?] [arg any/c] ...) void?]{Debug log.}
@defproc[#:link-target? #f
(info-my-module [msg string?] [arg any/c] ...) void?]{Info log.}
@defproc[#:link-target? #f
(warn-my-module [msg string?] [arg any/c] ...) void?]{Warning log.}
@defproc[#:link-target? #f
(err-my-module [msg string?] [arg any/c] ...) void?]{Error log.}
@defproc[#:link-target? #f
(fatal-my-module [msg string?] [arg any/c] ...) void?]{Fatal log.}
All use @racket[format] and emit asynchronously.