
Json.pudu
Pudu59 lines2.9 KB
1/** @Log.Formatting.Json.Formatter — events as JSON documents */2module PuduLangLog.Formatting.Json34import Std.Option as Option5import PuduLangLog.Domain.Dates as Dates6import PuduLangLog.Domain.Display as Display7import PuduLangLog.Domain.Json as Json8import PuduLangLog.Domain.Levels as Levels9import PuduLangLog as Log1011/** @Log.Formatting.Json.Options — message rendering and line ending */12export type Options = { renderMessage: Bool, closingDelimiter: Str }131415const TYPE_TAG: Str = "_typeTag"161718export fn defaults() -> Options { Options{renderMessage: false, closingDelimiter: "\n"} }1920212223export fn formatter(options: Options) -> Log.Formatter {24 fn(event: &Log.Event) -> Str {25 var members = [26 "\"Timestamp\":" + Json.quote(Dates.roundTrip(&event.timestamp)),27 "\"Level\":" + Json.quote(Levels.name(event.level)),28 "\"MessageTemplate\":" + Json.quote(event.template.text)29 ]30 if options.renderMessage { members = members.push("\"RenderedMessage\":" + Json.quote(Display.plain(&Display.message(&event.template, &event.properties, &None)))) }31 if let Some(trace) = event.traceId { members = members.push("\"TraceId\":" + Json.quote(trace)) }32 if let Some(span) = event.spanId { members = members.push("\"SpanId\":" + Json.quote(span)) }33 if let Some(problem) = event.failure { members = members.push("\"Exception\":" + Json.quote(Display.failure(&problem))) }34 if !event.properties.isEmpty() {35 let properties = event.properties.map(|property: Log.Property| Json.quote(property.name) + ":" + Json.value(&property.value, &Some(TYPE_TAG)))36 members = members.push("\"Properties\":\{" + properties.join(",") + "\}")37 }38 let renderings = renderingsOf(event)39 if !renderings.isEmpty() { members = members.push("\"Renderings\":\{" + renderings.join(",") + "\}") }40 "\{" + members.join(",") + "\}" + options.closingDelimiter41 }42}434445fn renderingsOf(event: &Log.Event) -> Array[Str] {46 let formatted = event.template.holes.filter(|hole: Log.Hole| hole.format != None)47 var names: Array[Str] = []48 for hole in formatted {49 if !names.contains(hole.name) { names = names.push(hole.name) }50 }51 names.map(|name: Str| {52 let entries = formatted.filter(|hole: Log.Hole| hole.name == name).map(|hole: Log.Hole| {53 let rendering = Display.plain(&Display.hole(&hole, &event.properties, true, false))54 "\{\"Format\":" + Json.quote(Option.unwrapOr(hole.format, "")) + ",\"Rendering\":" + Json.quote(rendering) + "\}"55 })56 Json.quote(name) + ":[" + entries.join(",") + "]"57 })58}59