Skip to content
Merged
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
8 changes: 5 additions & 3 deletions .meta/_partials/_conditions.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
[<%= namespace %>.type]
type = "string"
required = true
examples = ["check_fields"]
examples = ["check_fields", "is_log", "is_metric"]
common = true
description = """\
The type of the condition to execute. Currently only the `check_fields` type is \
available.\
The type of the condition to execute.\
"""

[<%= namespace %>."`<field_name>`.eq"]
Expand All @@ -14,6 +13,7 @@ examples = [
{ "message.eq" = "this is the content to match against" }
]
common = true
relevant_when = {type = "check_fields"}
description = """\
Check whether a fields contents exactly matches the value specified.\
"""
Expand All @@ -24,6 +24,7 @@ examples = [
{ "method.neq" = "POST" }
]
common = true
relevant_when = {type = "check_fields"}
description = """\
Check whether a fields contents does not match the value specified.\
"""
Expand All @@ -34,6 +35,7 @@ examples = [
{ "host.exists" = true }
]
common = true
relevant_when = {type = "check_fields"}
description = """\
Check whether a field exists or does not exist, depending on the provided value\
being `true` or `false` respectively.\
Expand Down
8 changes: 6 additions & 2 deletions config/vector.spec.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1823,18 +1823,20 @@ end

[transforms.swimlanes.lanes]
[transforms.swimlanes.lanes.`<swimlane_id>`]
# The type of the condition to execute. Currently only the `check_fields` type
# is available.
# The type of the condition to execute.
#
# * required
# * type: string
type = "check_fields"
type = "is_log"
type = "is_metric"

# Check whether a fields contents exactly matches the value specified.
#
# * optional
# * no default
# * type: string
# * relevant when type = "check_fields"
"message.eq" = "this is the content to match against"

# Check whether a field exists or does not exist, depending on the provided
Expand All @@ -1843,13 +1845,15 @@ end
# * optional
# * no default
# * type: bool
# * relevant when type = "check_fields"
"host.exists" = true

# Check whether a fields contents does not match the value specified.
#
# * optional
# * no default
# * type: string
# * relevant when type = "check_fields"
"method.neq" = "POST"

# Accepts and outputs `log` events allowing you to tokenize a field's value by splitting on white space, ignoring special wrapping characters, and zip the tokens into ordered field names.
Expand Down
71 changes: 71 additions & 0 deletions src/conditions/is_log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use serde::{Deserialize, Serialize};

use crate::{
conditions::{Condition, ConditionConfig, ConditionDescription},
Event,
};

//------------------------------------------------------------------------------

#[derive(Deserialize, Serialize, Debug, Default, Clone)]
pub struct IsLogConfig {}

inventory::submit! {
ConditionDescription::new::<IsLogConfig>("is_log")
}

#[typetag::serde(name = "is_log")]
impl ConditionConfig for IsLogConfig {
fn build(&self) -> crate::Result<Box<dyn Condition>> {
Ok(Box::new(IsLog {}))
}
}

//------------------------------------------------------------------------------

pub struct IsLog {}

impl Condition for IsLog {
fn check(&self, e: &Event) -> bool {
match e {
Event::Log(_) => true,
_ => false,
}
}

fn check_with_context(&self, e: &Event) -> Result<(), String> {
if self.check(e) {
Ok(())
} else {
Err("event is not a log type".to_string())
}
}
}

//------------------------------------------------------------------------------

#[cfg(test)]
mod test {
use super::*;
use crate::{
event::metric::{Metric, MetricKind, MetricValue},
Event,
};

#[test]
fn is_log_basic() {
let cond = IsLogConfig {}.build().unwrap();

assert_eq!(cond.check(&Event::from("just a log")), true);
assert_eq!(
cond.check(&Event::from(Metric {
name: "test metric".to_string(),
timestamp: None,
tags: None,
kind: MetricKind::Incremental,
value: MetricValue::Counter { value: 1.0 },
})),
false
);
}
}
71 changes: 71 additions & 0 deletions src/conditions/is_metric.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use serde::{Deserialize, Serialize};

use crate::{
conditions::{Condition, ConditionConfig, ConditionDescription},
Event,
};

//------------------------------------------------------------------------------

#[derive(Deserialize, Serialize, Debug, Default, Clone)]
pub struct IsMetricConfig {}

inventory::submit! {
ConditionDescription::new::<IsMetricConfig>("is_metric")
}

#[typetag::serde(name = "is_metric")]
impl ConditionConfig for IsMetricConfig {
fn build(&self) -> crate::Result<Box<dyn Condition>> {
Ok(Box::new(IsMetric {}))
}
}

//------------------------------------------------------------------------------

pub struct IsMetric {}

impl Condition for IsMetric {
fn check(&self, e: &Event) -> bool {
match e {
Event::Metric(_) => true,
_ => false,
}
}

fn check_with_context(&self, e: &Event) -> Result<(), String> {
if self.check(e) {
Ok(())
} else {
Err("event is not a metric type".to_string())
}
}
}

//------------------------------------------------------------------------------

#[cfg(test)]
mod test {
use super::*;
use crate::{
event::metric::{Metric, MetricKind, MetricValue},
Event,
};

#[test]
fn is_metric_basic() {
let cond = IsMetricConfig {}.build().unwrap();

assert_eq!(cond.check(&Event::from("just a log")), false);
assert_eq!(
cond.check(&Event::from(Metric {
name: "test metric".to_string(),
timestamp: None,
tags: None,
kind: MetricKind::Incremental,
value: MetricValue::Counter { value: 1.0 },
})),
true
);
}
}
2 changes: 2 additions & 0 deletions src/conditions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use crate::Event;
use inventory;

pub mod check_fields;
pub mod is_log;
pub mod is_metric;

pub use check_fields::CheckFieldsConfig;

Expand Down
12 changes: 12 additions & 0 deletions tests/behavior/transforms/swimlanes.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"message.eq" = "test swimlane 1"
[transforms.foo.lanes.second]
"message.eq" = "test swimlane 2"
[transforms.foo.lanes.third]
type = "is_log"

[transforms.bar]
inputs = ["foo.first"]
Expand All @@ -31,6 +33,11 @@
"message.equals" = "test swimlane 1"
"new_field.equals" = "new field added"

[[tests.outputs]]
extract_from = "foo.third"
[[tests.outputs.conditions]]
"message.equals" = "test swimlane 1"

[[tests]]
name = "swimlanes test 2"
no_outputs_from = [ "foo.first", "bar" ]
Expand All @@ -43,3 +50,8 @@
extract_from = "foo.second"
[[tests.outputs.conditions]]
"message.equals" = "test swimlane 2"

[[tests.outputs]]
extract_from = "foo.third"
[[tests.outputs.conditions]]
"message.equals" = "test swimlane 2"
10 changes: 5 additions & 5 deletions website/docs/reference/tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ A table that defines a collection of conditions to check against the output of a
groups={[]}
name={"`<field_name>`.eq"}
path={"outputs.conditions"}
relevantWhen={null}
relevantWhen={{"type":"check_fields"}}
required={false}
templateable={false}
type={"string"}
Expand All @@ -660,7 +660,7 @@ Check whether a fields contents exactly matches the value specified.
groups={[]}
name={"`<field_name>`.exists"}
path={"outputs.conditions"}
relevantWhen={null}
relevantWhen={{"type":"check_fields"}}
required={false}
templateable={false}
type={"bool"}
Expand All @@ -683,7 +683,7 @@ Check whether a field exists or does not exist, depending on the provided valueb
groups={[]}
name={"`<field_name>`.neq"}
path={"outputs.conditions"}
relevantWhen={null}
relevantWhen={{"type":"check_fields"}}
required={false}
templateable={false}
type={"string"}
Expand All @@ -702,7 +702,7 @@ Check whether a fields contents does not match the value specified.
common={true}
defaultValue={null}
enumValues={null}
examples={["check_fields"]}
examples={["check_fields","is_log","is_metric"]}
groups={[]}
name={"type"}
path={"outputs.conditions"}
Expand All @@ -715,7 +715,7 @@ Check whether a fields contents does not match the value specified.

##### type

The type of the condition to execute. Currently only the `check_fields` type is available.
The type of the condition to execute.


</Field>
Expand Down
10 changes: 5 additions & 5 deletions website/docs/reference/transforms/swimlanes.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ The identifier of a swimlane.
groups={[]}
name={"`<field_name>`.eq"}
path={"lanes.`<swimlane_id>`"}
relevantWhen={null}
relevantWhen={{"type":"check_fields"}}
required={false}
templateable={false}
type={"string"}
Expand All @@ -128,7 +128,7 @@ Check whether a fields contents exactly matches the value specified.
groups={[]}
name={"`<field_name>`.exists"}
path={"lanes.`<swimlane_id>`"}
relevantWhen={null}
relevantWhen={{"type":"check_fields"}}
required={false}
templateable={false}
type={"bool"}
Expand All @@ -151,7 +151,7 @@ Check whether a field exists or does not exist, depending on the provided valueb
groups={[]}
name={"`<field_name>`.neq"}
path={"lanes.`<swimlane_id>`"}
relevantWhen={null}
relevantWhen={{"type":"check_fields"}}
required={false}
templateable={false}
type={"string"}
Expand All @@ -170,7 +170,7 @@ Check whether a fields contents does not match the value specified.
common={true}
defaultValue={null}
enumValues={null}
examples={["check_fields"]}
examples={["check_fields","is_log","is_metric"]}
groups={[]}
name={"type"}
path={"lanes.`<swimlane_id>`"}
Expand All @@ -183,7 +183,7 @@ Check whether a fields contents does not match the value specified.

##### type

The type of the condition to execute. Currently only the `check_fields` type is available.
The type of the condition to execute.


</Field>
Expand Down