silk.io.logger_native.
Native providers of the Logger effect: StderrLogger writes log lines to standard error,
and StdoutLogger writes the bare messages to standard output.
When to use#
Provide StderrLogger for Logger in a native program. It is the normal choice for
diagnostics, because it keeps the log out of the program output. Provide StdoutLogger when
the messages are the output of the program. Code that logs uses silk.io.logger, so a test can
provide InMemoryLogger instead.
Details#
StderrLogger writes one line for each message: the level, a colon and a space, the formatted
message, and a newline, such as warning: disk 91% full. It holds the standard error lock of
silk.io.writer_native for the whole line, so lines of different threads do not mix. It formats into a
buffer of 64 bytes on the stack. Thus a short line is one system call, and the logger does not
allocate.
StderrLogger.make colors the level name when standard error is a terminal, the NO_COLOR
environment variable is not set or is empty, and TERM is not dumb. It checks once, at the
first message. StderrLogger.withColor turns color on or off without a check.
StdoutLogger formats each message directly to standard output. It adds no level, timestamp,
or newline, has no lock, and does not allocate.
Errors#
LogError with code 3 if the write fails. Part of the message can be written already.
Gotchas#
The providers exist on WASI, Darwin on aarch64, and Linux with GNU libc on x86_64 or aarch64.
A message template for
StderrLoggermust not end with a newline. The logger adds one.StderrLogger.makereads the environment at the first message. A change toNO_COLORafter that has no effect on the same logger.
Examples#
Log to standard error#
import silk.core.effect { Effect }
import silk.io.logger { LogError, Logger }
import silk.io.logger_native { StderrLogger }
pub effect fn main() -> i32
! LogError {
let mut logger = StderrLogger.make()
let values = .{ name: "silk", count: 3 }
// Writes "info: silk started 3 workers" and a newline to standard error.
run Effect.logInfo("{name} started {count} workers", &values)
|> Effect.provideMut<Logger>(&mut logger)
return 0
}Log to standard output#
import silk.core.effect { Effect }
import silk.io.logger { LogError, Logger }
import silk.io.logger_native { StdoutLogger }
pub effect fn main() -> i32
! LogError {
let mut logger = StdoutLogger.make()
let values = .{ name: "silk", count: 3 }
// The logger adds no newline, so the template ends with one.
run Effect.logInfo("{name} started {count} workers\n", &values)
|> Effect.provideMut<Logger>(&mut logger)
return 0
}WASI does not define terminal detection; automatic color selection is disabled on that target.
Import as StdoutLogger with import silk.io.logger_native { StdoutLogger }.
Public declarations: 2.
StderrLogger#
pub struct StderrLoggerA Logger provider that writes one line for each message to standard error, with the level.
Details#
Each line is the level name (trace, debug, info, warning, or error), a colon and a
space, the formatted message, and a newline. The logger holds the standard error lock of
silk.io.writer_native for the whole line. Thus lines of different threads do not mix, also with
StderrWriter writes. The logger does not allocate.
With color, the level name has an ANSI color: error bold red, warning bold yellow, info
green, debug blue, and trace cyan. The message has no color.
Gotchas#
The template must not end with a newline. The logger adds one.
Implementation StderrLogger#
impl StderrLoggerAssociated function make#
pub fn make() -> StderrLoggerReturns a logger that colors the level name when the terminal can show it. It does not write anything.
Details#
On WASI, automatic color selection stays disabled because WASI does not define terminal detection.
At the first message, the logger uses color when standard error is a terminal, NO_COLOR is
not set or is empty, and TERM is not dumb. Later messages use the same answer.
Associated function withColor#
pub fn withColor(enabled: bool) -> StderrLoggerReturns a logger that colors the level name when enabled is true, and never otherwise. It
does not check the terminal or the environment.
When to use#
Use it when the program has its own color setting, such as a --color flag.
Implementation Logger for StderrLogger#
impl Logger for StderrLoggerOperation log#
log: StderrLogger.writeStderrStdoutLogger#
pub struct StdoutLoggerA Logger provider that writes only the formatted message to standard output, and ignores the
level.
When to use#
Use it when the log messages are the output of the program. For diagnostics, use
StderrLogger.
Gotchas#
It adds no newline, so end each template with one. It has no lock, so messages of different threads can mix.
Implementation StdoutLogger#
impl StdoutLoggerAssociated function make#
pub fn make() -> StdoutLoggerReturns a logger. It does not write anything.
Implementation Logger for StdoutLogger#
impl Logger for StdoutLoggerOperation log#
log: StdoutLogger.writeStdoutCategory: Input and output.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, x86_64-unknown-linux-gnu, wasm32-wasip1, wasm32-wasip2.