diff --git a/src/main.rs b/src/main.rs index 30d0384..9c25a15 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,6 +41,10 @@ struct Args { /// jq expression(s) to evaluate on JSON text messages for logging (can be specified multiple times) #[arg(short = 'j', long = "jaq")] jaq: Vec, + + /// Normalize JSON messages: save as .json with pretty-printing and sorted keys (for easier diffing) + #[arg(short = 'n', long = "json-normalize")] + json_normalize: bool, } #[tokio::main] @@ -263,6 +267,7 @@ async fn main() -> Result<(), Box> { for (letter, url, ws_stream) in connections { let session_dir = session_dir.clone(); let jaq_filters = jaq_filters.clone(); + let json_normalize = args.json_normalize; join_set.spawn(async move { let (_, mut read) = ws_stream.split(); @@ -336,10 +341,30 @@ async fn main() -> Result<(), Box> { } } - // Always write full message to file - let filename = - session_dir.join(format!("{}{}.txt", letter, seq_num)); - if let Err(e) = fs::write(&filename, &text) { + // Write message to file + let (filename, content) = if json_normalize { + if let Ok(json_val) = + serde_json::from_str::(&text) + { + let pretty = + serde_json::to_string_pretty(&json_val).unwrap_or(text.clone()); + ( + session_dir.join(format!("{}{}.json", letter, seq_num)), + pretty, + ) + } else { + ( + session_dir.join(format!("{}{}.txt", letter, seq_num)), + text.clone(), + ) + } + } else { + ( + session_dir.join(format!("{}{}.txt", letter, seq_num)), + text.clone(), + ) + }; + if let Err(e) = fs::write(&filename, content) { error!("[{}] Failed to write {:?}: {}", letter, filename, e); } }