Skip to content

Commit

Permalink
Merge pull request #20 from pamburus/feature/regex
Browse files Browse the repository at this point in the history
new: field filter with regular expressions
  • Loading branch information
pamburus authored Jul 29, 2021
2 parents 1160cfc + 61f1b58 commit 39e9fbb
Show file tree
Hide file tree
Showing 10 changed files with 423 additions and 93 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ categories = ["command-line-utilities"]
description = "Utility for viewing json-formatted log files."
keywords = ["cli", "human", "log"]
name = "hl"
version = "0.10.1"
version = "0.10.2"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down Expand Up @@ -34,6 +34,7 @@ itertools = "0"
num_cpus = "1"
once_cell = "1"
platform-dirs = "0"
regex = "1"
rust-embed = "5"
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["raw_value"] }
Expand Down Expand Up @@ -94,3 +95,7 @@ harness = false
[[bench]]
name = "parse-and-format"
harness = false

[[bench]]
name = "json"
harness = false
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ Log viewer which translates JSON logs into pretty human-readable representation.
### Complete set of options and flags

```
hl 0.10.0
hl 0.10.2
JSON log converter to human readable representation

USAGE:
Expand All @@ -316,7 +316,7 @@ OPTIONS:
--buffer-size <buffer-size> Buffer size [env: HL_BUFFER_SIZE=] [default: 2 MiB]
--color <color> Color output options, one of { auto, always, never } [env: HL_COLOR=] [default: auto]
-C, --concurrency <concurrency> Number of processing threads [env: HL_CONCURRENCY=]
-f, --filter <filter>... Filtering by field values in one of forms <key>=<value>, <key>~=<value>, <key>!=<value>, <key>!~=<value>
-f, --filter <filter>... Filtering by field values in one of forms [<key>=<value>, <key>~=<value>, <key>~~=<value>, <key>!=<value>, <key>!~=<value>, <key>!~~=<value>] where ~ denotes substring match and ~~ denotes regular expression match
-h, --hide <hide>... Hide fields with the specified keys
-e, --hide-empty-fields <hide-empty-fields> Hide empty fields, applies for null, string, object and array fields only [env: HL_HIDE_EMPTY_FIELDS=]
--interrupt-ignore-count <interrupt-ignore-count> Number of interrupts to ignore, i.e. Ctrl-C (SIGINT) [env: HL_INTERRUPT_IGNORE_COUNT=] [default: 3]
Expand Down
46 changes: 46 additions & 0 deletions benches/json.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// std imports
use std::alloc::System;

// third-party imports
use criterion::{criterion_group, criterion_main, Criterion};
use serde_json as json;
use stats_alloc::{Region, StatsAlloc, INSTRUMENTED_SYSTEM};

#[global_allocator]
static GLOBAL: &StatsAlloc<System> = &INSTRUMENTED_SYSTEM;

fn benchmark(c: &mut Criterion) {
let mut c = c.benchmark_group("json");

let mut c1 = None;
let mut n1 = 0;
c.bench_function("parse-to-str", |b| {
let sample = r#""test-message""#;
let reg = Region::new(&GLOBAL);
b.iter(|| {
assert_eq!(json::from_str::<&str>(sample).unwrap(), "test-message");
n1 += 1;
});
c1 = Some(reg.change());
});
println!("allocations at 1 ({:?} iterations): {:#?}", n1, c1);

let mut c2 = None;
let mut n2 = 0;
c.bench_function("parse-to-string", |b| {
let sample = r#""test-\"message\"""#;
let reg = Region::new(&GLOBAL);
b.iter(|| {
assert_eq!(
json::from_str::<String>(sample).unwrap(),
r#"test-"message""#
);
n2 += 1;
});
c2 = Some(reg.change());
});
println!("allocations at 2 ({:?} iterations): {:#?}", n2, c2);
}

criterion_group!(benches, benchmark);
criterion_main!(benches);
4 changes: 4 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub enum Error {
Utf8Error(#[from] std::str::Utf8Error),
#[error("failed to parse yaml: {0}")]
YamlError(#[from] serde_yaml::Error),
#[error("wrong field filter format: {0}")]
WrongFieldFilter(String),
#[error("wrong regular expression: {0}")]
WrongRegularExpression(#[from] regex::Error),
}

/// Result is an alias for standard result with bound Error type.
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod eseq;
mod filtering;
mod formatting;
mod model;
mod pool;
mod scanning;

// conditional public modules
Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ struct Opt {
)]
concurrency: Option<usize>,
//
/// Filtering by field values in one of forms <key>=<value>, <key>~=<value>, <key>!=<value>, <key>!~=<value>.
/// Filtering by field values in one of forms [<key>=<value>, <key>~=<value>, <key>~~=<value>, <key>!=<value>, <key>!~=<value>, <key>!~~=<value>] where ~ denotes substring match and ~~ denotes regular expression match.
#[structopt(short, long, number_of_values = 1)]
filter: Vec<String>,
//
Expand Down Expand Up @@ -283,7 +283,7 @@ fn run() -> Result<()> {
let time_format = LinuxDateFormat::new(&opt.time_format).compile();
// Configure filter.
let filter = hl::Filter {
fields: hl::FieldFilterSet::new(opt.filter),
fields: hl::FieldFilterSet::new(opt.filter)?,
level: opt.level,
since: if let Some(v) = &opt.since {
Some(parse_time(v, &tz, &time_format)?.into())
Expand Down
Loading

0 comments on commit 39e9fbb

Please sign in to comment.