witness
Types
A unit of structured data
Use these to create them:
witness.string
witness.int
witness.float
witness.bool
pub opaque type Field
The currently available formats
pub type Format {
Json
Text
}
Constructors
-
Json(Pretty printed for reading convenience)
{ "timestamp": "2026-05-28T18:30:40.020522296Z", "level": "info", "message": "Some log message", "example": "you can add structured data", "also_bools": true, "and_floats": 1.23, "ints_as_well": 3 } -
Text[INFO] 20:30:40 Some log message example: you can add structured data also_bools: True and_floats: 1.23 ints_as_well: 3
pub type Sink =
fn(logging.LogLevel, String) -> Nil
Values
pub fn bool(name name: String, value value: Bool) -> Field
Create a bool field
Example
witness.this(logging.Info, "Things happened", [witness.bool("really", True)])
pub fn default_config() -> Config
The default config logging to io.println with format witness.Text
pub fn empty_config() -> Config
Get a new empty config
Example
witness.empty_config()
|> with_sink(witness.Json, logging.log)
|> witness.set_config
pub fn float(name name: String, value value: Float) -> Field
Create a float field
Example
witness.this(logging.Info, "Things happened", [witness.float("how_many", 3.14159)])
pub fn int(name name: String, value value: Int) -> Field
Create an int field
Example
witness.this(logging.Info, "Things happened", [witness.int("how_many", 21)])
pub fn level_to_short_string(level: logging.LogLevel) -> String
Turn a log level into a “[LEVEL]” string
pub fn set_config(config: Config) -> Nil
Set your config globally
Example
witness.empty_config()
|> with_sink(witness.Json, logging.log)
|> witness.set_config
pub fn set_process_fields(fields: List(Field)) -> Nil
Put per process fields into the process dictionary.
These fields will be prepended to every message that process logs.
Example
witness.set_process_fields([
witness.string("process_name", "my special process"),
])
pub fn string(name name: String, value value: String) -> Field
Create a string field
Example
witness.this(logging.Info, "Something happened", [witness.string("what", "i dont know, honestly")])
pub fn this(
level level: logging.LogLevel,
message message: String,
fields fields: List(Field),
) -> Nil
pub fn with_global_fields(
config: Config,
fields: List(Field),
) -> Config
These fields will be prepended to every message logged through witness. Does not replace fields from previous calls.
Example
witness.empty_config()
|> with_sink(witness.Json, logging.log)
|> witness.with_global_fields([
witness.string("application", "my_application"),
witness.string("version", "1.0.0"),
])
|> witness.set_config