Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fields and message expansion feature #320

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ members = [".", "crate/encstr", "crate/heapopt"]
[workspace.package]
repository = "https://github.com/pamburus/hl"
authors = ["Pavel Ivanov <[email protected]>"]
version = "0.31.0-alpha.3"
version = "0.32.0-alpha.1+expansion"
edition = "2021"
license = "MIT"

Expand Down Expand Up @@ -61,6 +61,7 @@ itertools = "0.14"
itoa = { version = "1", default-features = false }
known-folders = "1"
log = "0"
mline = { path = "./crate/mline" }
nonzero_ext = "0"
notify = { version = "7", features = ["macos_kqueue"] }
nu-ansi-term = "0"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ Output Options:
--no-local Disable local time zone, overrides --local option
-e, --hide-empty-fields Hide empty fields, applies for null, string, object and array fields only [env: HL_HIDE_EMPTY_FIELDS=]
-E, --show-empty-fields Show empty fields, overrides --hide-empty-fields option [env: HL_SHOW_EMPTY_FIELDS=]
-x, --expansion <MODE> Whether to expand fields and messages [env: HL_EXPANSION=] [default: medium] [possible values: never, inline, low, medium, high, always]
--input-info <VARIANT> Show input number and/or input filename before each message [default: auto] [possible values: auto, none, full, compact, minimal]
-o, --output <FILE> Output file

Expand Down
53 changes: 29 additions & 24 deletions benches/parse-and-format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use criterion::{criterion_group, criterion_main, Criterion};
// local imports
use hl::{
app::{RecordIgnorer, SegmentProcess, SegmentProcessorOptions},
settings,
formatting::Expansion,
settings::ExpansionMode,
timezone::Tz,
DateTimeFormatter, Filter, IncludeExcludeKeyFilter, LinuxDateFormat, Parser, ParserSettings, RecordFormatter,
DateTimeFormatter, Filter, LinuxDateFormat, Parser, ParserSettings, RecordFormatter, RecordFormatterSettings,
SegmentProcessor, Settings, Theme,
};

Expand All @@ -20,29 +21,33 @@ use hl::{
fn benchmark(c: &mut Criterion) {
let mut c = c.benchmark_group("parse-and-format");
for (name, record) in [("kibana-record-01", KIBANA_RECORD_01)] {
for theme in ["universal", "classic"] {
c.bench_function(format!("{}/{}", name, theme), |b| {
let settings = Settings::default();
let parser = Parser::new(ParserSettings::new(&settings.fields.predefined, empty(), None));
let formatter = RecordFormatter::new(
Arc::new(Theme::embedded(theme).unwrap()),
DateTimeFormatter::new(
LinuxDateFormat::new("%b %d %T.%3N").compile(),
Tz::FixedOffset(Utc.fix()),
),
false,
Arc::new(IncludeExcludeKeyFilter::default()),
settings::Formatting::default(),
);
let filter = Filter::default();
let mut processor =
SegmentProcessor::new(&parser, &formatter, &filter, SegmentProcessorOptions::default());
let mut buf = Vec::new();
b.iter(|| {
processor.process(record, &mut buf, "", None, &mut RecordIgnorer {});
buf.clear();
for expansion in [ExpansionMode::Inline, ExpansionMode::Medium] {
for theme in ["universal", "classic"] {
c.bench_function(format!("{}/expansion-{}/theme-{}", name, expansion, theme), |b| {
let settings = Settings::default();
let parser = Parser::new(ParserSettings::new(&settings.fields.predefined, empty(), None));
let formatter = RecordFormatter::new(RecordFormatterSettings {
theme: Arc::new(Theme::embedded(theme).unwrap()),
ts_formatter: DateTimeFormatter::new(
LinuxDateFormat::new("%b %d %T.%3N").compile(),
Tz::FixedOffset(Utc.fix()),
),
expansion: Expansion {
mode: expansion,
..Default::default()
},
..Default::default()
});
let filter = Filter::default();
let mut processor =
SegmentProcessor::new(&parser, &formatter, &filter, SegmentProcessorOptions::default());
let mut buf = Vec::new();
b.iter(|| {
processor.process(record, &mut buf, "", None, &mut RecordIgnorer {});
buf.clear();
});
});
});
}
}
}
}
Expand Down
39 changes: 17 additions & 22 deletions benches/ts-format.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
use std::io::Write;
use std::{hint::black_box, io::Write};

use chrono::{format::strftime::StrftimeItems, Datelike, FixedOffset, Timelike};
use criterion::{criterion_group, criterion_main, Criterion};

use hl::datefmt::{DateTimeFormatter, LinuxDateFormat};
use hl::{timestamp::Timestamp, timezone::Tz};

#[inline(never)]
fn ignore<T>(t: T) {
drop(t)
}

fn benchmark(c: &mut Criterion) {
let mut c = c.benchmark_group("ts-format");
let tsr = Timestamp::new("2020-06-27T00:48:30.466249792+00:00");
Expand All @@ -19,15 +14,15 @@ fn benchmark(c: &mut Criterion) {
let tz = |secs| Tz::FixedOffset(FixedOffset::east_opt(secs).unwrap());
c.bench_function("chrono conversion to naive local", |b| {
b.iter(|| {
ignore(ts.naive_local());
black_box(ts.naive_local());
});
});
c.bench_function("datefmt format utc [%y-%m-%d %T.%N]", |b| {
let mut buf = Vec::<u8>::with_capacity(4096);
let format = LinuxDateFormat::new("%y-%m-%d %T.%N").compile();
let formatter = DateTimeFormatter::new(format, tz(0));
b.iter(|| {
formatter.format(&mut buf, ts);
black_box(formatter.format(&mut buf, ts));
buf.clear();
});
});
Expand All @@ -36,7 +31,7 @@ fn benchmark(c: &mut Criterion) {
let format = LinuxDateFormat::new("%y-%m-%d %T.%N").compile();
let formatter = DateTimeFormatter::new(format, tz(3 * 3600));
b.iter(|| {
formatter.format(&mut buf, ts);
black_box(formatter.format(&mut buf, ts));
buf.clear();
});
});
Expand All @@ -45,7 +40,7 @@ fn benchmark(c: &mut Criterion) {
let format = LinuxDateFormat::new("%b %d %T.%N").compile();
let formatter = DateTimeFormatter::new(format, tz(0));
b.iter(|| {
formatter.format(&mut buf, ts);
black_box(formatter.format(&mut buf, ts));
buf.clear();
});
});
Expand All @@ -54,7 +49,7 @@ fn benchmark(c: &mut Criterion) {
let format = LinuxDateFormat::new("%b %d %T.%N").compile();
let formatter = DateTimeFormatter::new(format, tz(3 * 3600));
b.iter(|| {
formatter.format(&mut buf, ts);
black_box(formatter.format(&mut buf, ts));
buf.clear();
});
});
Expand All @@ -64,7 +59,7 @@ fn benchmark(c: &mut Criterion) {
let formatter = DateTimeFormatter::new(format, tz(0));
let tsr = tsr.as_rfc3339().unwrap();
b.iter(|| {
formatter.reformat_rfc3339(&mut buf, tsr.clone());
black_box(formatter.reformat_rfc3339(&mut buf, tsr.clone()));
buf.clear();
});
});
Expand All @@ -74,7 +69,7 @@ fn benchmark(c: &mut Criterion) {
let formatter = DateTimeFormatter::new(format, tz(0));
let tsr = tsr.as_rfc3339().unwrap();
b.iter(|| {
formatter.reformat_rfc3339(&mut buf, tsr.clone());
black_box(formatter.reformat_rfc3339(&mut buf, tsr.clone()));
buf.clear();
});
});
Expand All @@ -84,20 +79,20 @@ fn benchmark(c: &mut Criterion) {
let formatter = DateTimeFormatter::new(format, tz(0));
let tsr = tsr.as_rfc3339().unwrap();
b.iter(|| {
formatter.reformat_rfc3339(&mut buf, tsr.clone());
black_box(formatter.reformat_rfc3339(&mut buf, tsr.clone()));
buf.clear();
});
});
c.bench_function("calling chrono date-time methods", |b| {
b.iter(|| {
assert!(
tsn.year() as i64
+ tsn.month() as i64
+ tsn.day() as i64
+ tsn.hour() as i64
+ tsn.minute() as i64
+ tsn.second() as i64
+ tsn.nanosecond() as i64
black_box(tsn.year()) as i64
+ black_box(tsn.month()) as i64
+ black_box(tsn.day()) as i64
+ black_box(tsn.hour()) as i64
+ black_box(tsn.minute()) as i64
+ black_box(tsn.second()) as i64
+ black_box(tsn.nanosecond()) as i64
!= 0
);
});
Expand All @@ -106,7 +101,7 @@ fn benchmark(c: &mut Criterion) {
c.bench_function("chrono format", |b| {
let mut buf = Vec::<u8>::with_capacity(4096);
b.iter(|| {
assert!(write!(&mut buf, "{}", ts.format_with_items(items.clone())).is_ok());
assert!(black_box(write!(&mut buf, "{}", ts.format_with_items(items.clone()))).is_ok());
buf.clear();
});
});
Expand Down
2 changes: 1 addition & 1 deletion build/ci/coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function test() {
${MAIN_EXECUTABLE:?} --config - --man-page > /dev/null
${MAIN_EXECUTABLE:?} --config - --list-themes > /dev/null
${MAIN_EXECUTABLE:?} --config - sample/prometheus.log -P > /dev/null
echo "" | ${MAIN_EXECUTABLE:?} --config - --concurrency 4 > /dev/null
echo "" | ${MAIN_EXECUTABLE:?} --config - --config=etc/defaults/config.yaml --concurrency 4 > /dev/null
}

function merge() {
Expand Down
2 changes: 2 additions & 0 deletions crate/encstr/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ impl fmt::Display for Error {
}
}
}

impl std::error::Error for Error {}
1 change: 1 addition & 0 deletions crate/heapopt/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
1 change: 1 addition & 0 deletions crate/heapopt/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[package]
name = "heapopt"
version = "0.1.0"
description = "Optimized collections for minimal heap usage"
repository.workspace = true
authors.workspace = true
edition.workspace = true
Expand Down
10 changes: 10 additions & 0 deletions crate/heapopt/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ impl<T, const N: usize> Vec<T, N> {
v
}

/// Creates a new vector from the given slice.
#[inline]
pub fn from_iter<I: IntoIterator<Item = T>>(src: I) -> Self {
let mut iter = src.into_iter();
Self {
head: heapless::Vec::from_iter(iter.by_ref().take(N)),
tail: std::vec::Vec::from_iter(iter),
}
}

/// Returns the number of elements in the vector.
#[inline]
pub fn len(&self) -> usize {
Expand Down
1 change: 1 addition & 0 deletions crate/mline/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
13 changes: 13 additions & 0 deletions crate/mline/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
description = "Multi-line string manipulation library for Rust"
name = "mline"
version = "0.1.0"
workspace = "../.."
repository.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true

[dependencies]
heapopt = { path = "../heapopt" }
itertools = "0.13"
Loading
Loading