silk/logger
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc.
Typed semantic logging with replaceable stdout and bounded in-memory providers.
When to use
Require Logger when code emits whole semantic messages but should not choose storage or
destination. Provide silk.os_logger.StdoutLogger at a native process edge. Use InMemoryLogger for
deterministic observation and failure tests.
Details
Each invocation carries one LogLevel, one static format template, and one borrowed argument
pack. Providers reuse silk.format to produce one semantic message without adding caller-visible
Writer or allocation requirements. The in-memory provider retains at most eight committed events
and 64 message bytes, and exposes attempted calls separately from successful commits.
Gotchas
Logger failures are typed LogError values and do not guarantee that a message committed.
In-memory accessors require an event index less than length and a valid message-byte index.
Examples
Record and inspect one warning
import silk.effect { Effect }
import silk.logger { Logger, LogError }
import silk.logger { LogLevel }
import silk.usize
effect fn program() -> i32
! LogError {
let mut logger = Logger.inMemoryProvider()
let logged = run Effect.logWarning("cache {kind} missed {count} times", &.{
kind: "users",
count: 3,
})
|> Effect.provideMut(&mut logger)
if Logger.length(&logger) != usize.ONE {
return 1
}
if Logger.levelAt(&logger, usize.ZERO) != LogLevel.Warning {
return 2
}
return 42
}
effect fn recover(error: LogError) -> i32 {
return 0
}
pub fn main() -> i32 {
return run Effect.catchAll(program(), recover)
}Import as Logger with import silk.logger { Logger }.
Public declarations: 4.
LogLevel
pub enum LogLevelOne closed logging severity from Trace through Error.
Trace
Trace = 0Detailed diagnostic events.
Debug
Debug = 1Development diagnostic events.
Info
Info = 2Ordinary operational events.
Warning
Warning = 3Recoverable abnormal conditions.
Error
Error = 4Operations that did not complete as intended.
LogError
pub struct LogErrorA typed failure reported by one Logger provider.
Details
The numeric code belongs to the provider. Portable code can recover from LogError without
assigning one meaning to that code across different providers.
Logger
pub service LoggerA replaceable service that formats and receives one complete semantic log event per call.
When to use
Use this service when library code must emit events without selecting stdout, memory, or another destination.
Details
Each call carries one severity, one static template, and one borrowed argument pack. The service
does not require a newline, timestamp, prefix, allocation, or output destination. The provider
owns those choices and applies the shared silk.format contract.
Operation log
effect<'env> fn log<Args: 'env, 'life1: 'env, 'env>(level: LogLevel, static template: string<'static>, args: &'life1 Args) -> () ! LogError ? &mut LoggerFormats and submits one complete UTF-8 message at one severity to the active provider.
Details
Template validation and Display selection match Format.format. The call does not add a
newline, severity label, timestamp, or provider-independent decoration. A provider failure
produces LogError.
Associated function Logger.failure
pub fn failure(code: i32) -> LogErrorCreates a logging failure with a provider-defined code.
Associated function Logger.errorCode
pub fn errorCode(error: LogError) -> i32Returns the provider-defined failure code for diagnostics.
Gotchas
Interpret this code only with knowledge of the selected provider. Different providers can use the same code for different failures.
Associated function Logger.inMemoryProvider
pub fn inMemoryProvider() -> InMemoryLoggerCreates an empty in-memory logger with capacity for eight events and 64 message bytes.
Gotchas
A call fails when eight events are already committed. A call also fails when its bytes exceed the remaining 64-byte total. Neither failure commits the event.
Associated function Logger.inMemoryProviderFailAt
pub fn inMemoryProviderFailAt(failAt: usize) -> InMemoryLoggerCreates an in-memory logger that rejects one zero-based attempted-call ordinal.
Details
The configured attempt increases attempts but does not increase length or consume
message capacity. Other attempts retain the eight-event and 64-byte limits of
inMemoryProvider.
Associated function Logger.length
pub fn length<'life0>(self: &'life0 silk/logger.InMemoryLogger) -> usizeReturns the number of events that the in-memory logger committed.
Details
Failed attempts do not increase this count. Use attempts when rejected calls must also be
observed.
Associated function Logger.levelAt
pub fn levelAt<'life0>(self: &'life0 silk/logger.InMemoryLogger, index: usize) -> LogLevelReturns the severity of one committed event.
Gotchas
index must be less than length. An unused index below eight returns the initial Trace
value instead of trapping. An index of eight or more traps.
Associated function Logger.messageLengthAt
pub fn messageLengthAt<'life0>(self: &'life0 silk/logger.InMemoryLogger, index: usize) -> usizeReturns the UTF-8 byte length of one committed message.
Gotchas
index must be less than length. An unused index below eight returns zero instead of
trapping. An index of eight or more traps.
Associated function Logger.messageByteAt
pub fn messageByteAt<'life0>(self: &'life0 silk/logger.InMemoryLogger, eventIndex: usize, byteIndex: usize) -> u8Returns one UTF-8 byte from a committed message.
Gotchas
eventIndex must be less than length. byteIndex must be less than
messageLengthAt for that event. An unused event or invalid byte index traps. An event index
of eight or more also traps.
Associated function Logger.attempts
pub fn attempts<'life0>(self: &'life0 silk/logger.InMemoryLogger) -> usizeReturns the number of calls attempted, including calls that produced LogError.
InMemoryLogger
pub struct InMemoryLoggerA deterministic Logger provider that retains up to eight events and 64 total message bytes.
When to use
Use this provider in tests that must inspect event order, severity, message bytes, or failure behavior without process output.
Details
The provider copies each committed message into fixed internal storage. It records attempted calls separately from committed events. Capacity failure and configured failure do not commit an event.
Implementation Logger for InMemoryLogger
impl Logger for InMemoryLoggerOperation log
log = InMemoryLogger.record