diff --git a/src/afterfact.rs b/src/afterfact.rs index 985ca493..82287678 100644 --- a/src/afterfact.rs +++ b/src/afterfact.rs @@ -153,6 +153,15 @@ pub fn after_fact(all_record_cnt: usize) { process::exit(1); } } + } else if let Some(json_path) = &configs::CONFIG.read().unwrap().args.json_timeline { + // output to file + match File::create(json_path) { + Ok(file) => Box::new(BufWriter::new(file)), + Err(err) => { + AlertMessage::alert(&format!("Failed to open file. {}", err)).ok(); + process::exit(1); + } + } } else { displayflag = true; // stdoutput (termcolor crate color output is not csv writer) @@ -172,8 +181,9 @@ fn emit_csv( ) -> io::Result<()> { let disp_wtr = BufferWriter::stdout(ColorChoice::Always); let mut disp_wtr_buf = disp_wtr.buffer(); + let json_output_flag = configs::CONFIG.read().unwrap().args.json_timeline.is_some(); - let mut wtr = if configs::CONFIG.read().unwrap().args.json_timeline { + let mut wtr = if json_output_flag { WriterBuilder::new() .delimiter(b'\n') .double_quote(true) @@ -207,7 +217,7 @@ fn emit_csv( let mut timestamps: Vec = Vec::new(); let mut plus_header = true; let mut detected_record_idset: HashSet = HashSet::new(); - if configs::CONFIG.read().unwrap().args.json_timeline { + if json_output_flag { wtr.write_field("[")?; } for time in message::MESSAGES.clone().into_read_only().keys().sorted() { @@ -242,7 +252,7 @@ fn emit_csv( false, ) .ok(); - } else if configs::CONFIG.read().unwrap().args.json_timeline { + } else if json_output_flag { wtr.write_field(" {")?; wtr.write_field(&output_json_str(&detect_info.ext_field))?; wtr.write_field(" },")?; @@ -299,9 +309,10 @@ fn emit_csv( .insert(detect_info.level.to_lowercase(), detect_counts_by_date); } } - if configs::CONFIG.read().unwrap().args.json_timeline { + if json_output_flag { wtr.write_field("]")?; } + if displayflag { println!(); } else { diff --git a/src/detections/configs.rs b/src/detections/configs.rs index 43929d2e..02c1dab8 100644 --- a/src/detections/configs.rs +++ b/src/detections/configs.rs @@ -225,8 +225,8 @@ pub struct Config { pub set_default_profile: Option, /// Output result in JSON format - #[clap(help_heading = Some("OTHER-ACTIONS"), short = 'j', long = "json-timeline")] - pub json_timeline: bool, + #[clap(help_heading = Some("OTHER-ACTIONS"), short = 'j', long = "json-timeline", value_name = "FILE")] + pub json_timeline: Option, } impl ConfigReader<'_> {