diff --git a/Cargo.lock b/Cargo.lock index 2ec92b2..e0b9020 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -482,6 +482,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.52.0", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -602,6 +612,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "derive-into-owned" version = "0.2.0" @@ -1310,6 +1329,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.4.2" @@ -1360,6 +1385,15 @@ dependencies = [ "libc", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "object" version = "0.32.2" @@ -1487,6 +1521,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1679,6 +1719,7 @@ dependencies = [ "rayhunter", "serde", "serde_json", + "simple_logger", "tempfile", "thiserror", "tokio", @@ -1901,6 +1942,18 @@ dependencies = [ "quote", ] +[[package]] +name = "simple_logger" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c5dfa5e08767553704aa0ffd9d9794d527103c736aba9854773851fd7497eb" +dependencies = [ + "colored", + "log", + "time", + "windows-sys 0.48.0", +] + [[package]] name = "slab" version = "0.4.9" @@ -2065,6 +2118,39 @@ dependencies = [ "weezl", ] +[[package]] +name = "time" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tokio" version = "1.36.0" diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 939985a..28d4e97 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -32,3 +32,4 @@ clap = { version = "4.5.2", features = ["derive"] } serde_json = "1.0.114" image = "0.25.1" tempfile = "3.10.1" +simple_logger = "5.0.0" diff --git a/bin/src/check.rs b/bin/src/check.rs index 02fa0bd..3637369 100644 --- a/bin/src/check.rs +++ b/bin/src/check.rs @@ -1,5 +1,6 @@ use std::{collections::HashMap, future, path::PathBuf, pin::pin}; -use rayhunter::{analysis::analyzer::Harness, diag::DataType, gsmtap_parser, pcap::GsmtapPcapWriter, qmdl::QmdlReader}; +use log::{info, warn}; +use rayhunter::{analysis::analyzer::{EventType, Harness}, diag::DataType, gsmtap_parser, pcap::GsmtapPcapWriter, qmdl::QmdlReader}; use tokio::fs::{metadata, read_dir, File}; use clap::Parser; use futures::TryStreamExt; @@ -9,7 +10,7 @@ mod dummy_analyzer; #[derive(Parser, Debug)] #[command(version, about)] struct Args { - #[arg(short, long)] + #[arg(long)] qmdl_path: PathBuf, #[arg(short, long)] @@ -20,6 +21,9 @@ struct Args { #[arg(long)] enable_dummy_analyzer: bool, + + #[arg(short, long)] + quiet: bool, } async fn analyze_file(harness: &mut Harness, qmdl_path: &str, show_skipped: bool) { @@ -41,20 +45,37 @@ async fn analyze_file(harness: &mut Harness, qmdl_path: &str, show_skipped: bool } for analysis in row.analysis { for maybe_event in analysis.events { - if let Some(event) = maybe_event { - warnings += 1; - println!("{}: {:?}", analysis.timestamp, event); + let Some(event) = maybe_event else { continue }; + match event.event_type { + EventType::Informational => { + info!( + "{}: INFO - {} {}", + qmdl_path, + analysis.timestamp, + event.message, + ); + } + EventType::QualitativeWarning { severity } => { + warn!( + "{}: WARNING (Severity: {:?}) - {} {}", + qmdl_path, + severity, + analysis.timestamp, + event.message, + ); + warnings += 1; + } } } } } if show_skipped && skipped > 0 { - println!("{}: messages skipped:", qmdl_path); + info!("{}: messages skipped:", qmdl_path); for (reason, count) in skipped_reasons.iter() { - println!(" - {}: \"{}\"", count, reason); + info!(" - {}: \"{}\"", count, reason); } } - println!("{}: {} messages analyzed, {} warnings, {} messages skipped", qmdl_path, total_messages, warnings, skipped); + info!("{}: {} messages analyzed, {} warnings, {} messages skipped", qmdl_path, total_messages, warnings, skipped); } async fn pcapify(qmdl_path: &PathBuf) { @@ -75,21 +96,30 @@ async fn pcapify(qmdl_path: &PathBuf) { } } } - println!("wrote pcap to {:?}", &pcap_path); + info!("wrote pcap to {:?}", &pcap_path); } #[tokio::main] async fn main() { - env_logger::init(); let args = Args::parse(); + let level = if args.quiet { + log::LevelFilter::Warn + } else { + log::LevelFilter::Trace + }; + simple_logger::SimpleLogger::new() + .with_colors(true) + .without_timestamps() + .with_level(level) + .init().unwrap(); let mut harness = Harness::new_with_all_analyzers(); if args.enable_dummy_analyzer { harness.add_analyzer(Box::new(dummy_analyzer::TestAnalyzer { count: 0 })); } - println!("Analyzers:"); + info!("Analyzers:"); for analyzer in harness.get_metadata().analyzers { - println!(" - {}: {}", analyzer.name, analyzer.description); + info!(" - {}: {}", analyzer.name, analyzer.description); } let metadata = metadata(&args.qmdl_path).await.expect("failed to get metadata");