Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Logging

Levels, fields, the output, and the functions that write a line.

Source: runtime/log/log.pep

Level

enum Level

How much a line matters, most important first.

As the level a target shows (set_level, PEPPER_LOG), each level also shows the ones above it: Info shows errors, warnings and info lines.

Cases

Off

Off

Nothing: as the level a target shows, turns its lines off.

Error

Error

Something failed (error).

Warning

Warning

Something looks wrong but the program carries on (warning).

Info

Info

What the program is doing, at the level of whole operations (info).

Debug

Debug

Detail for finding a bug (debug).

Trace

Trace

Step-by-step detail (trace).

Format

enum Format

How each line is written.

Cases

Text

Text

One readable line: the UTC time, the level, the target in brackets, the message, key=value fields, and the call’s location in parentheses.

Json

Json

One JSON object per line (JSON Lines), with the keys time, level, target (when there is one), message and location, then each field.

Field

struct Field

A key and value attached to a line. Make one with field.

Fields

key

var key: String = ""

The key.

value

var value: String = ""

The value as JSON text: 200, "ann", true.

Constructor

Field()

construct(key: String, value: String)

Creates a field from a key and the JSON text of its value; field makes the text from any value.

Parameters

  • key — the key
  • value — the value’s JSON text

field

field<T>(key: String, value: T): Field

Makes a field for a line: log.info("done", [log.field("ms", 12)]).

The value is turned into JSON (see json.encode) when the field is made, whether or not the line is written; guard costly fields with enabled.

Type parameters

  • T — the type of value

Parameters

  • key — the key
  • value — the value

Returns

  • the field

Example

import log;

main(): int {
    log.info("request done", [log.field("status", 200), log.field("path", "/")]);
    return 0;
}

set_level

set_level(level: Level, target: String = "")

Sets the level a target shows, or with no target the level every target without its own shows. The default is Level.Info, unless the PEPPER_LOG environment variable says otherwise.

Parameters

  • level — the least important level to show; Level.Off shows nothing
  • target — the target, as the logging functions’ target; empty for the global level

Example

import log;

main(): int {
    log.set_level(log.Level.Debug);
    log.set_level(log.Level.Warning, "http");
    log.debug("shown");
    log.info("not shown", target = "http");
    return 0;
}

set_output

set_output([Move] writer: io.Writer, format: Format = Format.Text)

Sends every line from now on to writer in format, instead of to standard error. Lines are written whole, one write_all each, under a lock, so lines from many threads and tasks never interleave. A failed write is ignored. Colors are off.

Parameters

  • writer — where lines go: a new value, or one handed over with move(x), since the log keeps it
  • format — how each line is written

Example

import io;
import log;

main(): int {
    var path = io.Directory.temp().join("app.log");
    var file = io.File.create(path).value();
    log.set_output(move(file), log.Format.Json);
    log.info("started");
    return 0;
}

enabled

enabled(level: Level, target: String = ""): bool

Reports whether a line at level for target would be written, so a caller can skip building a costly message or field.

Cheap when no target shows level: two atomic loads, with no lock.

Parameters

  • level — the line’s level
  • target — the line’s target; empty for none

Returns

  • true when target shows level; false for Level.Off

Example

import log;

main(): int {
    if (log.enabled(log.Level.Debug)) {
        log.debug($"state: {[1, 2, 3]}");
    }
    return 0;
}

error

error( message: String, fields: Array<Field> = Array<Field>(), target: String = "" )

Writes an error line: something failed.

Parameters

  • message — the message
  • fields — keys and values to add to the line (see field)
  • target — the part of the program the line is about, which set_level and PEPPER_LOG can show or hide on its own; empty for none

Example

log.error("cannot open the database", [log.field("path", path)]);

warning

warning( message: String, fields: Array<Field> = Array<Field>(), target: String = "" )

Writes a warning line: something looks wrong but the program carries on.

Parameters

  • message — the message
  • fields — keys and values to add to the line (see field)
  • target — the part of the program the line is about; empty for none

Example

log.warning("retrying", [log.field("attempt", 2)], target = "http");

info

info( message: String, fields: Array<Field> = Array<Field>(), target: String = "" )

Writes an info line: what the program is doing.

Parameters

  • message — the message
  • fields — keys and values to add to the line (see field)
  • target — the part of the program the line is about; empty for none

Example

log.info("listening", [log.field("port", 8080)]);

debug

debug( message: String, fields: Array<Field> = Array<Field>(), target: String = "" )

Writes a debug line: detail for finding a bug. Not shown by default.

Parameters

  • message — the message
  • fields — keys and values to add to the line (see field)
  • target — the part of the program the line is about; empty for none

Example

log.debug("cache miss", [log.field("key", key)], target = "cache");

trace

trace( message: String, fields: Array<Field> = Array<Field>(), target: String = "" )

Writes a trace line: step-by-step detail. Not shown by default.

Parameters

  • message — the message
  • fields — keys and values to add to the line (see field)
  • target — the part of the program the line is about; empty for none

Example

log.trace("read a frame", [log.field("bytes", 512)], target = "http");