ocs progress bar
All checks were successful
CI / build (push) Successful in 57s
CI / checks (push) Successful in 1m25s
CI / build-nixpkgs (push) Successful in 39s

This commit is contained in:
Robin Appelman 2025-08-06 15:30:03 +02:00
commit c5af0ac37a
3 changed files with 64 additions and 1 deletions

7
Cargo.lock generated
View file

@ -913,6 +913,7 @@ dependencies = [
"itertools 0.14.0",
"logsmash-data",
"main_error",
"osc94",
"ratatui",
"rayon",
"regex",
@ -1065,6 +1066,12 @@ version = "1.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
[[package]]
name = "osc94"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34f8ab1141a6a07f7a5f7fc5ca6f42770b1024b15d5987a044e853fe3ba8c71a"
[[package]]
name = "parking_lot"
version = "0.12.3"

View file

@ -32,6 +32,7 @@ sevenz-rust2 = "0.13.2"
dialoguer = "0.11.0"
indicatif = { version = "0.17.11", features = ["rayon"] }
csv = "1.3.1"
osc94 = "0.1.1"
[target.'cfg(target_env = "musl")'.dependencies]
tikv-jemallocator = "0.6.0"

View file

@ -9,12 +9,15 @@ use indicatif::{ParallelProgressIterator, ProgressStyle};
use logfile::logline::{Exception, FullException, FullLogLine, LogLine, CUSTOM_TIME_FORMAT};
use logsmash_data::{default_apps, get_statements, SourceDefinition};
use main_error::MainResult;
use osc94::Progress;
use rayon::prelude::*;
use std::borrow::Cow;
use std::collections::HashMap;
use std::fs::File;
use std::io::BufReader;
use std::io::{BufReader, Stderr, Write};
use std::iter::once;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::RwLock;
mod app;
mod error;
@ -73,6 +76,7 @@ fn main() -> MainResult {
.enumerate()
.map(|(line_number, line)| (LogLineNumber::from(line_number), line))
.collect();
let line_count = lines.len();
let mut counts: HashMap<MatchResult, Vec<LogIndex>> = HashMap::new();
let Some(first_parsed) = lines.iter().find_map(|(_, line)| parse_line(line).ok()) else {
@ -94,6 +98,8 @@ fn main() -> MainResult {
)
.expect("invalid progress bar style");
let progress = OcsProgress::new(line_count);
let mut results: Vec<_> = lines
.into_par_iter()
.map(|(line_number, line)| {
@ -101,6 +107,9 @@ fn main() -> MainResult {
if let Ok(parsed) = parsed.as_mut() {
parsed.line_number = line_number;
};
progress.icr();
parsed.map_err(|err| (line_number, err))
})
.progress_with_style(progress_style.clone())
@ -112,11 +121,15 @@ fn main() -> MainResult {
});
let parsed_log: ParsedLogs = results.into_iter().collect();
progress.reset();
let line_matches: Vec<_> = parsed_log
.all()
.par_iter()
.map(|line| (line.index, matcher.match_log(line)))
.inspect(|_| {
progress.icr();
})
.progress_with_style(progress_style)
.collect();
@ -162,6 +175,8 @@ fn main() -> MainResult {
return Ok(());
}
drop(progress);
run_ui(app)?;
Ok(())
@ -204,3 +219,43 @@ fn parse_line_full(mut line: &str) -> Result<FullLogLine, serde_json::Error> {
}
res
}
struct OcsProgress<W: Write> {
max: usize,
count: AtomicUsize,
progress: RwLock<Progress<W>>,
}
impl OcsProgress<Stderr> {
pub fn new(max: usize) -> Self {
let mut progress = Progress::default();
progress.start();
OcsProgress {
max,
count: AtomicUsize::default(),
progress: RwLock::new(progress),
}
}
}
impl<W: Write> OcsProgress<W> {
pub fn icr(&self) {
let items_done = self.count.fetch_add(1, Ordering::Relaxed);
let percent = (items_done * 100 / self.max) as u8;
if percent
> self
.progress
.read()
.map(|p| p.get_progress())
.unwrap_or_default()
{
if let Ok(mut p) = self.progress.try_write() {
let _ = p.progress(percent).flush();
}
}
}
pub fn reset(&self) {
self.count.store(0, Ordering::SeqCst);
self.progress.write().unwrap().progress(0);
}
}