Standard library · System and tools

log

Recording what a program does, with levels, a prefix, structured fields, JSON output and writing to a file.

import log

For a program running on a server, println is not enough: you need to know how important each message is and when it was written, and to be able to silence the unimportant ones. The log package has four levels, debug, info, warn and error, and records only the messages at or above the level you set; the default level is info.

By default the log goes to standard error with a timestamp. The examples below turn the time off so their output is stable.

Constants and variables

LevelDebug

const LevelDebug: i32 = 0
The debug level: detail for whoever is working on the code.
log-Info.salam
import log

func main:
    log.ToStdout()
    log.ShowTime(false)
    log.SetPrefix("[app]")
    log.Debug("this is not shown")
    log.Info("the server is ready")
    log.Warn("memory is running low")
    log.Error("the connection dropped")
    log.SetLevel(log.LevelDebug)
    log.Debug("now it is shown")
    log.Log(log.LevelWarn, "at a level of my choosing")
    println log.GetLevel(), log.LevelName(log.LevelError), log.ParseLevel("warn"), log.LevelInfo
end
Output[INFO] [app] the server is ready [WARN] [app] memory is running low [ERROR] [app] the connection dropped [DEBUG] [app] now it is shown [WARN] [app] at a level of my choosing 0 ERROR 2 1

LevelInfo

const LevelInfo: i32 = 1
The info level: ordinary events.

The example for this item is shown with the ones above: log-Info.salam

LevelWarn

const LevelWarn: i32 = 2
The warn level: something unusual, but not an error.

The example for this item is shown with the ones above: log-Info.salam

LevelError

const LevelError: i32 = 3
The error level.

The example for this item is shown with the ones above: log-Info.salam

FormatText

const FormatText: i32 = 0
The readable text format.
log-InfoKV.salam
import log

func main:
    log.ToStdout()
    log.ShowTime(false)
    mut keys := Vector {} as Vector<str>
    mut values := Vector {} as Vector<str>
    defer keys.free()
    defer values.free()
    keys.push("user")
    values.push("sara")
    keys.push("ms")
    values.push("42")
    log.InfoKV("request served", keys, values)
    log.WarnKV("it was slow", keys, values)
    log.ErrorKV("it failed", keys, values)
    log.SetLevel(log.LevelDebug)
    log.DebugKV("the details", keys, values)
    log.SetFormat(log.FormatJSON)
    log.Info("as JSON")
    println log.GetFormat() == log.FormatJSON, log.FormatText
    mut fields := Vector {} as Vector<str>
    defer fields.free()
    fields.push(log.Field("path", "/login"))
    fields.push(log.FieldInt("status", 200))
    fields.push(log.FieldBool("cached", false))
    println log.KV("response", fields)
end
Output[INFO] request served user=sara ms=42 [WARN] it was slow user=sara ms=42 [ERROR] it failed user=sara ms=42 [DEBUG] the details user=sara ms=42 {"level": "INFO", "msg": "as JSON"} true 0 response path=/login status=200 cached=false

FormatJSON

const FormatJSON: i32 = 1
The JSON format, one object per line, for log collectors.

The example for this item is shown with the ones above: log-InfoKV.salam

Functions

LevelName

func LevelName(l: int): str
The English name of a level.

The example for this item is shown with the ones above: log-Info.salam

ParseLevel

func ParseLevel(s: str): int
Turns text such as "warn" into a level, for reading the level from a configuration file.

The example for this item is shown with the ones above: log-Info.salam

SetLevel

func SetLevel(l: int)
The lowest level that is recorded.

The example for this item is shown with the ones above: log-Info.salam

GetLevel

func GetLevel(): int
The current level.

The example for this item is shown with the ones above: log-Info.salam

SetPrefix

func SetPrefix(p: str)
A prefix that comes after the level on every message.

The example for this item is shown with the ones above: log-Info.salam

ShowTime

func ShowTime(b: bool)
Whether to show the time on each message.

The example for this item is shown with the ones above: log-Info.salam

SetFormat

func SetFormat(f: int)
The text or JSON format.

The example for this item is shown with the ones above: log-InfoKV.salam

GetFormat

func GetFormat(): int
The current format.

The example for this item is shown with the ones above: log-InfoKV.salam

SetRotation

func SetRotation(max_bytes: i64, max_backups: int)
For a file log: when the file grows past max_bytes it is set aside, and at most max_backups old copies are kept.
log-ToFile.salam
import log
import io

func main:
    log.ShowTime(false)
    println log.ToFile("app.log")
    log.SetRotation(1024 * 1024, 3)
    log.Info("written to the file")
    log.CloseFile()
    log.ToStderr()
    print io.ReadFile("app.log")
end
Output0 [INFO] written to the file

ToStderr

func ToStderr()
Write the log to standard error, which is the default.

The example for this item is shown with the ones above: log-ToFile.salam

ToStdout

func ToStdout()
Write the log to standard output.

The example for this item is shown with the ones above: log-Info.salam

ToFile

func ToFile(path: str): int
Write the log to a file, or return minus one when it cannot.

The example for this item is shown with the ones above: log-ToFile.salam

CloseFile

func CloseFile()
Closes the log file.

The example for this item is shown with the ones above: log-ToFile.salam

Log

func Log(l: int, msg: str)
Records a message at the level you choose.

The example for this item is shown with the ones above: log-Info.salam

Debug

func Debug(msg: str)
A debug message.

The example for this item is shown with the ones above: log-Info.salam

Info

func Info(msg: str)
An info message.

The example for this item is shown with the ones above: log-Info.salam

Warn

func Warn(msg: str)
A warning.

The example for this item is shown with the ones above: log-Info.salam

Error

func Error(msg: str)
An error message.

The example for this item is shown with the ones above: log-Info.salam

Debugf

func Debugf(tmpl: str, args: Vector<str>)
A formatted debug message; every {} is filled with the next value.
log-Infof.salam
import log

func main:
    log.ToStdout()
    log.ShowTime(false)
    mut args := Vector {} as Vector<str>
    defer args.free()
    args.push("Sara")
    args.push("3")
    log.Infof("user {} signed in and has {} messages", args)
    log.Warnf("a failed attempt for {}", args)
    log.Errorf("user {} was blocked", args)
    log.SetLevel(log.LevelDebug)
    log.Debugf("id {}", args)
end
Output[INFO] user Sara signed in and has 3 messages [WARN] a failed attempt for Sara [ERROR] user Sara was blocked [DEBUG] id Sara

Infof

func Infof(tmpl: str, args: Vector<str>)
A formatted info message.

The example for this item is shown with the ones above: log-Infof.salam

Warnf

func Warnf(tmpl: str, args: Vector<str>)
A formatted warning.

The example for this item is shown with the ones above: log-Infof.salam

Errorf

func Errorf(tmpl: str, args: Vector<str>)
A formatted error message.

The example for this item is shown with the ones above: log-Infof.salam

Fatal

func Fatal(msg: str)
Records an error message and ends the program with code one. Its example is not run here.
log-Fatal.salam
import log

func main:
    log.Fatal("the configuration file was not found")
end

Field

func Field(key: str, val: str): str
Builds one key=value field.

The example for this item is shown with the ones above: log-InfoKV.salam

FieldInt

func FieldInt(key: str, val: i64): str
A field with a numeric value.

The example for this item is shown with the ones above: log-InfoKV.salam

FieldBool

func FieldBool(key: str, val: bool): str
A field with a boolean value.

The example for this item is shown with the ones above: log-InfoKV.salam

KV

func KV(msg: str, fields: Vector<str>): str
Puts a message and its fields together.

The example for this item is shown with the ones above: log-InfoKV.salam

DebugKV

func DebugKV(msg: str, keys: Vector<str>, vals: Vector<str>)
A debug message with key and value fields.

The example for this item is shown with the ones above: log-InfoKV.salam

InfoKV

func InfoKV(msg: str, keys: Vector<str>, vals: Vector<str>)
An info message with fields, which makes logs much easier to search.

The example for this item is shown with the ones above: log-InfoKV.salam

WarnKV

func WarnKV(msg: str, keys: Vector<str>, vals: Vector<str>)
A warning with fields.

The example for this item is shown with the ones above: log-InfoKV.salam

ErrorKV

func ErrorKV(msg: str, keys: Vector<str>, vals: Vector<str>)
An error message with fields.

The example for this item is shown with the ones above: log-InfoKV.salam