Merge branch 'fern' into 'master'
Logging to stdout and 2 separate files: human-readable logs and stats for processing See merge request rad/software/hailsens_logger_rs!1
This commit is contained in:
commit
754cd667d9
3 changed files with 112 additions and 47 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
|
@ -235,26 +235,12 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.0"
|
||||
name = "fern"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
|
||||
checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"humantime",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -272,7 +258,7 @@ dependencies = [
|
|||
"colored",
|
||||
"crc",
|
||||
"ctrlc",
|
||||
"env_logger",
|
||||
"fern",
|
||||
"hound",
|
||||
"log",
|
||||
"serialport",
|
||||
|
|
@ -291,12 +277,6 @@ version = "3.5.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ edition = "2021"
|
|||
[dependencies]
|
||||
serialport = {version="4.3", default-features=false}
|
||||
log = "0.4"
|
||||
env_logger = "0.11"
|
||||
chrono = "0.4"
|
||||
fern = "0.6"
|
||||
colored = "2.1"
|
||||
chrono = "0.4"
|
||||
hound = "3.5"
|
||||
clap = { version = "4.5", features = ["derive"] }
|
||||
ctrlc = "3.4"
|
||||
|
|
|
|||
127
src/main.rs
127
src/main.rs
|
|
@ -1,7 +1,7 @@
|
|||
use chrono::{Local, Timelike};
|
||||
use clap::{arg, Parser};
|
||||
use crc::{Crc, CRC_16_IBM_3740};
|
||||
use env_logger::Builder;
|
||||
use fern::Dispatch;
|
||||
use hound::{SampleFormat, WavSpec, WavWriter};
|
||||
use log::{debug, error, info, trace, warn, Level, LevelFilter};
|
||||
use serialport::SerialPort;
|
||||
|
|
@ -53,11 +53,18 @@ impl fmt::Display for StatsOnDetect {
|
|||
|
||||
impl fmt::Display for Stats10Min {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"In last 10 min: Hail detected: {}. Noise detected: {}.",
|
||||
self.hail, self.noise,
|
||||
)
|
||||
write!(f, "{} {}.", self.hail, self.noise,)
|
||||
}
|
||||
}
|
||||
|
||||
impl Stats10Min {
|
||||
fn nice_log_format(input: &str) -> Option<String> {
|
||||
let parts: Vec<&str> = input.split_whitespace().collect();
|
||||
let hail = parts.first()?;
|
||||
let noise = parts.get(1)?;
|
||||
Some(format!(
|
||||
"In last 10 min: Hail detected: {hail}. Noise detected: {noise}."
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,6 +118,12 @@ struct Args {
|
|||
#[arg(long, default_value = "wave")]
|
||||
name: String,
|
||||
|
||||
#[arg(long)]
|
||||
app_logs_path: Option<String>,
|
||||
|
||||
#[arg(long)]
|
||||
stat_logs_path: Option<String>,
|
||||
|
||||
#[arg(long, default_value = "./out/")]
|
||||
path: String,
|
||||
|
||||
|
|
@ -118,18 +131,61 @@ struct Args {
|
|||
verbose: u8,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
let log_level = match args.verbose {
|
||||
fn init_logger(
|
||||
verbosity: u8,
|
||||
app_log_path: Option<&Path>,
|
||||
stat_log_path: Option<&Path>,
|
||||
) -> Result<(), fern::InitError> {
|
||||
|
||||
let log_level = match verbosity {
|
||||
0 => LevelFilter::Info,
|
||||
1 => LevelFilter::Debug,
|
||||
_ => LevelFilter::Trace,
|
||||
};
|
||||
let mut builder = Builder::new();
|
||||
builder
|
||||
.format(|buf, record| {
|
||||
|
||||
let app_dispatch = app_log_path.map(|path| {
|
||||
Dispatch::new()
|
||||
.format(|out, message, record| {
|
||||
let now = Local::now();
|
||||
let message = message.to_string();
|
||||
out.finish(format_args!(
|
||||
"{} [{}] - {}",
|
||||
now.format("%Y-%m-%d %H:%M:%S%.3f"),
|
||||
record.level(),
|
||||
if record.target() == "stats10min" {
|
||||
Stats10Min::nice_log_format(&message)
|
||||
.expect("Couldn't get nice string for 10-min stats!")
|
||||
} else {
|
||||
message
|
||||
}
|
||||
))
|
||||
})
|
||||
.level(log_level)
|
||||
.chain(fern::log_file(path).unwrap())
|
||||
});
|
||||
|
||||
let stat_dispatch = stat_log_path.map(|path| {
|
||||
Dispatch::new()
|
||||
.level(LevelFilter::Info)
|
||||
.format(|out, message, _| {
|
||||
let now = Local::now();
|
||||
out.finish(format_args!(
|
||||
"{} {}",
|
||||
now.format("%Y-%m-%d %H:%M:%S%.3f"),
|
||||
message
|
||||
))
|
||||
})
|
||||
.filter(|metadata| {
|
||||
metadata.level() == Level::Info && metadata.target().contains("stats10min")
|
||||
})
|
||||
.chain(fern::log_file(path).unwrap())
|
||||
});
|
||||
|
||||
let stdout_dispatch = Dispatch::new()
|
||||
.format(|out, message, record| {
|
||||
use colored::*;
|
||||
let timestamp = Local::now().format("%Y-%m-%d %H:%M:%S,%3f");
|
||||
let now = Local::now();
|
||||
let message = message.to_string();
|
||||
let level = match record.level() {
|
||||
Level::Error => "ERROR".red(),
|
||||
Level::Warn => "WARN".yellow(),
|
||||
|
|
@ -137,11 +193,40 @@ fn main() {
|
|||
Level::Debug => "DEBUG".blue(),
|
||||
Level::Trace => "TRACE".purple(),
|
||||
};
|
||||
|
||||
writeln!(buf, "{} [{}] - {}", timestamp, level, record.args())
|
||||
out.finish(format_args!(
|
||||
"{} [{}] - {}",
|
||||
now.format("%Y-%m-%d %H:%M:%S%.3f"),
|
||||
level,
|
||||
if record.target() == "stats10min" {
|
||||
Stats10Min::nice_log_format(&message)
|
||||
.expect("Couldn't get nice string for 10-min stats!")
|
||||
} else {
|
||||
message
|
||||
}
|
||||
))
|
||||
})
|
||||
.filter(None, log_level)
|
||||
.init();
|
||||
.level(log_level)
|
||||
.chain(std::io::stdout());
|
||||
|
||||
let root_dispatch = Dispatch::new().chain(stdout_dispatch);
|
||||
let root_dispatch = match stat_dispatch {
|
||||
Some(dispatch) => root_dispatch.chain(dispatch),
|
||||
None => root_dispatch,
|
||||
};
|
||||
let root_dispatch = match app_dispatch {
|
||||
Some(dispatch) => root_dispatch.chain(dispatch),
|
||||
None => root_dispatch,
|
||||
};
|
||||
root_dispatch.apply()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
let app_logs_path = args.app_logs_path.as_deref().map(Path::new);
|
||||
let stat_logs_path = args.stat_logs_path.as_deref().map(Path::new);
|
||||
init_logger(args.verbose, app_logs_path, stat_logs_path)
|
||||
.expect("Failed to initialize the logger");
|
||||
|
||||
assert!(
|
||||
args.request_rate >= 1 && args.request_rate <= 100,
|
||||
|
|
@ -239,7 +324,7 @@ fn main() {
|
|||
handle_error_with_timeout(&mut err_counter);
|
||||
continue;
|
||||
}
|
||||
StatsOptions::Stats(val) => info!("{val}"),
|
||||
StatsOptions::Stats(val) => info!(target: "stats10min", "{val}"),
|
||||
StatsOptions::DetectedNew(cur_stats) => {
|
||||
err_counter = err_counter.saturating_sub(1);
|
||||
if prev_stats.map_or(true, |v| v != cur_stats) {
|
||||
|
|
@ -249,11 +334,11 @@ fn main() {
|
|||
cur_stats.hail_since_startup > prev_stats.hail_since_startup,
|
||||
cur_stats.noise_since_startup > prev_stats.noise_since_startup,
|
||||
) {
|
||||
(true, true) => info!("Hail and noise detected, {cur_stats}"),
|
||||
(true, false) => info!("Hail detected, {cur_stats}"),
|
||||
(true, true) => info!(target: "detected", "Hail and noise detected, {cur_stats}"),
|
||||
(true, false) => info!(target: "detected", "Hail detected, {cur_stats}"),
|
||||
(false, true) => {
|
||||
if args.noise_logging {
|
||||
info!("Noise detected, {cur_stats}")
|
||||
info!(target: "detected", "Noise detected, {cur_stats}")
|
||||
}
|
||||
}
|
||||
(false, false) => (),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue