Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-log

Structured event logging for Pudu: message templates, enrichment, filtering, formatting, and sinks

0.1.0Apache-2.01

InstallClose

Enricher.pudu

Pudu67 lines3.0 KB

GitHub ↗
1/** @Log.Enricher.Stage — adds properties to events as they pass */2module PuduLangLog.Enricher34import PuduLangLog.Domain.Capture as Capture5import PuduLangLog.Domain.Levels as Levels6import PuduLangLog.Domain.Properties as Properties7import PuduLangLog.LevelSwitch as LevelSwitch8import PuduLangLog as Log910/** @Log.Enricher.Function — an event in, the enriched event out */11export type Enricher = fn(Log.Event, &Capture.Policy) -> Log.Event1213/// Adds a property unless the event already has one of that name; structures render to text.14export fn property(name: Str, held: Log.Value) -> Enricher { captured(name, held, Log.Default) }1516/// Adds a property unless the event already has one of that name, keeping structures.17export fn destructured(name: Str, held: Log.Value) -> Enricher { captured(name, held, Log.Destructure) }1819/// Adds a property captured under a hint unless the event already has one of that name.20fn captured(name: Str, held: Log.Value, hint: Log.Hint) -> Enricher {21  fn(event: Log.Event, policy: &Capture.Policy) -> Log.Event {22    if Properties.has(&event.properties, name) { return event }23    Log.Event{..event, properties: event.properties.push(Log.Property{name: name, value: Capture.capture(policy, &held, hint)})}24  }25}2627/// Adds a property computed from the event unless the event already has one of that name, keeping28/// structures when `destructure` is set.29export fn computed(name: Str, compute: fn(&Log.Event) -> Log.Value, destructure: Bool) -> Enricher {30  let hint = if destructure { Log.Destructure } else { Log.Default }31  fn(event: Log.Event, policy: &Capture.Policy) -> Log.Event {32    if Properties.has(&event.properties, name) { return event }33    let held = compute(&event)34    Log.Event{..event, properties: event.properties.push(Log.Property{name: name, value: Capture.capture(policy, &held, hint)})}35  }36}3738/// An enricher from a function over events.39export fn from(change: fn(Log.Event) -> Log.Event) -> Enricher {40  fn(event: Log.Event, _policy: &Capture.Policy) -> Log.Event { change(event) }41}4243/// Applies an enricher only to events the condition accepts.44export fn when(condition: fn(&Log.Event) -> Bool, enricher: Enricher) -> Enricher {45  fn(event: Log.Event, policy: &Capture.Policy) -> Log.Event { if condition(&event) { enricher(event, policy) } else { event } }46}4748/// Applies an enricher only to events at or above a level.49export fn atLevel(minimum: Log.Level, enricher: Enricher) -> Enricher {50  when(fn(event: &Log.Event) -> Bool { Levels.passes(event.level, minimum) }, enricher)51}5253/// Applies an enricher only to events a level switch allows.54export fn atSwitch(control: &LevelSwitch.LevelSwitch, enricher: Enricher) -> Enricher {55  let shared = *control56  when(fn(event: &Log.Event) -> Bool { LevelSwitch.allows(&shared, event.level) }, enricher)57}5859/// Applies enrichers in order.60export fn all(enrichers: Array[Enricher]) -> Enricher {61  fn(event: Log.Event, policy: &Capture.Policy) -> Log.Event {62    var current = event63    for enricher in enrichers { current = enricher(current, policy) }64    current65  }66}67