Logging

Modern structured logging for Kit applications. Features multiple log levels, output formats (JSON, Pretty, Compact), configurable output targets, and structured fields with context propagation.

import IO.Logging as Log

Quick Start

Use the global convenience functions for simple logging:

import IO.Logging as Log

# Log messages at different levels
Log.debug "Debugging info" {}
Log.info "Application started" {version: "1.0.0"}
Log.warn "Resource running low" {memory: 85"Connection failed" {host: "db.example.com"# Output (Pretty format):
# 2026-01-26 10:30:45.123 INFO  Application started {version: "1.0.0"}
# 2026-01-26 10:30:45.124 WARN  Resource running low {memory: 85}
# 2026-01-26 10:30:45.125 ERROR Connection failed {host: "db.example.com"}

Types

Level
type Level = Debug | Info | Warn | Error
Log levels from least to most severe. Messages below the configured minimum level are filtered out.
LevelDescription
DebugDetailed debugging information
InfoGeneral informational messages
WarnWarning conditions that may need attention
ErrorError conditions and failures
Format
type Format = JsonFmt | PrettyFmt | CompactFmt
Output format for log entries.
FormatDescription
JsonFmtMachine-readable JSON format
PrettyFmtHuman-readable with ANSI colors
CompactFmtCompact text without colors
Output
type Output = ToStdout | ToStderr
Output target for log entries.
TargetDescription
ToStdoutWrite to standard output
ToStderrWrite to standard error

Global Functions

These convenience functions use the default logger configuration (Info level, Pretty format, stdout).

FunctionTypeDescription
Log.debugString -> Record -> ()Log a debug message with optional fields
Log.infoString -> Record -> ()Log an info message with optional fields
Log.warnString -> Record -> ()Log a warning message with optional fields
Log.errorString -> Record -> ()Log an error message with optional fields
# All logging functions take a message and a fields record
Log.info "User logged in" {user-id: 123, ip: "192.168.1.1"}

# Use empty record {} for messages without fields
Log.info "Server started" {}

Configuration

Configure loggers using the builder pattern with these functions:

FunctionTypeDescription
Log.default-configConfigDefault configuration (Info, Pretty, stdout)
Log.with-levelConfig -> Level -> ConfigSet the minimum log level
Log.with-formatConfig -> Format -> ConfigSet the output format
Log.with-outputConfig -> Output -> ConfigSet the output target
Log.with-contextConfig -> Record -> ConfigSet context fields included in all entries
# Build a custom configuration
config = Log.default-config
  |> Log.with-level Log.Debug
  |> Log.with-format Log.JsonFmt
  |> Log.with-output Log.ToStderr
  |> Log.with-context {app: "my-service"# Create a logger with this configuration
log = Log.logger config

Custom Loggers

Log.logger
Config -> Logger
Create a logger instance with the given configuration. The returned logger has debug, info, warn, error, and with-context methods.
# Create a custom logger
config = Log.with-level Log.default-config Log.Debug
log = Log.logger config

# Use the logger
log.info "Processing request" {request-id: "abc123"}
log.debug "Request details" {method: "GET"# Create a child logger with additional context
request-log = log.with-context {request-id: "abc123"}
request-log.info "Request completed" {status: 200}

Logger Presets

Pre-configured loggers for common use cases:

Log.json-logger
() -> Logger
Create a logger with JSON output format. Good for log aggregation systems.
Log.production-logger
() -> Logger
Create a production-ready logger: JSON format, stderr output, Info level. Ideal for containerized and cloud deployments.
log = Log.production-logger

log.info "Service started" {port: 8080}
# Output to stderr:
# {"timestamp":"2026-01-26 10:30:45.123","level":"info","message":"Service started","fields":{"port":8080},"context":{}}
Log.dev-logger
() -> Logger
Create a development logger: Pretty format with colors, Debug level. Shows all log levels with human-readable output.
log = Log.dev-logger

log.debug "Variable value" {x: 42}
log.info "Processing" {}
# Output with colors:
# 2026-01-26 10:30:45.123 DEBUG Variable value {x: 42}
# 2026-01-26 10:30:45.124 INFO  Processing

Format Examples

The same log entry in each format:

# Pretty format (default) - colored, human-readable
# 2026-01-26 10:30:45.123 INFO  User logged in {user: "alice"}

# Compact format - plain text, no colors
# 2026-01-26 10:30:45.123 info: User logged in {user: "alice"}

# JSON format - machine-readable
# {"timestamp":"2026-01-26 10:30:45.123","level":"info","message":"User logged in","fields":{"user":"alice"},"context":{}}