mirror of
https://codeberg.org/icewind/logsmash.git
synced 2026-06-03 10:04:12 +02:00
log file stats
This commit is contained in:
parent
246b4552f9
commit
19c1c57acc
2 changed files with 55 additions and 0 deletions
|
|
@ -11,3 +11,6 @@ regex = "1.10.5"
|
|||
log = "0.4.22"
|
||||
clap = { version = "=4.1.3", features = ["derive"] }
|
||||
cloud-log-analyser-data = { version = "0.1.0", path = "./data" }
|
||||
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 3
|
||||
52
src/main.rs
52
src/main.rs
|
|
@ -3,12 +3,18 @@ use clap::Parser;
|
|||
use cloud_log_analyser_data::get_statements;
|
||||
use serde::Deserialize;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::iter::once;
|
||||
use std::ops::AddAssign;
|
||||
|
||||
mod matcher;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
enum Args {
|
||||
Log(LogCommand),
|
||||
File(FileCommand),
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
|
|
@ -16,6 +22,11 @@ struct LogCommand {
|
|||
line: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
struct FileCommand {
|
||||
file: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct LogLine<'a> {
|
||||
version: &'a str,
|
||||
|
|
@ -41,5 +52,46 @@ fn main() {
|
|||
eprintln!("No match found");
|
||||
}
|
||||
}
|
||||
Args::File(FileCommand { file }) => {
|
||||
let file = BufReader::new(File::open(file).unwrap());
|
||||
let mut counts: HashMap<usize, usize> = HashMap::default();
|
||||
let mut lines = file.lines().flatten();
|
||||
let first = lines.next().unwrap();
|
||||
let first_parsed: LogLine = serde_json::from_str(&first).unwrap();
|
||||
|
||||
let major = first_parsed.version.split(".").next().unwrap();
|
||||
let major = major.parse().unwrap();
|
||||
let statements = get_statements("server", major);
|
||||
let matcher = Matcher::new(statements);
|
||||
|
||||
let lines = once(first).chain(lines);
|
||||
let mut error_count = 0;
|
||||
for line in lines {
|
||||
if line.starts_with('{') {
|
||||
let parsed = match serde_json::from_str::<LogLine>(&line) {
|
||||
Ok(parsed) => parsed,
|
||||
Err(_) => {
|
||||
error_count += 1;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if let Some(index) =
|
||||
matcher.match_log(parsed.level.into(), parsed.message.as_ref())
|
||||
{
|
||||
counts.entry(index).or_default().add_assign(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut counts: Vec<(_, _)> = counts.into_iter().collect();
|
||||
counts.sort_by_key(|(_, count)| *count);
|
||||
counts.reverse();
|
||||
for (index, count) in counts {
|
||||
let statement = &statements[index];
|
||||
println!("{} line {}: {}", statement.path, statement.line, count);
|
||||
}
|
||||
if error_count > 0 {
|
||||
eprintln!("{error_count} lines failed to parse as valid log json");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue