Skip to content

Commit 9fc515d

Browse files
committed
output multiple metrics from a single log
1 parent 013ca8e commit 9fc515d

File tree

1 file changed

+57
-7
lines changed

1 file changed

+57
-7
lines changed

src/transforms/log_to_metric.rs

+57-7
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,14 @@ impl LogToMetric {
9090
}
9191

9292
impl Transform for LogToMetric {
93+
// Only used in tests
9394
fn transform(&mut self, event: Event) -> Option<Event> {
95+
let mut output = Vec::new();
96+
self.transform_into(&mut output, event);
97+
output.pop()
98+
}
99+
100+
fn transform_into(&mut self, output: &mut Vec<Event>, event: Event) {
94101
let event = event.into_log();
95102

96103
for metric in self.config.metrics.iter() {
@@ -99,17 +106,16 @@ impl Transform for LogToMetric {
99106
if let Some(val) = event.get(&counter.field) {
100107
if counter.increment_by_value {
101108
if let Ok(val) = val.to_string_lossy().parse::<f32>() {
102-
return Some(Event::Metric(Metric::Counter {
109+
output.push(Event::Metric(Metric::Counter {
103110
name: counter.sanitized_name.to_string(),
104111
val: val as u32,
105112
sampling: None,
106113
}));
107114
} else {
108115
trace!("failed to parse counter value");
109-
return None;
110116
}
111117
} else {
112-
return Some(Event::Metric(Metric::Counter {
118+
output.push(Event::Metric(Metric::Counter {
113119
name: counter.sanitized_name.to_string(),
114120
val: 1,
115121
sampling: None,
@@ -120,21 +126,18 @@ impl Transform for LogToMetric {
120126
MetricConfig::Gauge(gauge) => {
121127
if let Some(val) = event.get(&gauge.field) {
122128
if let Ok(val) = val.to_string_lossy().parse() {
123-
return Some(Event::Metric(Metric::Gauge {
129+
output.push(Event::Metric(Metric::Gauge {
124130
name: gauge.sanitized_name.to_string(),
125131
val,
126132
direction: None,
127133
}));
128134
} else {
129135
trace!("failed to parse gauge value");
130-
return None;
131136
}
132137
}
133138
}
134139
}
135140
}
136-
137-
None
138141
}
139142
}
140143

@@ -328,4 +331,51 @@ mod tests {
328331
let mut transform = LogToMetric::new(&config);
329332
assert!(transform.transform(log).is_none());
330333
}
334+
335+
#[test]
336+
fn multiple_metrics() {
337+
let config: LogToMetricConfig = toml::from_str(
338+
r##"
339+
[[metrics]]
340+
type = "counter"
341+
field = "status"
342+
labels = {status = "#{event.status}", host = "#{event.host}"}
343+
344+
[[metrics]]
345+
type = "counter"
346+
field = "backtrace"
347+
name = "exception_total"
348+
labels = {host = "#{event.host}"}
349+
"##,
350+
)
351+
.unwrap();
352+
353+
let mut log = Event::from("i am a log");
354+
log.as_mut_log()
355+
.insert_explicit("status".into(), "42".into());
356+
log.as_mut_log()
357+
.insert_explicit("backtrace".into(), "message".into());
358+
359+
let mut transform = LogToMetric::new(&config);
360+
361+
let mut output = Vec::new();
362+
transform.transform_into(&mut output, log);
363+
assert_eq!(2, output.len());
364+
assert_eq!(
365+
output.pop().unwrap().into_metric(),
366+
Metric::Counter {
367+
name: "exception_total".into(),
368+
val: 1,
369+
sampling: None
370+
}
371+
);
372+
assert_eq!(
373+
output.pop().unwrap().into_metric(),
374+
Metric::Counter {
375+
name: "status_total".into(),
376+
val: 1,
377+
sampling: None
378+
}
379+
);
380+
}
331381
}

0 commit comments

Comments
 (0)