Skip to content

Settings

Chris Michael edited this page Sep 29, 2026 · 1 revision

Pudu

Settings

Settings.apply changes a configuration from key-value settings and answers the configuration with the level switches it declared, or every problem at once.

Key Meaning
MinimumLevel, MinimumLevel:Default the minimum level
MinimumLevel:ControlledBy a level switch, $name
MinimumLevel:Override:Source a level or $switch for a source prefix
LevelSwitches:$name a switch and its initial level
Properties:Name a text property on every event
Enrich:i, Enrich:i:Name, Enrich:i:Args:arg a registered enricher
WriteTo:i, WriteTo:i:Name, WriteTo:i:Args:arg a registered sink; restrictedToMinimumLevel and levelSwitch apply to any sink
AuditTo:… the same, for audit sinks
Filter:i:ByExcluding, Filter:i:ByIncludingOnly a filter expression
Destructure:MaximumDepth, MaximumStringLength, MaximumCollectionCount, AsScalar:i capture limits and tags kept as text

Settings come from Settings.fromJson, fromJsonFile (under a section such as Log), and fromEnvironment (APP__MinimumLevel__Default=Debug). Registry.standard() names the Console, File, and Http sinks and the enrichers MachineName, EnvironmentUserName, EnvironmentName, EnvironmentVariable, ProcessId, ProcessName, and FailureDetail; withSink and withEnricher add your own.

module Ex08Settings

import Std.Io as Io
import PuduLangLog.Configuration as Configuration
import PuduLangLog.LevelSwitch as LevelSwitch
import PuduLangLog as Log
import PuduLangLog.Logger as Logger
import PuduLangLog.Settings as Settings
import PuduLangLog.Settings.Registry as Registry
import PuduLangLog.Sink as Sink
import PuduLangLog.Sinks.Memory as Memory
import PuduLangLog.Value as Value

const DOCUMENT: Array[Str] = [
  "\{\"Log\": \{",
  "  \"MinimumLevel\": \{\"Default\": \"Debug\", \"Override\": \{\"Shop.Http\": \"Warning\", \"Shop.Jobs\": \"$jobs\"\}\},",
  "  \"LevelSwitches\": \{\"$jobs\": \"Error\"\},",
  "  \"Properties\": \{\"Application\": \"Shop\"\},",
  "  \"Enrich\": [\{\"Name\": \"EnvironmentName\", \"Args\": \{\"variable\": \"SHOP_ENVIRONMENT\"\}\}],",
  "  \"Filter\": [\{\"ByExcluding\": \"RequestPath like '/health%'\"\}],",
  "  \"WriteTo\": [\{\"Name\": \"Memory\", \"Args\": \{\"prefix\": \"> \"\}\}]",
  "\}\}"
]

export fn main() -> Int {
  let store = Memory.create()
  let registry = Registry.standard().withSink("Memory", fn(arguments: &Array[(Str, Str)]) -> Result[Sink.Sink, Str] {
      let prefix = match Settings.argument(arguments, "prefix") {
        case Some(given) => given
        case None => ""
      }
      let _noted = Io.writeLine("building the memory sink with prefix `" + prefix + "`")
      Ok(Memory.sink(&store))
    })
  let pairs = match Settings.fromJson(DOCUMENT.join("\n"), "Log") {
    case Ok(found) => found
    case Err(problem) => panic(problem)
  }
  for (key, value) in pairs { let _pair = Io.writeLine(key + " = " + value) }
  let loaded = match Settings.apply(&Configuration.create(), &pairs, &registry) {
    case Ok(found) => found
    case Err(problems) => panic(problems.join("; "))
  }
  let logger = loaded.configuration.createLogger()
  logger.debug("debug is on", [])
  logger.information("GET \{RequestPath\}", [Value.text("/health")])
  logger.forSource("Shop.Http.Client").information("dropped by the override", [])
  logger.forSource("Shop.Jobs").warning("dropped by the switch", [])
  if let Some(jobs) = Settings.switchNamed(&loaded, "$jobs") { LevelSwitch.set(&jobs, Log.Warning) }
  logger.forSource("Shop.Jobs").warning("kept once the switch moved", [])
  let _kept = Io.writeLine("kept: " + Memory.messages(&store).join(" | "))
  match Settings.apply(&Configuration.create(), &[("MinimumLevel", "Loud"), ("WriteTo:0", "Queue"), ("Filter:0:ByExcluding", "Count >")], &registry) {
    case Ok(_) => {}
    case Err(problems) => {
      for problem in problems { let _problem = Io.writeLine("problem: " + problem) }
    }
  }
  Logger.close(&logger)
  0
}

Check it and run it:

pudu check src/Ex08Settings.pudu
pudu run src/Ex08Settings.pudu

Output:

MinimumLevel:Default = Debug
MinimumLevel:Override:Shop.Http = Warning
MinimumLevel:Override:Shop.Jobs = $jobs
LevelSwitches:$jobs = Error
Properties:Application = Shop
Enrich:0:Name = EnvironmentName
Enrich:0:Args:variable = SHOP_ENVIRONMENT
Filter:0:ByExcluding = RequestPath like '/health%'
WriteTo:0:Name = Memory
WriteTo:0:Args:prefix = > 
building the memory sink with prefix `> `
kept: debug is on | kept once the switch moved
problem: Unknown or malformed setting `MinimumLevel`
problem: The filter `Count >`: the expression ends too soon
problem: No sink is registered as `Queue`

Related

Clone this wiki locally