
Configuration.pudu
Pudu208 lines10.7 KB
1/** @Log.Configuration.Builder — assembles a logger's pipeline step by step */2module PuduLangLog.Configuration34import Std.List as List5import PuduLangLog.Clock as Clock6import PuduLangLog.Domain.Capture as Capture7import PuduLangLog.Domain.Masking as Masking8import PuduLangLog.Enricher as Enricher9import PuduLangLog.Filter as Filter10import PuduLangLog.LevelSwitch as LevelSwitch11import PuduLangLog as Log12import PuduLangLog.Logger as Logger13import PuduLangLog.Pipeline as Pipeline14import PuduLangLog.SelfLog as SelfLog15import PuduLangLog.Sink as Sink1617/** @Log.Configuration.Settings — every choice a pipeline is built from */18export type Configuration = {19 minimum: Log.Level,20 control: Option[LevelSwitch.LevelSwitch],21 overrides: Array[Pipeline.Override],22 enrichers: Array[Enricher.Enricher],23 filters: Array[Filter.Filter],24 sinks: Array[Sink.Sink],25 audits: Array[Sink.Sink],26 policy: Capture.Policy,27 selfLog: SelfLog.SelfLog,28 clock: Clock.Clock29}30313233export fn create() -> Configuration {34 Configuration {35 minimum: Log.Information,36 control: None,37 overrides: [],38 enrichers: [],39 filters: [],40 sinks: [],41 audits: [],42 policy: Capture.defaults(),43 selfLog: SelfLog.create(),44 clock: Clock.system()45 }46}47484950export fn nested() -> Configuration { Configuration{..create(), minimum: Log.Verbose} }515253export fn pipelineOf(configuration: &Configuration) -> Pipeline.Pipeline {54 Pipeline.Pipeline {55 minimum: configuration.minimum,56 control: configuration.control,57 overrides: List.sortOn(&configuration.overrides, |entry: Pipeline.Override| entry.source.toLower()).reverse(),58 enrichers: configuration.enrichers,59 filters: configuration.filters,60 sink: Sink.aggregate(configuration.sinks, &configuration.selfLog),61 audit: if configuration.audits.isEmpty() { None } else { Some(Sink.audited(configuration.audits)) },62 policy: configuration.policy,63 selfLog: configuration.selfLog,64 clock: configuration.clock,65 templates: Pipeline.templates(),66 silent: false67 }68}6970/** @Log.Configuration.Configuring — one decision changed per call */71export trait Configuring {72 fn createLogger(self: &Self) -> Logger.Logger73 fn createReloadableLogger(self: &Self) -> Logger.Logger74 fn minimumLevel(self: &Self, level: Log.Level) -> Self75 fn controlledBy(self: &Self, control: &LevelSwitch.LevelSwitch) -> Self76 fn overrideLevel(self: &Self, source: Str, level: Log.Level) -> Self77 fn overrideSwitch(self: &Self, source: Str, control: &LevelSwitch.LevelSwitch) -> Self78 fn writeTo(self: &Self, sink: Sink.Sink) -> Self79 fn writeToAtLeast(self: &Self, sink: Sink.Sink, minimum: Log.Level) -> Self80 fn writeToControlled(self: &Self, sink: Sink.Sink, control: &LevelSwitch.LevelSwitch) -> Self81 fn writeToWhen(self: &Self, condition: fn(&Log.Event) -> Bool, sink: Sink.Sink) -> Self82 fn writeToLogger(self: &Self, logger: &Logger.Logger) -> Self83 fn writeToFallible(self: &Self, sink: Sink.Sink, listener: fn(&Sink.Report) -> ()) -> Self84 fn writeToFallbackChain(self: &Self, sinks: Array[Sink.Sink]) -> Self85 fn auditTo(self: &Self, sink: Sink.Sink) -> Self86 fn enrichWith(self: &Self, enricher: Enricher.Enricher) -> Self87 fn enrichWithProperty(self: &Self, name: Str, held: Log.Value) -> Self88 fn filterWith(self: &Self, filter: Filter.Filter) -> Self89 fn filterExcluding(self: &Self, predicate: fn(&Log.Event) -> Bool) -> Self90 fn filterIncludingOnly(self: &Self, predicate: fn(&Log.Event) -> Bool) -> Self91 fn destructureByTransforming(self: &Self, tag: Str, transform: fn(Log.Value) -> Log.Value) -> Self92 fn destructureAsScalar(self: &Self, tag: Str) -> Self93 fn destructureWithRule(self: &Self, rule: fn(&Log.Value) -> Option[Log.Value]) -> Self94 fn destructureByIgnoring(self: &Self, tag: Str, names: Array[Str]) -> Self95 fn destructureByMasking(self: &Self, tag: Str, names: Array[Str], mask: Str) -> Self96 fn maximumDepth(self: &Self, depth: Int) -> Self97 fn maximumStringLength(self: &Self, length: Int) -> Self98 fn maximumCollectionCount(self: &Self, count: Int) -> Self99 fn selfLog(self: &Self, log: &SelfLog.SelfLog) -> Self100 fn clock(self: &Self, clock: Clock.Clock) -> Self101}102103impl Configuring for Configuration {104 105 106 fn createLogger(self: &Self) -> Logger.Logger { Logger.fromPipeline(pipelineOf(self)) }107108 109 110 fn createReloadableLogger(self: &Self) -> Logger.Logger { Logger.reloadable(pipelineOf(self)) }111112 113 fn minimumLevel(self: &Self, level: Log.Level) -> Self { Configuration{..*self, minimum: level, control: None} }114115 116 fn controlledBy(self: &Self, control: &LevelSwitch.LevelSwitch) -> Self { Configuration{..*self, minimum: Log.Verbose, control: Some(*control)} }117118 119 fn overrideLevel(self: &Self, source: Str, level: Log.Level) -> Self { self.overrideSwitch(source, &LevelSwitch.create(level)) }120121 122 123 fn overrideSwitch(self: &Self, source: Str, control: &LevelSwitch.LevelSwitch) -> Self {124 let others = self.overrides.filter(|existing: Pipeline.Override| existing.source.toLower() != source.toLower())125 Configuration{..*self, overrides: others.push(Pipeline.Override{source: source, control: *control})}126 }127128 129 fn writeTo(self: &Self, sink: Sink.Sink) -> Self { Configuration{..*self, sinks: self.sinks.push(sink)} }130131 132 fn writeToAtLeast(self: &Self, sink: Sink.Sink, minimum: Log.Level) -> Self { self.writeTo(Sink.restricted(sink, minimum)) }133134 135 fn writeToControlled(self: &Self, sink: Sink.Sink, control: &LevelSwitch.LevelSwitch) -> Self { self.writeTo(Sink.controlled(sink, control)) }136137 138 fn writeToWhen(self: &Self, condition: fn(&Log.Event) -> Bool, sink: Sink.Sink) -> Self { self.writeTo(Sink.conditional(sink, condition)) }139140 141 fn writeToLogger(self: &Self, logger: &Logger.Logger) -> Self { self.writeTo(Logger.asSink(logger)) }142143 144 fn writeToFallible(self: &Self, sink: Sink.Sink, listener: fn(&Sink.Report) -> ()) -> Self { self.writeTo(Sink.fallible(sink, listener)) }145146 147 fn writeToFallbackChain(self: &Self, sinks: Array[Sink.Sink]) -> Self { self.writeTo(Sink.fallbackChain(sinks)) }148149 150 fn auditTo(self: &Self, sink: Sink.Sink) -> Self { Configuration{..*self, audits: self.audits.push(sink)} }151152 153 fn enrichWith(self: &Self, enricher: Enricher.Enricher) -> Self { Configuration{..*self, enrichers: self.enrichers.push(enricher)} }154155 156 fn enrichWithProperty(self: &Self, name: Str, held: Log.Value) -> Self { self.enrichWith(Enricher.property(name, held)) }157158 159 fn filterWith(self: &Self, filter: Filter.Filter) -> Self { Configuration{..*self, filters: self.filters.push(filter)} }160161 162 fn filterExcluding(self: &Self, predicate: fn(&Log.Event) -> Bool) -> Self { self.filterWith(Filter.byExcluding(predicate)) }163164 165 fn filterIncludingOnly(self: &Self, predicate: fn(&Log.Event) -> Bool) -> Self { self.filterWith(Filter.byIncludingOnly(predicate)) }166167 168 fn destructureByTransforming(self: &Self, tag: Str, transform: fn(Log.Value) -> Log.Value) -> Self {169 Configuration{..*self, policy: Capture.Policy{..self.policy, transforms: self.policy.transforms.push(Capture.Transform{tag: tag, apply: transform})}}170 }171172 173 fn destructureAsScalar(self: &Self, tag: Str) -> Self {174 Configuration{..*self, policy: Capture.Policy{..self.policy, scalars: self.policy.scalars.push(tag)}}175 }176177 178 fn destructureWithRule(self: &Self, rule: fn(&Log.Value) -> Option[Log.Value]) -> Self {179 Configuration{..*self, policy: Capture.Policy{..self.policy, custom: self.policy.custom.push(rule)}}180 }181182 183 fn destructureByIgnoring(self: &Self, tag: Str, names: Array[Str]) -> Self {184 self.destructureWithRule(fn(held: &Log.Value) -> Option[Log.Value] { Masking.ignoring(held, tag, &names) })185 }186187 188 189 fn destructureByMasking(self: &Self, tag: Str, names: Array[Str], mask: Str) -> Self {190 self.destructureWithRule(fn(held: &Log.Value) -> Option[Log.Value] { Masking.masking(held, tag, &names, mask) })191 }192193 194 fn maximumDepth(self: &Self, depth: Int) -> Self { Configuration{..*self, policy: Capture.Policy{..self.policy, maximumDepth: depth}} }195196 197 fn maximumStringLength(self: &Self, length: Int) -> Self { Configuration{..*self, policy: Capture.Policy{..self.policy, maximumStringLength: length}} }198199 200 fn maximumCollectionCount(self: &Self, count: Int) -> Self { Configuration{..*self, policy: Capture.Policy{..self.policy, maximumCollectionCount: count}} }201202 203 fn selfLog(self: &Self, log: &SelfLog.SelfLog) -> Self { Configuration{..*self, selfLog: *log} }204205 206 fn clock(self: &Self, clock: Clock.Clock) -> Self { Configuration{..*self, clock: clock} }207}208