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

Compact.pudu

Pudu57 lines2.7 KB

GitHub ↗
1/** @Log.Formatting.Compact.Formatter — events as compact newline-delimited JSON */2module PuduLangLog.Formatting.Compact34import PuduLangLog.Domain.Dates as Dates5import PuduLangLog.Domain.Display as Display6import PuduLangLog.Domain.EventId as EventId7import PuduLangLog.Domain.Json as Json8import PuduLangLog.Domain.Levels as Levels9import PuduLangLog as Log1011/// The UTC timestamp pattern of the `@t` member.12const UTC_PATTERN: Str = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffff'Z'"1314/// A formatter writing each event as one line: `@t`, `@mt`, `@r` for formatted holes, `@l` unless15/// the level is `Information`, `@x`, `@tr`, `@sp`, and the properties, names starting with `@`16/// doubled to `@@`.17export fn compact() -> Log.Formatter {18  fn(event: &Log.Event) -> Str {19    var members = [timestampOf(event), "\"@mt\":" + Json.quote(event.template.text)]20    let formatted = event.template.holes.filter(|hole: Log.Hole| hole.format != None)21    if !formatted.isEmpty() {22      let renderings = formatted.map(|hole: Log.Hole| Json.quote(Display.plain(&Display.hole(&hole, &event.properties, false, false))))23      members = members.push("\"@r\":[" + renderings.join(",") + "]")24    }25    "\{" + members.concat(tail(event)).join(",") + "\}\n"26  }27}2829/// A formatter like `compact` that writes the rendered message as `@m` and the template's30/// identifier as `@i` in place of the template and renderings.31export fn rendered() -> Log.Formatter {32  fn(event: &Log.Event) -> Str {33    let message = Display.plain(&Display.message(&event.template, &event.properties, &None))34    let members = [timestampOf(event), "\"@m\":" + Json.quote(message), "\"@i\":\"" + EventId.hex(EventId.compute(event.template.text)) + "\""]35    "\{" + members.concat(tail(event)).join(",") + "\}\n"36  }37}3839/// The `@t` member.40fn timestampOf(event: &Log.Event) -> Str {41  "\"@t\":" + Json.quote(Dates.formatMoment(&Log.Timestamp{..event.timestamp, offset: 0}, &Some(UTC_PATTERN)))42}4344/// The level, failure, trace, span, and property members.45fn tail(event: &Log.Event) -> Array[Str] {46  var members: Array[Str] = []47  if event.level != Log.Information { members = members.push("\"@l\":" + Json.quote(Levels.name(event.level))) }48  if let Some(problem) = event.failure { members = members.push("\"@x\":" + Json.quote(Display.failure(&problem))) }49  if let Some(trace) = event.traceId { members = members.push("\"@tr\":" + Json.quote(trace)) }50  if let Some(span) = event.spanId { members = members.push("\"@sp\":" + Json.quote(span)) }51  for property in event.properties {52    let name = if property.name.startsWith("@") { "@" + property.name } else { property.name }53    members = members.push(Json.quote(name) + ":" + Json.value(&property.value, &Some(Display.TYPE_TAG)))54  }55  members56}57