logger

Simple structured logging for CHICKEN Scheme with per-module level control.

  1. logger
    1. Description
    2. Author
    3. Repository
    4. Requirements
    5. Documentation
      1. Quick Start
      2. Per-Module Logging
      3. API Reference
        1. Parameters
        2. Procedures
        3. Macros
      4. Log Levels
    6. Examples
      1. Application with Multiple Modules
      2. JSON Logging for Production
    7. License
    8. Version History

Description

A lightweight logging library that provides:

Author

Rolando Abarca

Repository

https://forgejo.rolando.cl/cpm/logger-egg

Requirements

Documentation

Quick Start

(import logger)

;; Basic logging (uses GLOBAL module name)
(logger/d "debug message")
(logger/i "info message")
(logger/w "warning message")
(logger/e "error message")

;; Messages can be concatenated
(logger/i "user " user-id " logged in")

Output:

 2026-01-18T19:07:51Z [INFO] [GLOBAL] info message

Per-Module Logging

Use logger/install inside a module to create local d, i, w, e functions that automatically tag logs with the module name:

(module my-app
  (do-stuff)
  (import scheme chicken.base logger)

  (logger/install my-app)

  (define (do-stuff)
    (i "doing stuff")    ;; tagged as [my-app]
    (d "details...")))

Output:

 2026-01-18T19:07:51Z [INFO] [my-app] doing stuff
 2026-01-18T19:07:51Z [DEBUG] [my-app] details...

API Reference

Parameters
[parameter] logger/level

Global log level. Messages below this priority are suppressed. Default: 'debug.

Valid values: 'debug, 'info, 'warn, 'error, 'none

;; Set global level to info (hides debug messages)
(logger/level 'info)

;; Get current level
(logger/level)  ; => 'info
[parameter] logger/output

Output port for log messages. Default: (current-output-port).

(import chicken.file.posix)

;; Log to a file
(define log-port (open-output-file "app.log"))
(logger/output log-port)

;; Log to stderr
(import chicken.port)
(logger/output (current-error-port))
[parameter] logger/format

Output format. Default: 'text.

'text
Human-readable format: TIMESTAMP [LEVEL] [MODULE] message
'json
JSON format: {"ts":N,"level":"...","module":"...","message":"..."}
;; Text format (default)
(logger/format 'text)
;; Output: 2026-01-18T19:07:51Z [INFO] [GLOBAL] message

;; JSON format
(logger/format 'json)
;; Output: {"ts":1737226071,"level":"info","module":"GLOBAL","message":"message"}
[parameter] logger/module-levels

Alist of per-module log levels. Use logger/set-module-level! to modify.

Procedures
[procedure] (logger/log module-name level msg . rest)

Core logging function. Logs a message if level meets or exceeds the effective level for module-name.

module-name
Symbol identifying the module.
level
Log level symbol: 'debug, 'info, 'warn, or 'error.
msg
Message string or value.
rest
Additional values to concatenate to the message.
(logger/log 'my-module 'info "Processing item " item-id)
[procedure] (logger/d msg . rest)
[procedure] (logger/i msg . rest)
[procedure] (logger/w msg . rest)
[procedure] (logger/e msg . rest)

Convenience functions for logging at debug, info, warn, and error levels respectively. Uses 'GLOBAL as the module name.

(logger/d "debug details")
(logger/i "informational message")
(logger/w "warning!")
(logger/e "error occurred: " error-msg)
[procedure] (logger/set-module-level! module-name level)

Set the log level for a specific module. This overrides the global logger/level for that module.

;; Only show warnings and errors from noisy-module
(logger/set-module-level! 'noisy-module 'warn)

;; Show all messages from important-module even if global level is higher
(logger/set-module-level! 'important-module 'debug)
[procedure] (logger/disable-module! module-name)

Disable all logging for a specific module. Equivalent to (logger/set-module-level! module-name 'none).

(logger/disable-module! 'noisy-module)
Macros
[syntax] (logger/install module-name)

Installs module-local logging functions d, i, w, and e that automatically tag messages with module-name.

Must be called at the top level of a module, after imports.

(module my-component
  (initialize shutdown)
  (import scheme chicken.base logger)

  (logger/install my-component)

  (define (initialize)
    (i "initializing...")
    (d "loading config"))

  (define (shutdown)
    (i "shutting down")))

Log Levels

Levels from lowest to highest priority:

debug
Detailed information for debugging. Priority: 0
info
General informational messages. Priority: 1
warn
Warning conditions. Priority: 2
error
Error conditions. Priority: 3
none
Disables logging entirely. Priority: 999

Messages are logged only if their level priority is greater than or equal to the effective level for the module.

Examples

Application with Multiple Modules

;;; main.scm
(import scheme chicken.base logger)
(import my-db my-http)

;; Set global level to info
(logger/level 'info)

;; But show debug messages from database module
(logger/set-module-level! 'my-db 'debug)

;; Suppress http module unless errors
(logger/set-module-level! 'my-http 'error)

(db-connect "localhost")
(http-serve 8080)
;;; my-db.scm
(module my-db
  (db-connect)
  (import scheme chicken.base logger)

  (logger/install my-db)

  (define (db-connect host)
    (i "connecting to " host)
    (d "using default port 5432")
    ;; ...
    (i "connected")))
;;; my-http.scm
(module my-http
  (http-serve)
  (import scheme chicken.base logger)

  (logger/install my-http)

  (define (http-serve port)
    (i "starting server on port " port)  ;; suppressed
    (d "debug info")                      ;; suppressed
    ;; ...
    ))

JSON Logging for Production

(import logger chicken.file.posix)

;; Configure for production
(logger/format 'json)
(logger/level 'info)
(logger/output (open-output-file "/var/log/myapp.log"))

(logger/i "application started")
;; {"ts":1737226071,"level":"info","module":"GLOBAL","message":"application started"}

License

BSD-3-Clause

Version History

0.0.2
Initial release.