Skip to content

Commit 0b163b1

Browse files
fix: wrong-resource-attributes-on-javasqs-span (#56)
1 parent a1bf6a8 commit 0b163b1

3 files changed

Lines changed: 145 additions & 21 deletions

File tree

src/otlp/metrics_creation.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ pub fn create_metrics(invocation_id: &str) -> Option<StoredMetric> {
174174
return None;
175175
}
176176

177+
let metric_names: Vec<String> = metrics.iter().map(|m| m.name.clone()).collect();
178+
177179
let scope_metrics = ScopeMetrics {
178180
scope: Some(InstrumentationScope {
179181
name: "dash0.lambda-extension".to_string(),
@@ -214,6 +216,13 @@ pub fn create_metrics(invocation_id: &str) -> Option<StoredMetric> {
214216
header::HeaderValue::from_static("application/x-protobuf"),
215217
);
216218

219+
tracing::info!(
220+
"[{}] Created supplementary metrics for invocation {}: {}",
221+
crate::log_prefix(),
222+
invocation_id,
223+
metric_names.join(", "),
224+
);
225+
217226
Some(StoredMetric {
218227
method: hyper::Method::POST,
219228
path_and_query: "/v1/metrics".to_string(),
@@ -224,13 +233,6 @@ pub fn create_metrics(invocation_id: &str) -> Option<StoredMetric> {
224233

225234
pub fn create_supplementary_metrics(invocation_id: &str) {
226235
if let Some(metric) = create_metrics(invocation_id) {
227-
tracing::info!(
228-
"[{}] Created supplementary metrics for invocation {}: path={} body_len={}",
229-
crate::log_prefix(),
230-
invocation_id,
231-
metric.path_and_query,
232-
metric.body.len()
233-
);
234236
store_metric(metric);
235237
}
236238
}

src/otlp/span_mutations.rs

Lines changed: 129 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -264,21 +264,26 @@ fn extract_span_links(event_payload: &str) -> Vec<Link> {
264264

265265
fn add_resource_attributes(span: &mut Span) {
266266
use crate::otlp::attributes::*;
267-
if let Some(account_id) = crate::state::global::get_account_id() {
268-
span.attributes.push(KeyValue {
269-
key: CLOUD_ACCOUNT_ID.to_string(),
270-
value: Some(AnyValue {
271-
value: Some(Value::StringValue(account_id)),
272-
}),
273-
});
267+
let has_attribute = |span: &Span, key: &str| span.attributes.iter().any(|kv| kv.key == key);
268+
if !has_attribute(span, CLOUD_ACCOUNT_ID) {
269+
if let Some(account_id) = crate::state::global::get_account_id() {
270+
span.attributes.push(KeyValue {
271+
key: CLOUD_ACCOUNT_ID.to_string(),
272+
value: Some(AnyValue {
273+
value: Some(Value::StringValue(account_id)),
274+
}),
275+
});
276+
}
274277
}
275-
if let Some(function_arn) = crate::state::global::get_function_arn() {
276-
span.attributes.push(KeyValue {
277-
key: CLOUD_RESOURCE_ID.to_string(),
278-
value: Some(AnyValue {
279-
value: Some(Value::StringValue(function_arn)),
280-
}),
281-
});
278+
if !has_attribute(span, CLOUD_RESOURCE_ID) {
279+
if let Some(function_arn) = crate::state::global::get_function_arn() {
280+
span.attributes.push(KeyValue {
281+
key: CLOUD_RESOURCE_ID.to_string(),
282+
value: Some(AnyValue {
283+
value: Some(Value::StringValue(function_arn)),
284+
}),
285+
});
286+
}
282287
}
283288
}
284289

@@ -641,6 +646,7 @@ pub fn process_trace_request(
641646
}
642647

643648
for span in &mut scope_span.spans {
649+
add_resource_attributes(span);
644650
let invocation_id = match extract_invocation_id(span) {
645651
Some(id) => id,
646652
None => continue,
@@ -995,6 +1001,115 @@ mod tests {
9951001
);
9961002
}
9971003

1004+
#[test]
1005+
#[serial]
1006+
fn add_resource_attributes_does_not_duplicate_existing_keys() {
1007+
use crate::otlp::attributes::{CLOUD_ACCOUNT_ID, CLOUD_RESOURCE_ID};
1008+
1009+
crate::state::global::reset_for_tests();
1010+
crate::state::global::store_account_id("999988887777");
1011+
crate::state::global::store_function_arn(
1012+
"arn:aws:lambda:us-east-1:999988887777:function:from-global",
1013+
);
1014+
1015+
let mut span = Span {
1016+
attributes: vec![
1017+
KeyValue {
1018+
key: CLOUD_ACCOUNT_ID.to_string(),
1019+
value: Some(AnyValue {
1020+
value: Some(Value::StringValue("preexisting-account".to_string())),
1021+
}),
1022+
},
1023+
KeyValue {
1024+
key: CLOUD_RESOURCE_ID.to_string(),
1025+
value: Some(AnyValue {
1026+
value: Some(Value::StringValue("preexisting-arn".to_string())),
1027+
}),
1028+
},
1029+
],
1030+
..Default::default()
1031+
};
1032+
1033+
super::add_resource_attributes(&mut span);
1034+
1035+
let account_keys: Vec<&KeyValue> = span
1036+
.attributes
1037+
.iter()
1038+
.filter(|kv| kv.key == CLOUD_ACCOUNT_ID)
1039+
.collect();
1040+
assert_eq!(
1041+
account_keys.len(),
1042+
1,
1043+
"cloud.account.id should not duplicate"
1044+
);
1045+
assert_eq!(
1046+
account_keys[0]
1047+
.value
1048+
.as_ref()
1049+
.and_then(|v| v.value.as_ref()),
1050+
Some(&Value::StringValue("preexisting-account".to_string())),
1051+
"preexisting cloud.account.id should be preserved"
1052+
);
1053+
1054+
let resource_keys: Vec<&KeyValue> = span
1055+
.attributes
1056+
.iter()
1057+
.filter(|kv| kv.key == CLOUD_RESOURCE_ID)
1058+
.collect();
1059+
assert_eq!(
1060+
resource_keys.len(),
1061+
1,
1062+
"cloud.resource_id should not duplicate"
1063+
);
1064+
assert_eq!(
1065+
resource_keys[0]
1066+
.value
1067+
.as_ref()
1068+
.and_then(|v| v.value.as_ref()),
1069+
Some(&Value::StringValue("preexisting-arn".to_string())),
1070+
"preexisting cloud.resource_id should be preserved"
1071+
);
1072+
1073+
crate::state::global::reset_for_tests();
1074+
}
1075+
1076+
#[test]
1077+
#[serial]
1078+
fn add_resource_attributes_adds_when_missing() {
1079+
use crate::otlp::attributes::{CLOUD_ACCOUNT_ID, CLOUD_RESOURCE_ID};
1080+
1081+
crate::state::global::reset_for_tests();
1082+
crate::state::global::store_account_id("111122223333");
1083+
crate::state::global::store_function_arn(
1084+
"arn:aws:lambda:us-east-1:111122223333:function:added",
1085+
);
1086+
1087+
let mut span = Span::default();
1088+
super::add_resource_attributes(&mut span);
1089+
1090+
let account = find_attribute(&span, CLOUD_ACCOUNT_ID)
1091+
.and_then(|v| v.value.as_ref())
1092+
.cloned();
1093+
assert_eq!(
1094+
account,
1095+
Some(Value::StringValue("111122223333".to_string())),
1096+
"cloud.account.id should be added from global state"
1097+
);
1098+
1099+
let resource = find_attribute(&span, CLOUD_RESOURCE_ID)
1100+
.and_then(|v| v.value.as_ref())
1101+
.cloned();
1102+
assert_eq!(
1103+
resource,
1104+
Some(Value::StringValue(
1105+
"arn:aws:lambda:us-east-1:111122223333:function:added".to_string()
1106+
)),
1107+
"cloud.resource_id should be added from global state"
1108+
);
1109+
1110+
crate::state::global::reset_for_tests();
1111+
}
1112+
9981113
#[test]
9991114
#[serial]
10001115
fn process_trace_request_updates_encoded_body_correctly() {

src/state/global.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ pub fn get_env_var_attrs() -> Vec<KeyValue> {
9595
ENV_VAR_ATTRS.lock().clone()
9696
}
9797

98+
#[cfg(test)]
99+
pub(crate) fn reset_for_tests() {
100+
FUNCTION_ARN.lock().take();
101+
ACCOUNT_ID.lock().take();
102+
ENV_VAR_ATTRS.lock().clear();
103+
}
104+
98105
#[cfg(test)]
99106
mod tests {
100107
use super::*;

0 commit comments

Comments
 (0)