From 30dc9c01b43c3a6bd14d14048cb93a7f223e8a96 Mon Sep 17 00:00:00 2001 From: daywalker90 <8257956+daywalker90@users.noreply.github.com> Date: Mon, 26 Jan 2026 11:50:05 +0100 Subject: [PATCH] cln-plugin: add support for structured logging dependencies We filter out the metadata fields from the log-tracing bridge Changelog-None --- plugins/src/logging.rs | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/plugins/src/logging.rs b/plugins/src/logging.rs index 1d4e2c1b84eb..7800d84d9fdd 100644 --- a/plugins/src/logging.rs +++ b/plugins/src/logging.rs @@ -116,10 +116,21 @@ mod trace { ) { let mut extractor = LogExtract::default(); event.record(&mut extractor); - let message = match extractor.msg { + let mut message = match extractor.msg { Some(m) => m, None => return, }; + + // Append any additional fields to the message + if !extractor.fields.is_empty() { + let fields_str: Vec = extractor + .fields + .iter() + .map(|(k, v)| format!("{}=\"{}\"", k, v)) + .collect(); + message = format!("{} [{}]", message, fields_str.join(", ")); + } + let level = event.metadata().level().into(); self.sender.send(LogEntry { level, message }).unwrap(); } @@ -141,14 +152,26 @@ mod trace { #[derive(Default)] struct LogExtract { msg: Option, + fields: Vec<(String, String)>, } impl tracing::field::Visit for LogExtract { fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) { - if field.name() != "message" { - return; + let field_name = field.name(); + let field_value = format!("{value:?}"); + + if field_name == "message" { + self.msg = Some(field_value); + } else if !is_log_metadata_field(field_name) { + self.fields.push((field_name.to_owned(), field_value)); } - self.msg = Some(format!("{:?}", value)); } } + + fn is_log_metadata_field(name: &str) -> bool { + matches!( + name, + "log.target" | "log.module_path" | "log.file" | "log.line" + ) + } }