Repository navigation
Improve match logging #387
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
Changes from all commits
041c554
5343dad
8981bd7
ebb324c
6d9133f
9c64880
231bfe3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ pub use crate::secondary_validation::Validator; | |
| use crate::stats::GLOBAL_STATS; | ||
| use crate::tokio::TOKIO_RUNTIME; | ||
| use crate::{CreateScannerError, EncodeIndices, MatchAction, Path, ScannerError}; | ||
| use ::metrics::counter; | ||
| use ahash::AHashMap; | ||
| use futures::executor::block_on; | ||
| use serde::{Deserialize, Serialize}; | ||
|
|
@@ -107,6 +108,11 @@ pub struct RootRuleConfig<T> { | |
| precedence: Precedence, | ||
| #[serde(default)] | ||
| pub is_supporting_rule: bool, | ||
| /// Raw `"key:value"` strings, matching the format used by standard rule definitions | ||
| /// (e.g. `sensitive_data:travis_ci_access_token`). Not parsed into a map since no | ||
| /// producer of these values does so either; consumers parse the entries they need. | ||
| #[serde(default)] | ||
| pub tags: Vec<String>, | ||
| #[serde(flatten)] | ||
| pub inner: T, | ||
| } | ||
|
|
@@ -135,6 +141,7 @@ impl<T> RootRuleConfig<T> { | |
| suppressions: None, | ||
| precedence: Precedence::default(), | ||
| is_supporting_rule: false, | ||
| tags: Vec::new(), | ||
| inner, | ||
| } | ||
| } | ||
|
|
@@ -149,6 +156,7 @@ impl<T> RootRuleConfig<T> { | |
| suppressions: self.suppressions, | ||
| precedence: self.precedence, | ||
| is_supporting_rule: self.is_supporting_rule, | ||
| tags: self.tags, | ||
| inner: func(self.inner), | ||
| } | ||
| } | ||
|
|
@@ -186,6 +194,11 @@ impl<T> RootRuleConfig<T> { | |
| self | ||
| } | ||
|
|
||
| pub fn tags(mut self, tags: Vec<String>) -> Self { | ||
| self.tags = tags; | ||
| self | ||
| } | ||
|
|
||
| pub fn get_suppressions(&self) -> Option<&Suppressions> { | ||
| self.suppressions.as_ref() | ||
| } | ||
|
|
@@ -213,6 +226,10 @@ pub struct RootCompiledRule { | |
| pub suppressions: Option<CompiledSuppressions>, | ||
| pub precedence: Precedence, | ||
| pub is_supporting_rule: bool, | ||
| /// Precomputed `"{sensitive_data_category}/{sensitive_data}"` tag value derived from | ||
| /// the rule's `tags`, used to tag `scanning.match_count`. `None` when the rule has no | ||
| /// `sensitive_data` tag. | ||
| pub sds_rule_name: Option<String>, | ||
|
Comment on lines
+229
to
+232
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could it be kept generic with "labels" similarly to how these telemetry tags are attached to scanner? |
||
| } | ||
|
|
||
| impl RootCompiledRule { | ||
|
|
@@ -589,10 +606,26 @@ impl Scanner { | |
| ) { | ||
| // Add number of scanned events | ||
| self.metrics.num_scanned_events.increment(1); | ||
| // Add number of matches | ||
| self.metrics | ||
| .match_count | ||
| .increment(output_rule_matches.len() as u64); | ||
| // Add number of matches, tagged per rule so `sds_rule_name` can break down match counts | ||
| // by the rule's sensitive_data_category/sensitive_data tags. | ||
| let mut match_counts_by_rule: AHashMap<usize, u64> = AHashMap::new(); | ||
| for rule_match in output_rule_matches { | ||
| *match_counts_by_rule | ||
| .entry(rule_match.rule_index) | ||
| .or_default() += 1; | ||
| } | ||
| for (rule_index, count) in match_counts_by_rule { | ||
| match self.rules[rule_index].sds_rule_name.as_deref() { | ||
| Some(sds_rule_name) => { | ||
| let labels = self.labels.clone_with_labels(Labels::new(&[( | ||
| "sds_rule_name", | ||
| sds_rule_name.to_string(), | ||
| )])); | ||
| counter!("scanning.match_count", labels).increment(count); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The cardinality of this metric is already high and it will increase even more with this new tag. To avoid cardinality issues, these additional labels must be enabled as opt-in when required, for instance for correctness validation. If |
||
| } | ||
| None => self.metrics.match_count.increment(count), | ||
| } | ||
| } | ||
|
|
||
| if let Some(io_duration) = io_duration { | ||
| let total_duration = start.elapsed(); | ||
|
|
@@ -1137,6 +1170,7 @@ impl ScannerBuilder<'_> { | |
| suppressions: compiled_suppressions, | ||
| precedence: config.precedence, | ||
| is_supporting_rule: config.is_supporting_rule, | ||
| sds_rule_name: metrics::compute_sds_rule_name(&config.tags), | ||
| }) | ||
| }) | ||
| .collect::<Result<Vec<RootCompiledRule>, CreateScannerError>>()?; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: there is no concept of standard rules here, and in general the concept of
sensitive_datatag is not associated to standard rule but is generic for all kind of rules.