Skip to content
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(spans): extract cache size and cache hit in indexed spans #3367

Merged
merged 9 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## Unreleased

Check failure on line 3 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Changelogs

Missing changelog entry.

Please consider adding a changelog entry for the next release.

**Features**:

Expand All @@ -13,6 +13,7 @@

**Internal**:

- Extract `cache.item_size` and `cache.hit` data into span indexed ([#3367]https://github.com/getsentry/relay/pull/3367)
- Enable `db.redis` span metrics extraction. ([#3283](https://github.com/getsentry/relay/pull/3283))
- Add data categories for continuous profiling. ([#3284](https://github.com/getsentry/relay/pull/3284), [#3303](https://github.com/getsentry/relay/pull/3303))
- Apply rate limits to span metrics. ([#3255](https://github.com/getsentry/relay/pull/3255))
Expand Down
106 changes: 106 additions & 0 deletions relay-event-normalization/src/normalize/span/tag_extraction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ pub enum SpanTagKey {
/// The start type of the application when the span occurred.
AppStartType,
ReplayId,
CacheHit,
CacheItemSize,
}

impl SpanTagKey {
Expand Down Expand Up @@ -104,6 +106,7 @@ impl SpanTagKey {
SpanTagKey::TimeToInitialDisplay => "ttid",
SpanTagKey::FileExtension => "file_extension",
SpanTagKey::MainThread => "main_thread",
SpanTagKey::CacheHit => "cache.hit",
SpanTagKey::OsName => "os.name",
SpanTagKey::AppStartType => "app_start_type",
SpanTagKey::ReplayId => "replay_id",
Expand Down Expand Up @@ -406,6 +409,13 @@ pub fn extract_tags(
}
}

if span_op.starts_with("cache.") {
if let Some(Value::Bool(cache_hit)) = span.data.value().and_then(|data| data.cache_hit.value()) {
let tag_value = if cache_hit { "true" } else { "false" };
span_tags.insert(SpanTagKey::CacheHit, tag_value.to_owned());
}
}

if let Some(scrubbed_desc) = scrubbed_description {
// Truncating the span description's tag value is, for now,
// a temporary solution to not get large descriptions dropped. The
Expand Down Expand Up @@ -559,6 +569,27 @@ pub fn extract_measurements(span: &mut Span) {
return;
};

if span_op.starts_with("cache.") {
if let Some(data) = span.data.value() {
if let Some(value) = match &data.cache_item_size.value() {
Some(Value::F64(f)) => Some(*f),
Some(Value::I64(i)) => Some(*i as f64),
Some(Value::U64(u)) => Some(*u as f64),
_ => None,
} {
let measurements = span.measurements.get_or_insert_with(Default::default);
measurements.insert(
"cache.item_size".to_owned(),
Measurement {
value: value.into(),
unit: MetricUnit::Information(InformationUnit::Byte).into(),
}
.into(),
);
}
}
}

if span_op.starts_with("resource.") {
if let Some(data) = span.data.value() {
for (field, key) in [
Expand Down Expand Up @@ -1283,6 +1314,81 @@ LIMIT 1
assert!(!tags_3.contains_key("raw_domain"));
}

#[test]
fn test_cache_extraction() {
let json = r#"
{
"spans": [
{
"timestamp": 1694732408.3145,
"start_timestamp": 1694732407.8367,
"exclusive_time": 477.800131,
"description": "get my_key",
"op": "cache.get_item",
"span_id": "97c0ef9770a02f9d",
"parent_span_id": "9756d8d7b2b364ff",
"trace_id": "77aeb1c16bb544a4a39b8d42944947a3",
"data": {
"cache.hit": true,
"cache.item_size": 8,
"thread.id": "6286962688",
"thread.name": "Thread-4 (process_request_thread)"

},
"hash": "e2fae740cccd3781"
},
{
"timestamp": 1694732409.3145,
"start_timestamp": 1694732408.8367,
"exclusive_time": 477.800131,
"description": "get my_key",
"op": "cache.get_item",
"span_id": "97c0ef9770a02f9d",
"parent_span_id": "9756d8d7b2b364ff",
"trace_id": "77aeb1c16bb544a4a39b8d42944947a3",
"data": {
"cache.hit": false,
"cache.item_size": 8,
"thread.id": "6286962688",
"thread.name": "Thread-4 (process_request_thread)"

},
"hash": "e2fae740cccd3781"
}
]
}
"#;

let mut event = Annotated::<Event>::from_json(json)
.unwrap()
.into_value()
.unwrap();

extract_span_tags_from_event(&mut event, 200);

let span_1 = &event.spans.value().unwrap()[0];
let span_2 = &event.spans.value().unwrap()[1];

let tags_1 = get_value!(span_1.sentry_tags).unwrap();
let tags_2 = get_value!(span_2.sentry_tags).unwrap();
let measurements_1 = span_1.value().unwrap().measurements.value().unwrap();

assert_eq!(tags_1.get("cache.hit").unwrap().as_str(), Some("true"));
assert_eq!(tags_2.get("cache.hit").unwrap().as_str(), Some("false"));
assert_debug_snapshot!(measurements_1, @r###"
Measurements(
{
"cache.item_size": Measurement {
value: 8.0,
unit: Information(
Byte,
),
},
},
)
"###);
}

#[test]
fn test_mobile_specific_tags() {
let json = r#"
Expand Down
12 changes: 11 additions & 1 deletion relay-event-schema/src/protocol/span.rs
iker-barriocanal marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,18 @@ pub struct SpanData {
#[metastructure(field = "resource.render_blocking_status")]
pub resource_render_blocking_status: Annotated<Value>,

/// Name of the database host.
/// Name of the web server host.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was just an incorrect comment, I updated to reflect the value better

#[metastructure(field = "server.address")]
pub server_address: Annotated<Value>,

/// Whether cache was hit or miss on a read operation.
#[metastructure(field = "cache.hit")]
pub cache_hit: Annotated<Value>,

/// The size of the cache item.
#[metastructure(field = "cache.item_size")]
pub cache_item_size: Annotated<Value>,

/// The status HTTP response.
#[metastructure(field = "http.response.status_code", legacy_alias = "status_code")]
pub http_response_status_code: Annotated<Value>,
Expand Down Expand Up @@ -512,6 +520,8 @@ mod tests {
http_response_transfer_size: ~,
resource_render_blocking_status: ~,
server_address: ~,
cache_hit: ~,
cache_item_size: ~,
http_response_status_code: ~,
ai_input_messages: ~,
ai_completion_tokens_used: ~,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ expression: "(&event.value().unwrap().spans, metrics)"
http_response_transfer_size: ~,
resource_render_blocking_status: ~,
server_address: ~,
cache_hit: ~,
cache_item_size: ~,
http_response_status_code: ~,
ai_input_messages: ~,
ai_completion_tokens_used: ~,
Expand Down Expand Up @@ -403,6 +405,8 @@ expression: "(&event.value().unwrap().spans, metrics)"
http_response_transfer_size: ~,
resource_render_blocking_status: ~,
server_address: ~,
cache_hit: ~,
cache_item_size: ~,
http_response_status_code: ~,
ai_input_messages: ~,
ai_completion_tokens_used: ~,
Expand Down
Loading