On this page:
15.5.1 Creating Loggers
15.5.2 Logging Events
15.5.3 Receiving Logged Events

15.5 Logging

A logger accepts events that contain information to be logged for interested parties. A log receiver represents an interested party that receives logged events asynchronously. Each event has a level of importance, and a log receiver subscribes to logging events at a certain level of importance and higher. The levels, in decreasing order of importance, are 'fatal, 'error, 'warning, 'info, and 'debug.

To help organize logged events, loggers can be named and hierarchical. Every event reported to a logger is also propagated to its parent (if any), but the event message is prefixed with a name (if any) that is typically the name of the logger to which is was originally reported. A logger is not required to have a parent or name.

On start-up, Racket creates an initial logger that is used to record events from the core run-time system. For example, an 'debug event is reported for each garbage collection (see Garbage Collection). For this initial logger, two log receivers are also created: one that writes events to the process’s original error output port, and one that writes events to the system log. The level of written events in each case is system-specific, and the default can be changed through command-line flags (see Command Line) or through environment variables:

The current-logger parameter determines the current logger that is used by forms such as log-warning. On start-up, the initial value of this parameter is the initial logger. The run-time system sometimes uses the current logger to report events. For example, the bytecode compiler sometimes reports 'warning events when it detects an expression that would produce a run-time error if evaluated.

15.5.1 Creating Loggers


(logger? v)  boolean?

  v : any/c
Returns #t if v is a logger, #f otherwise.


(make-logger [name parent notify-callback])  logger?

  name : (or/c symbol? #f) = #f
  parent : (or/c logger? #f) = #f
  notify-callback : (vector? . -> . any/c) = #f
Creates a new logger with an optional name and parent.

If notify-callback is provided, then it is called (under a continuation barrier) whenever an event is logged to the result logger or one of its descendants, but only if some log receiver is inteested in the event in the same sense as log-level?. The event is not propagated to any log receivers until notify-callback returns.


(logger-name logger)  (or/c symbol? #f)

  logger : logger?
Reports logger’s name, if any.


(current-logger)  logger?

(current-logger logger)  void?
  logger : logger?
A parameter that determines the current logger.


(define-logger id)

Defines log-id-fatal, log-id-error, log-id-warning, log-id-info, and log-id-debug as forms like log-fatal, log-error,log-warning, log-info, and log-debug. The define-logger form also defines id-logger, which is a logger named 'id that is a child of (current-logger); the log-id-fatal, etc. forms use this new logger. The new logger is created when define-logger is evaluated.

15.5.2 Logging Events


(log-message logger level [name] message data)  void?

  logger : logger?
  level : (or/c 'fatal 'error 'warning 'info 'debug)
  name : (or/c symbol? #f) = (object-name logger)
  message : string?
  data : any/c
Reports an event to logger, which in turn distributes the information to any log receivers attached to logger or its ancestors that are interested in events at level or higher.

Log receivers can filter events based on name. In addition, if name is not #f, then message is prefixed with the name followed by ": " before it is sent to receivers.


(log-level? logger level)  boolean?

  logger : logger?
  level : (or/c 'fatal 'error 'warning 'info 'debug)
Reports whether any log receiver attached to logger or one of its ancestors is interested in level events (or potentially lower). Use this function to avoid work generating an event for log-message if no receiver is interested in the information; this shortcut is built into log-fatal, log-error, log-warning, log-info, log-debug, and forms bound by define-logger, however, so it should not be used with those forms.

The result of this function can change if a garbage collection determines that a log receiver is no longer accessible (and therefore that any event information it receives will never become accessible).


(log-max-level logger)

  (or/c #f 'fatal 'error 'warning 'info 'debug)
  logger : logger?
Similar to log-level?, but reports the maximum level of logging for which log-level? on logger returns #t. The result is #f if log-level? with logger currently returns #f for all levels.


(log-fatal string-expr)

(log-fatal format-string-expr v ...)


(log-error string-expr)

(log-error format-string-expr v ...)


(log-warning string-expr)

(log-warning format-string-expr v ...)


(log-info string-expr)

(log-info format-string-expr v ...)


(log-debug string-expr)

(log-debug format-string-expr v ...)
Log an event with the current logger, evaluating string-expr or (format format-string-expr v ...) only if the logger has receivers that are interested in the event. In addition, the current continuation’s continuation marks are sent to the logger with the message string.

These form are convenient for using the current logger, but libraries should generally use a specifically named logger—typically through similar convenience forms generated by define-logger.

For each log-level,

(log-level string-expr)

is equivalent to

(let ([l (current-logger)])
  (when (log-level? l 'level)
    (log-message l 'level string-expr


(log-level format-string-expr v ...)

is equivalent to

(log-level (format format-string-expr v ...))

15.5.3 Receiving Logged Events


(log-receiver? v)  boolean?

  v : any/c
Returns #t if v is a log receiver, #f otherwise.


(make-log-receiver logger level [name ...] ...)  log-receiver?

  logger : logger?
  level : (or/c 'none 'fatal 'error 'warning 'info 'debug)
  name : (or/c #f symbol?) = #f
Creates a log receiver to receive events of importance level and higher as reported to logger and its descendants, as long as either name is #f or the event’s name matches name.

A log receiver is a synchronizable event. It becomes ready for synchronization when a logging event is received, so use sync to receive an logged event. The log receiver’s synchronization result is an immutable vector containing four values: the level of the event as a symbol, an immutable string for the event message, an arbitrary value that was supplied as the last argument to log-message when the event was logged, and a symbol or #f for the event name (where a symbol is usually the name of the original logger for the event).

Multiple pairs of level and name can be provided to indicate different specific levels for different names (where name defaults to #f only for the last given level). A level for a #f name applies only to events whose names do not match any other provided name. If the same name is provided multiple times, the level provided with the last instance in the argument list takes precedence.