relay_event_normalization/
timestamp.rsuse relay_event_schema::processor::{
ProcessValue, ProcessingAction, ProcessingResult, ProcessingState, Processor,
};
use relay_event_schema::protocol::{Breadcrumb, Event, Span};
use relay_protocol::{Error, Meta};
pub struct TimestampProcessor;
impl Processor for TimestampProcessor {
fn process_event(
&mut self,
event: &mut Event,
_: &mut Meta,
state: &ProcessingState,
) -> ProcessingResult {
if let Some(end_timestamp) = event.timestamp.value() {
if end_timestamp.into_inner().timestamp_millis() < 0 {
return Err(ProcessingAction::InvalidTransaction(
"timestamp is too stale",
));
}
}
if let Some(start_timestamp) = event.start_timestamp.value() {
if start_timestamp.into_inner().timestamp_millis() < 0 {
return Err(ProcessingAction::InvalidTransaction(
"timestamp is too stale",
));
}
}
event.process_child_values(self, state)?;
Ok(())
}
fn process_span(
&mut self,
span: &mut Span,
meta: &mut Meta,
_: &ProcessingState<'_>,
) -> ProcessingResult {
if let Some(start_timestamp) = span.start_timestamp.value() {
if start_timestamp.into_inner().timestamp_millis() < 0 {
meta.add_error(Error::invalid(format!(
"start_timestamp is too stale: {}",
start_timestamp
)));
return Err(ProcessingAction::DeleteValueHard);
}
}
if let Some(end_timestamp) = span.timestamp.value() {
if end_timestamp.into_inner().timestamp_millis() < 0 {
meta.add_error(Error::invalid(format!(
"timestamp is too stale: {}",
end_timestamp
)));
return Err(ProcessingAction::DeleteValueHard);
}
}
Ok(())
}
fn process_breadcrumb(
&mut self,
breadcrumb: &mut Breadcrumb,
meta: &mut Meta,
_: &ProcessingState<'_>,
) -> ProcessingResult where {
if let Some(timestamp) = breadcrumb.timestamp.value() {
if timestamp.into_inner().timestamp_millis() < 0 {
meta.add_error(Error::invalid(format!(
"timestamp is too stale: {}",
timestamp
)));
return Err(ProcessingAction::DeleteValueHard);
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use relay_event_schema::processor::{process_value, ProcessingState};
use relay_event_schema::protocol::{Breadcrumb, Event, Span};
use relay_protocol::{assert_annotated_snapshot, get_value, Annotated};
use crate::timestamp::TimestampProcessor;
#[test]
fn test_accept_recent_errors() {
let json = r#"{
"event_id": "52df9022835246eeb317dbd739ccd059",
"timestamp": 1
}"#;
let mut error = Annotated::<Event>::from_json(json).unwrap();
assert!(
process_value(&mut error, &mut TimestampProcessor, ProcessingState::root()).is_ok()
);
assert_eq!(get_value!(error.timestamp!).into_inner().timestamp(), 1);
}
#[test]
fn test_reject_stale_errors() {
let json = r#"{
"event_id": "52df9022835246eeb317dbd739ccd059",
"timestamp": -1
}"#;
let mut error = Annotated::<Event>::from_json(json).unwrap();
assert_eq!(
process_value(&mut error, &mut TimestampProcessor, ProcessingState::root())
.unwrap_err()
.to_string(),
"invalid transaction event: timestamp is too stale"
);
}
#[test]
fn test_accept_recent_transactions() {
let json = r#"{
"event_id": "52df9022835246eeb317dbd739ccd059",
"start_timestamp": 1,
"timestamp": 2
}"#;
let mut transaction = Annotated::<Event>::from_json(json).unwrap();
assert!(process_value(
&mut transaction,
&mut TimestampProcessor,
ProcessingState::root()
)
.is_ok());
}
#[test]
fn test_reject_stale_transactions() {
let json = r#"{
"event_id": "52df9022835246eeb317dbd739ccd059",
"start_timestamp": -2,
"timestamp": -1
}"#;
let mut transaction = Annotated::<Event>::from_json(json).unwrap();
assert_eq!(
process_value(
&mut transaction,
&mut TimestampProcessor,
ProcessingState::root()
)
.unwrap_err()
.to_string(),
"invalid transaction event: timestamp is too stale"
);
}
#[test]
fn test_reject_long_running_transactions() {
let json = r#"{
"event_id": "52df9022835246eeb317dbd739ccd059",
"start_timestamp": -1,
"timestamp": 1
}"#;
let mut transaction = Annotated::<Event>::from_json(json).unwrap();
assert_eq!(
process_value(
&mut transaction,
&mut TimestampProcessor,
ProcessingState::root()
)
.unwrap_err()
.to_string(),
"invalid transaction event: timestamp is too stale"
);
}
#[test]
fn test_accept_recent_span() {
let json = r#"{
"span_id": "52df9022835246eeb317dbd739ccd050",
"start_timestamp": 1,
"timestamp": 2
}"#;
let mut span = Annotated::<Span>::from_json(json).unwrap();
assert!(process_value(&mut span, &mut TimestampProcessor, ProcessingState::root()).is_ok());
assert_eq!(
get_value!(span.start_timestamp!).into_inner().timestamp(),
1
);
assert_eq!(get_value!(span.timestamp!).into_inner().timestamp(), 2);
}
#[test]
fn test_reject_stale_span() {
let json = r#"{
"span_id": "52df9022835246eeb317dbd739ccd050",
"start_timestamp": -2,
"timestamp": -1
}"#;
let mut span = Annotated::<Span>::from_json(json).unwrap();
assert!(process_value(&mut span, &mut TimestampProcessor, ProcessingState::root()).is_ok());
assert_annotated_snapshot!(&span, @r###"
{
"_meta": {
"": {
"err": [
[
"invalid_data",
{
"reason": "start_timestamp is too stale: 1969-12-31 23:59:58 UTC"
}
]
]
}
}
}
"###);
}
#[test]
fn test_reject_long_running_span() {
let json = r#"{
"span_id": "52df9022835246eeb317dbd739ccd050",
"start_timestamp": -1,
"timestamp": 1
}"#;
let mut span = Annotated::<Span>::from_json(json).unwrap();
assert!(process_value(&mut span, &mut TimestampProcessor, ProcessingState::root()).is_ok());
assert_annotated_snapshot!(&span, @r###"
{
"_meta": {
"": {
"err": [
[
"invalid_data",
{
"reason": "start_timestamp is too stale: 1969-12-31 23:59:59 UTC"
}
]
]
}
}
}
"###);
}
#[test]
fn test_accept_recent_breadcrumb() {
let json = r#"{
"timestamp": 1
}"#;
let mut breadcrumb = Annotated::<Breadcrumb>::from_json(json).unwrap();
assert!(process_value(
&mut breadcrumb,
&mut TimestampProcessor,
ProcessingState::root()
)
.is_ok());
assert_eq!(
get_value!(breadcrumb.timestamp!).into_inner().timestamp(),
1
);
}
#[test]
fn test_reject_stale_breadcrumb() {
let json = r#"{
"timestamp": -1
}"#;
let mut breadcrumb = Annotated::<Breadcrumb>::from_json(json).unwrap();
assert!(process_value(
&mut breadcrumb,
&mut TimestampProcessor,
ProcessingState::root()
)
.is_ok());
assert_annotated_snapshot!(&breadcrumb, @r###"
{
"_meta": {
"": {
"err": [
[
"invalid_data",
{
"reason": "timestamp is too stale: 1969-12-31 23:59:59 UTC"
}
]
]
}
}
}
"###);
}
}