moonzero · control plane v0.15.0 · 49 packages · 4 targets · Apache-2.0 docs / control / logx GitHub

05 / CONTROL

logx

Structured logging over moonlog's sink: the four level names an etc/*.yaml carries, the @timestamp / content keys a collector indexes, the WithDuration view, and a logger whose level and destination move at runtime.

struct Logger

structA leveled, structured logger: entries below the configured level are dropped without being rendered, and everything else reaches the sink as one record carrying @timestamp, level, content, an optional duration, and any extra fields. The timestamp is milliseconds from the injected Clock, not a formatted calendar time: MoonBit has no portable date formatter, and the clock is already how every other timed layer here reads the time.

let stamp_key : String = "@timestamp"

letThe key the entry's time is written under.

let message_key : String = "content"

letThe key the message is written under.

let duration_key : String = "duration"

letThe key the elapsed time is written under.

fn entry(record : @moonlog.Record) -> String

fnOne entry as the single-line JSON object emits: @timestamp, level, content, then whatever else the entry carries. This is the default sink's format, not a rule — hand Logger::new another moonlog sink and the same records are rendered that sink's way.

let level_key : String = "level"

letThe key the level is written under.

fn level_name(level : @moonlog.Level) -> String

fnname for a level. fatal reads as severe, which is what calls its top level and what its collectors filter on.

fn Logger::new( clock : @clock.Clock, level~ : LogLevel = Info, sink~ : &@moonlog.Sink = @moonlog.Lines::new(line => println(line))) -> Logger

fnA logger writing to sink at level and above. Every record reaches the sink with its [entry] line already rendered; the default sink prints that line. Logger::new(clock, sink=@moonlog.Discard::new()) is how a test silences one.

fn Logger::level(self : Logger) -> LogLevel

fnThe level below which entries are dropped.

fn Logger::set_level(self : Logger, level : LogLevel) -> Unit

fnRaise or lower the threshold, for this logger and every view derived from it.

fn Logger::set_sink(self : Logger, sink : &@moonlog.Sink) -> Unit

fnSend entries to another sink, for this logger and every view derived from it — a file, a collector client, a buffer under test. The sink is handed the record and line, and may write either.

fn Logger::set_writer(self : Logger, writer : (String) -> Unit) -> Unit

fnSend entries somewhere other than stdout, keeping line format. [Logger::set_sink] changes the format too.

fn Logger::enabled(self : Logger, level : LogLevel) -> Bool

fnWhether an entry at level would be written.

fn Logger::with_duration(self : Logger, ms : Int64) -> Logger

fnA view of this logger that stamps duration on every entry, sharing the level and sink with the original.

fn Logger::log( self : Logger, level : LogLevel, content : String, fields~ : Array[(String, Json)] = []) -> Unit

fnRender and write one entry, unless level is below the threshold.

fn Logger::debug( self : Logger, content : String, fields~ : Array[(String, Json)] = []) -> Unit

fnWrite a debug entry.

fn Logger::info( self : Logger, content : String, fields~ : Array[(String, Json)] = []) -> Unit

fnWrite an info entry.

fn Logger::error( self : Logger, content : String, fields~ : Array[(String, Json)] = []) -> Unit

fnWrite an error entry.

fn Logger::severe( self : Logger, content : String, fields~ : Array[(String, Json)] = []) -> Unit

fnWrite a severe entry.

let logx : Logger = Logger::new(@clock.Clock::system())

letThe process-wide logger: what the middlewares write to when no logger is handed to them, on the system clock at info. RestEngine::new points its level at the loaded Log.Level.

fn set_log_level(level : LogLevel) -> Unit

fnSet the process logger's level.

fn set_log_writer(writer : (String) -> Unit) -> Unit

fnSend the process logger's entries to writer.

fn set_log_sink(sink : &@moonlog.Sink) -> Unit

fnSend the process logger's entries to sink.

enum LogLevel

enum

fn LogLevel::to_string(self : LogLevel) -> String

fnThe canonical lowercase name uses on the wire.

fn LogLevel::as_level(self : LogLevel) -> @moonlog.Level

fnThe moonlog level this one records as. ladder has four rungs and moonlog's has six, so the map is one-way: Severe records as fatal, and [level_name] writes it back out as severe.

fn LogLevel::parse(s : String) -> LogLevel

fnParse a level name, falling back to Info for anything unrecognised — the same lenient default applies to a missing/empty level.

extend LogLevel with Compare::

item

extend LogLevel with Debug::

item

extend LogLevel with Eq::

item

extend LogLevel with FromJson::

item

impl @json.FromJson for LogLevel with fn from_json(json, path)

itemDecode a LogLevel from a JSON string ("debug"/"info"/"error"/ "severe"), reusing LogLevel::parse's lenient fallback to Info. This impl lets ServiceConf's derived FromJson read log_level as a plain string — the way writes it in YAML/JSON config — instead of a tagged variant.