-
Notifications
You must be signed in to change notification settings - Fork 94
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(metrics): Add received_at timestamp in bucket metadata #3488
Changes from 15 commits
f8ab10c
9d51e9f
85c7dcb
d07aa34
9966952
d341e53
5649429
b520960
adab977
8ee95c5
640a26d
0e61ac1
a7d50f0
7766480
20bd2eb
3a12653
35a69cc
4d51d41
f80c03f
072f96e
9519e31
8ebdd62
d0d1b1e
b83fa01
24fc67f
5c5680b
768eae6
f9bdf3f
cc1b985
22443d0
c4b0b13
0244cb6
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 |
---|---|---|
|
@@ -524,13 +524,17 @@ struct SentryMetrics { | |
/// | ||
/// Defaults to 5. | ||
pub meta_locations_max: usize, | ||
/// Whether to override the [`received_at`] field in the [`BucketMetadata`] with the current | ||
/// receive time of the instance. | ||
pub override_received_at_metadata: bool, | ||
} | ||
|
||
impl Default for SentryMetrics { | ||
fn default() -> Self { | ||
Self { | ||
meta_locations_expiry: 15 * 24 * 60 * 60, | ||
meta_locations_max: 5, | ||
override_received_at_metadata: false, | ||
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. By default we do not want to override the metadata to avoid unexpected behaviors due to the missing config param. |
||
} | ||
} | ||
} | ||
|
@@ -1947,6 +1951,11 @@ impl Config { | |
Duration::from_secs(self.values.sentry_metrics.meta_locations_expiry) | ||
} | ||
|
||
/// Returns whether we want to override the [`received_at`] field of [`BucketMetadata`]. | ||
pub fn metrics_override_received_at_metadata(&self) -> bool { | ||
self.values.sentry_metrics.override_received_at_metadata | ||
} | ||
|
||
/// Returns the default timeout for all upstream HTTP requests. | ||
pub fn http_timeout(&self) -> Duration { | ||
Duration::from_secs(self.values.http.timeout.into()) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
use std::cmp::min; | ||
use std::collections::{BTreeMap, BTreeSet}; | ||
use std::hash::Hash; | ||
use std::iter::FusedIterator; | ||
|
@@ -502,7 +503,7 @@ pub struct Bucket { | |
/// # Statsd Format | ||
/// | ||
/// In statsd, timestamps are part of the `|`-separated list following values. Timestamps start | ||
/// with with the literal character `'T'` followed by the UNIX timestamp. | ||
/// with the literal character `'T'` followed by the UNIX timestamp. | ||
/// | ||
/// The timestamp must be a positive integer in decimal notation representing the value of the | ||
/// UNIX timestamp. | ||
|
@@ -748,33 +749,55 @@ pub struct BucketMetadata { | |
/// For example: Merging two un-merged buckets will yield a total | ||
/// of `2` merges. | ||
pub merges: NonZeroU32, | ||
|
||
/// Received timestamp of the first metric in this bucket. | ||
/// | ||
/// This field should be set to the time in which the first metric of a specific bucket was | ||
/// received in the outermost internal Relay. | ||
pub received_at: Option<UnixTimestamp>, | ||
} | ||
|
||
impl BucketMetadata { | ||
/// Creates a fresh metadata instance. | ||
/// | ||
/// The new metadata is initialized with `1` merge. | ||
pub fn new() -> Self { | ||
/// The new metadata is initialized with `1` merge and a given [`received_at`] timestamp. | ||
pub fn new(received_at: UnixTimestamp) -> Self { | ||
Self { | ||
merges: NonZeroU32::MIN, | ||
received_at: Some(received_at), | ||
} | ||
} | ||
|
||
/// Whether the metadata does not contain more information than the default. | ||
pub fn is_default(&self) -> bool { | ||
let Self { merges } = self; | ||
*merges == NonZeroU32::MIN | ||
let Self { | ||
merges, | ||
received_at, | ||
} = self; | ||
|
||
*merges == NonZeroU32::MIN && received_at.is_none() | ||
} | ||
|
||
/// Merges another metadata object into the current one. | ||
pub fn merge(&mut self, other: Self) { | ||
self.merges = self.merges.saturating_add(other.merges.get()); | ||
self.received_at = match (self.received_at, other.received_at) { | ||
(Some(received_at), None) => Some(received_at), | ||
(None, Some(received_at)) => Some(received_at), | ||
(Some(left_received_at), Some(right_received_at)) => { | ||
Some(min(left_received_at, right_received_at)) | ||
} | ||
(None, None) => None, | ||
}; | ||
iambriccardo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
impl Default for BucketMetadata { | ||
fn default() -> Self { | ||
Self::new() | ||
Self { | ||
merges: NonZeroU32::MIN, | ||
received_at: None, | ||
} | ||
} | ||
} | ||
iambriccardo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
@@ -907,6 +930,9 @@ mod tests { | |
tags: {}, | ||
metadata: BucketMetadata { | ||
merges: 1, | ||
received_at: Some( | ||
UnixTimestamp(4711), | ||
), | ||
}, | ||
} | ||
"###); | ||
|
@@ -940,6 +966,9 @@ mod tests { | |
tags: {}, | ||
metadata: BucketMetadata { | ||
merges: 1, | ||
received_at: Some( | ||
UnixTimestamp(4711), | ||
), | ||
}, | ||
} | ||
"###); | ||
|
@@ -991,6 +1020,9 @@ mod tests { | |
tags: {}, | ||
metadata: BucketMetadata { | ||
merges: 1, | ||
received_at: Some( | ||
UnixTimestamp(4711), | ||
), | ||
}, | ||
} | ||
"###); | ||
|
@@ -1050,6 +1082,9 @@ mod tests { | |
tags: {}, | ||
metadata: BucketMetadata { | ||
merges: 1, | ||
received_at: Some( | ||
UnixTimestamp(4711), | ||
), | ||
}, | ||
} | ||
"###); | ||
|
@@ -1079,6 +1114,9 @@ mod tests { | |
tags: {}, | ||
metadata: BucketMetadata { | ||
merges: 1, | ||
received_at: Some( | ||
UnixTimestamp(4711), | ||
), | ||
}, | ||
} | ||
"###); | ||
|
@@ -1102,6 +1140,9 @@ mod tests { | |
tags: {}, | ||
metadata: BucketMetadata { | ||
merges: 1, | ||
received_at: Some( | ||
UnixTimestamp(4711), | ||
), | ||
}, | ||
} | ||
"###); | ||
|
@@ -1242,7 +1283,10 @@ mod tests { | |
.collect::<Result<Vec<_>, _>>() | ||
.unwrap(); | ||
|
||
let json_metrics: Vec<Bucket> = serde_json::from_str(json).unwrap(); | ||
let mut json_metrics: Vec<Bucket> = serde_json::from_str(json).unwrap(); | ||
for json_metric in &mut json_metrics { | ||
json_metric.metadata.received_at = Some(timestamp); | ||
} | ||
|
||
assert_eq!(statsd_metrics, json_metrics); | ||
} | ||
|
@@ -1254,7 +1298,8 @@ mod tests { | |
|
||
let timestamp = UnixTimestamp::from_secs(1615889449); | ||
let statsd_metric = Bucket::parse(text.as_bytes(), timestamp).unwrap(); | ||
let json_metric: Bucket = serde_json::from_str(json).unwrap(); | ||
let mut json_metric: Bucket = serde_json::from_str(json).unwrap(); | ||
json_metric.metadata.received_at = Some(timestamp); | ||
|
||
assert_eq!(statsd_metric, json_metric); | ||
} | ||
|
@@ -1275,7 +1320,9 @@ mod tests { | |
} | ||
]"#; | ||
|
||
let buckets = serde_json::from_str::<Vec<Bucket>>(json).unwrap(); | ||
let mut buckets = serde_json::from_str::<Vec<Bucket>>(json).unwrap(); | ||
buckets[0].metadata = BucketMetadata::new(UnixTimestamp::from_secs(1615889440)); | ||
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. You can just put this into the json, right? |
||
|
||
insta::assert_debug_snapshot!(buckets, @r###" | ||
[ | ||
Bucket { | ||
|
@@ -1297,6 +1344,9 @@ mod tests { | |
}, | ||
metadata: BucketMetadata { | ||
merges: 1, | ||
received_at: Some( | ||
UnixTimestamp(1615889440), | ||
), | ||
}, | ||
}, | ||
] | ||
|
@@ -1315,7 +1365,9 @@ mod tests { | |
} | ||
]"#; | ||
|
||
let buckets = serde_json::from_str::<Vec<Bucket>>(json).unwrap(); | ||
let mut buckets = serde_json::from_str::<Vec<Bucket>>(json).unwrap(); | ||
buckets[0].metadata = BucketMetadata::new(UnixTimestamp::from_secs(1615889440)); | ||
|
||
insta::assert_debug_snapshot!(buckets, @r###" | ||
[ | ||
Bucket { | ||
|
@@ -1330,6 +1382,9 @@ mod tests { | |
tags: {}, | ||
metadata: BucketMetadata { | ||
merges: 1, | ||
received_at: Some( | ||
UnixTimestamp(1615889440), | ||
), | ||
}, | ||
}, | ||
] | ||
|
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.
In production, we would like to set this option to true only for pop relays, since we want to have the
received_at
metadata field set to the outermost relay timestamp that receives a given bucket.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.
We already have that handling in the processor as
keep_metadata
for example inhandle_process_metrics
which should already do the right thing.