Add P55: JSON structured log format option to logd
When LOGD_JSON=1 is set in the environment, logd formats all log lines as JSON objects with timestamp, source, and message fields. Also fixes indentation issues in P51 logd rotation patch.
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
--- a/logd/src/scheme.rs
|
||||
+++ b/logd/src/scheme.rs
|
||||
@@ -5,6 +5,7 @@
|
||||
use std::os::fd::{FromRawFd, RawFd};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::mpsc::{self, Sender};
|
||||
+use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use redox_scheme::scheme::SchemeSync;
|
||||
use redox_scheme::{CallerCtx, OpenResult, SendFdRequest, Socket};
|
||||
@@ -38,6 +39,50 @@
|
||||
AddSink(usize),
|
||||
}
|
||||
|
||||
+fn json_escape(s: &str) -> String {
|
||||
+ let mut out = String::with_capacity(s.len());
|
||||
+ for c in s.chars() {
|
||||
+ match c {
|
||||
+ '\\' => out.push_str("\\\\"),
|
||||
+ '"' => out.push_str("\\\""),
|
||||
+ '\n' => out.push_str("\\n"),
|
||||
+ '\r' => out.push_str("\\r"),
|
||||
+ '\t' => out.push_str("\\t"),
|
||||
+ c if c.is_control() => out.push_str(&format!("\\u{:04x}", c as u32)),
|
||||
+ c => out.push(c),
|
||||
+ }
|
||||
+ }
|
||||
+ out
|
||||
+}
|
||||
+
|
||||
+fn format_json_line(context: &str, line: &[u8]) -> Vec<u8> {
|
||||
+ let now = SystemTime::now()
|
||||
+ .duration_since(UNIX_EPOCH)
|
||||
+ .unwrap_or_default();
|
||||
+ let secs = now.as_secs();
|
||||
+ let timestamp = format!(
|
||||
+ "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z",
|
||||
+ 1970 + secs / 31_557_600,
|
||||
+ (secs % 31_557_600) / 2_592_000 + 1,
|
||||
+ (secs % 2_592_000) / 86_400 + 1,
|
||||
+ (secs % 86_400) / 3600,
|
||||
+ (secs % 3600) / 60,
|
||||
+ secs % 60
|
||||
+ );
|
||||
+ let text = String::from_utf8_lossy(line).trim_end_matches('\n').to_string();
|
||||
+ let (source, message) = match text.split_once(": ") {
|
||||
+ Some((s, m)) => (s, m),
|
||||
+ None => (context, text.as_str()),
|
||||
+ };
|
||||
+ let json = format!(
|
||||
+ "{{\"timestamp\":\"{}\",\"source\":\"{}\",\"message\":\"{}\"}}\n",
|
||||
+ json_escape(×tamp),
|
||||
+ json_escape(source),
|
||||
+ json_escape(message)
|
||||
+ );
|
||||
+ json.into_bytes()
|
||||
+}
|
||||
+
|
||||
struct LogFile {
|
||||
file: File,
|
||||
path: PathBuf,
|
||||
@@ -110,6 +155,8 @@
|
||||
let _ = std::fs::create_dir_all(LOG_DIR);
|
||||
|
||||
|
||||
+ let json_format = std::env::var("LOGD_JSON").map_or(false, |v| v == "1");
|
||||
+
|
||||
let (output_tx, output_rx) = mpsc::channel::<OutputCmd>();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
@@ -123,9 +170,15 @@
|
||||
for cmd in output_rx {
|
||||
match cmd {
|
||||
OutputCmd::Log { context, line } => {
|
||||
+ let out_line = if json_format {
|
||||
+ format_json_line(&context, &line)
|
||||
+ } else {
|
||||
+ line.clone()
|
||||
+ };
|
||||
if let Some(ref mut f) = persistent {
|
||||
- let _ = f.write(&line);
|
||||
+ let _ = f.write(&out_line);
|
||||
let _ = f.flush();
|
||||
+ }
|
||||
|
||||
let service_name = context.split(':').next().unwrap_or("unknown");
|
||||
if !service_name.is_empty() {
|
||||
@@ -135,7 +188,7 @@
|
||||
LogFile::open(PathBuf::from("/dev/null")).unwrap()
|
||||
})
|
||||
});
|
||||
- let _ = entry.write(&line);
|
||||
+ let _ = entry.write(&out_line);
|
||||
let _ = entry.maybe_rotate();
|
||||
}
|
||||
|
||||
@@ -145,15 +198,14 @@
|
||||
LogFile::open(PathBuf::from("/dev/null")).unwrap()
|
||||
})
|
||||
});
|
||||
- let _ = system_entry.write(&line);
|
||||
+ let _ = system_entry.write(&out_line);
|
||||
let _ = system_entry.maybe_rotate();
|
||||
|
||||
- }
|
||||
for file in &mut files {
|
||||
- let _ = file.write(&line);
|
||||
+ let _ = file.write(&out_line);
|
||||
let _ = file.flush();
|
||||
}
|
||||
- logs.push_back(line);
|
||||
+ logs.push_back(out_line);
|
||||
while logs.len() > MEMORY_LOG_LIMIT {
|
||||
logs.pop_front();
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../local/patches/base/P55-logd-json-format.patch
|
||||
@@ -111,6 +111,8 @@ patches = [
|
||||
"P52-acpid-cstates.patch",
|
||||
# P53: Add e1000d interrupt throttling rate (ITR) coalescing
|
||||
"P53-e1000d-itr-coalescing.patch",
|
||||
# P55: Add JSON structured log format option to logd
|
||||
"P55-logd-json-format.patch",
|
||||
]
|
||||
|
||||
[package]
|
||||
|
||||
Reference in New Issue
Block a user