
Environment.pudu
Pudu105 lines3.9 KB
1/** @Log.Enrichers.Environment.Module — machine, user, process, and failure properties */2module PuduLangLog.Enrichers.Environment34import Std.Env as Env5import Std.List as List6import Std.Option as Option7import Std.Process as Process8import Std.Result as Result9import PuduLangLog.Enricher as Enricher10import PuduLangLog as Log111213export const ENVIRONMENT_VARIABLE: Str = "PUDU_ENVIRONMENT"141516const PRODUCTION: Str = "Production"17181920export fn machineName() -> Enricher.Enricher {21 let name = match firstVariable(["HOSTNAME", "COMPUTERNAME"]) {22 case Some(found) => found23 case None => Result.unwrapOr(Process.output("hostname", &[]), "").trim()24 }25 Enricher.property("MachineName", Log.Scalar(Log.Text(name)))26}272829export fn environmentUserName() -> Enricher.Enricher {30 let name = match firstVariable(["USER", "USERNAME"]) {31 case Some(found) => found32 case None => ""33 }34 Enricher.property("EnvironmentUserName", Log.Scalar(Log.Text(name)))35}363738export fn environmentName(variable: Str) -> Enricher.Enricher {39 let name = match firstVariable([variable]) {40 case Some(found) => found41 case None => PRODUCTION42 }43 Enricher.property("EnvironmentName", Log.Scalar(Log.Text(name)))44}454647export fn processId() -> Enricher.Enricher {48 let answer = Result.unwrapOr(Process.output("sh", &["-c", "echo $PPID"]), "").trim()49 let held = match answer.toInt() {50 case Some(number) => Log.Scalar(Log.Integer(number))51 case None => Log.Scalar(Log.Null)52 }53 Enricher.property("ProcessId", held)54}555657export fn processName() -> Enricher.Enricher {58 let answer = Result.unwrapOr(Process.output("sh", &["-c", "ps -o comm= -p $PPID"]), "").trim()59 let name = Option.unwrapOr(List.last(&answer.split("/")), answer)60 Enricher.property("ProcessName", if name.isEmpty() { Log.Scalar(Log.Null) } else { Log.Scalar(Log.Text(name)) })61}62636465export fn environmentVariable(variable: Str) -> Enricher.Enricher {66 match Env.variable(variable) {67 case Some(found) => Enricher.property(variable, Log.Scalar(Log.Text(found)))68 case None => Enricher.all([])69 }70}71727374export fn failureDetail() -> Enricher.Enricher {75 Enricher.computed("FailureDetail", fn(event: &Log.Event) -> Log.Value {76 match event.failure {77 case Some(problem) => detailOf(&problem)78 case None => Log.Scalar(Log.Null)79 }80 }, true)81}828384fn detailOf(problem: &Log.Failure) -> Log.Value {85 Log.Structure(Log.Structure {86 tag: Some(problem.kind),87 properties: [88 Log.Property{name: "Kind", value: Log.Scalar(Log.Text(problem.kind))},89 Log.Property{name: "Message", value: Log.Scalar(Log.Text(problem.message))},90 Log.Property{name: "Trace", value: Log.Sequence(problem.trace.map(|line: Str| Log.Scalar(Log.Text(line))))},91 Log.Property{name: "Causes", value: Log.Sequence(problem.causes.map(|cause: Log.Failure| detailOf(&cause)))}92 ]93 })94}959697fn firstVariable(names: Array[Str]) -> Option[Str] {98 for name in names {99 if let Some(found) = Env.variable(name) {100 if !found.trim().isEmpty() { return Some(found.trim()) }101 }102 }103 None104}105