Skip to content

structlog #

Structured Logs

The structlog module develops the idea of vlogger by constructing a record using a chain of method calls.

Concept

When initialized, the logger starts a thread with a record handler. The logger has a number of methods, each of which creates a record with the corresponding logging level, e.g. info().

By chaining method calls, the module user can create a record with any structure. The final .send() call sends the record to the handler for writing.

The record handler completely defines how to prepare the Record object for writing, how and whereto the writing will occur. The handler must implement the RecordHandler interface. Two ready-made handlers for recording are provided: TextHandler (the default) and JSONHandler for JSON formatted logs.

Usage

import structlog

fn main() {
    log := structlog.new()
    defer {
        log.close()
    }

    log.info().message('Hello, World!').send()
}

Output:

2026-01-03T09:33:35.366Z [INFO ] message: 'Hello, World!'

See also examples dir for more usage examples.

fn new #

fn new(config LogConfig) StructuredLog

new creates new logger with given config. See LogConfig for defaults. This function starts a separate thread for processing and writing logs. The calling code MUST wait for this thread to complete to ensure all logs are written correctly. To do this, close the logger as shown in the examples.

Example

log := structlog.new()
defer {
	log.close()
}

interface RecordHandler #

interface RecordHandler {
mut:
	// handle method must prepare the Record for writing and write it.
	handle(rec Record) !
}

type Value #

type Value = i8
	| i16
	| i32
	| i64
	| int
	| isize
	| u8
	| u16
	| u32
	| u64
	| usize
	| f32
	| f64
	| string
	| bool
	| []Value
	| map[string]Value

fn (Value) str #

fn (v Value) str() string

str returns a string representation of Value.

fn ([]Field) as_map #

fn (f []Field) as_map() map[string]Value

as_map converts array of fields into map.

enum Level #

enum Level {
	none  // disables all logs.
	fatal // disables error, warn, info, debug and trace.
	error // disables warn, info, debug and trace.
	warn  // disables info, debug and trace.
	info  // disables debug and trace.
	debug // disables trace.
	trace
}

enum TimestampFormat #

enum TimestampFormat {
	default
	rfc3339
	rfc3339_micro
	rfc3339_nano
	ss
	ss_micro
	ss_milli
	ss_nano
	unix
	unix_micro
	unix_milli
	unix_nano
	custom
}

struct DefaultHandler #

struct DefaultHandler {
pub mut:
	writer io.Writer
}

DefaultHandler is a default empty implementation of RecordHandler interface. Its only purpose for existence is to be embedded in a concrete implementation of the interface for common struct fields.

fn (DefaultHandler) handle #

fn (mut h DefaultHandler) handle(rec Record) !

handle is the default implementation of handle method of RecordHandler. It does nothing.

struct Field #

struct Field {
pub:
	name  string
	value Value
}

Field represents a named field of log record.

struct JSONHandler #

struct JSONHandler {
	DefaultHandler
}

fn (JSONHandler) handle #

fn (mut h JSONHandler) handle(rec Record) !

handle converts the log record into json string and writes it into underlying writer.

struct LogConfig #

@[params]
struct LogConfig {
pub:
	// level holds a logging level for the logger.
	// This value cannot be changed after logger initialization.
	level Level = .info

	// timestamp holds the timestamp settings.
	timestamp Timestamp

	add_level     bool = true // if true add `level` field to all log records.
	add_timestamp bool = true // if true add `timestamp` field to all log records.

	// handler holds a log record handler object which is used to process logs.
	handler RecordHandler = TextHandler{
		writer: os.stdout()
	}
}

struct Record #

@[noinit]
struct Record {
	channel chan Record
pub:
	level  Level
	fields []Field
}

fn (Record) append #

fn (r Record) append(field ...Field) Record

append adds new fields to a record and returns the modified record.

fn (Record) prepend #

fn (r Record) prepend(field ...Field) Record

prepend adds new fields to the beginning of the record and returns the modified record.

fn (Record) field #

fn (r Record) field(name string, value Value) Record

field adds new field with given name and value to a record and returns the modified record.

fn (Record) message #

fn (r Record) message(s string) Record

message adds new message field to a record and returns the modified record. This is a shothand for field('message', 'message text').

fn (Record) error #

fn (r Record) error(err IError) Record

error adds an error as new field to a record and returns the modified record. The IError .msg() and .code() methods output will be logged.

fn (Record) send #

fn (r Record) send()

send sends a record to the record handler for the futher processing and writing.

struct StructuredLog #

@[heap]
@[noinit]
struct StructuredLog {
	LogConfig
mut:
	channel        chan Record
	handler_thread thread
}

fn (StructuredLog) trace #

fn (s StructuredLog) trace() Record

trace creates new log record with trace level.

fn (StructuredLog) debug #

fn (s StructuredLog) debug() Record

debug creates new log record with debug level.

fn (StructuredLog) info #

fn (s StructuredLog) info() Record

info creates new log record with info level.

fn (StructuredLog) warn #

fn (s StructuredLog) warn() Record

warn creates new log record wth warning level.

fn (StructuredLog) error #

fn (s StructuredLog) error() Record

error creates new log record with error level.

fn (StructuredLog) fatal #

fn (s StructuredLog) fatal() Record

fatal creates new log record with fatal level.

Note: After calling send() on record with fatal level the program will immediately exit with exit code 1.

fn (StructuredLog) close #

fn (s StructuredLog) close()

close closes the internal communication channell (which is used for transfer log messages) and waits for record handler thread. It MUST be called for normal log processing.

struct TextHandler #

struct TextHandler {
	DefaultHandler
pub:
	// If true use colors in log messages. Otherwise disable colors at all.
	// Turning on/off color here does not affect any colors that may be contained
	// within the log itself i.e. in-string ANSI escape sequences are not processed.
	color bool = true
}

fn (TextHandler) handle #

fn (mut h TextHandler) handle(rec Record) !

handle builds a log string from given record and writes it into underlying writer.

struct Timestamp #

struct Timestamp {
pub mut:
	// format sets the format of datetime in logs. TimestampFormat values
	// map 1-to-1 to the date formats provided by `time.Time`.
	// If .custom format is selected the `custom` field must be set.
	format TimestampFormat = .rfc3339

	// custom sets the custom datetime string format if format is set to .custom.
	// See docs for Time.format_custom() fn from stadnard `time` module.
	custom string

	// If local is true the local time will be used instead of UTC.
	local bool
}