Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 6 additions & 1 deletion src/datadog/filter/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ pub trait Filter<V: Debug + Send + Sync + Clone + 'static>: DynClone {
/// # Errors
///
/// Will return `Err` if the query contains an invalid path.
fn equals(&self, field: Field, to_match: &str) -> Result<Box<dyn Matcher<V>>, PathParseError>;
fn equals(
&self,
field: Field,
to_match: &str,
is_phrase: bool,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which implementation needs this bool?
Also, please avoid passing flags if possible e.g. we can introduce a new phrase_equals.

Copy link
Author

@PSeitz PSeitz Mar 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for matching on default fields (typically message) in datadog. The matching behavior for phrases is different than non-phrased. In a phrase the tokens need to be in the same order. E.g.
Hello nice world => "Hello world" no match
Hello nice world => Hello world matches

Btw. there is an alternative solution where the tokenizer would emit multiple tokens.
Hello world would expand to the equivalent of_default_:Hello AND _default_:World.
"Hello world" would expand to the equivalent of_default_:"Hello World"

I considered adding a new method phrase_equals, but wasn't sure, since this behavior applies only to default fields.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated to introduce phrase fn callback

) -> Result<Box<dyn Matcher<V>>, PathParseError>;

/// Determine whether a value starts with a prefix.
///
Expand Down
14 changes: 11 additions & 3 deletions src/datadog/filter/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,23 @@ where

Ok(all(matchers?))
}
QueryNode::AttributeTerm { attr, value }
| QueryNode::QuotedAttribute {
QueryNode::AttributeTerm { attr, value } => {
let matchers: Result<Vec<_>, _> = filter
.build_fields(attr)
.into_iter()
.map(|field| filter.equals(field, value, false))
.collect();

Ok(any(matchers?))
}
QueryNode::QuotedAttribute {
attr,
phrase: value,
} => {
let matchers: Result<Vec<_>, _> = filter
.build_fields(attr)
.into_iter()
.map(|field| filter.equals(field, value))
.map(|field| filter.equals(field, value, true))
.collect();

Ok(any(matchers?))
Expand Down
1 change: 1 addition & 0 deletions src/stdlib/match_datadog_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ impl Filter<Value> for VrlFilter {
&self,
field: Field,
to_match: &str,
_is_phrase: bool,
) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
let buf = lookup_field(&field)?;

Expand Down