Skip to content

Commit 1e47903

Browse files
fix(datadog): status_code must be 0 or 1 (open-telemetry#580) (open-telemetry#581)
opentelemetry's StatusCode enum can be 0 (Unset), 1 (Ok) or 2 (Error). otel specification says "don't ever use Ok, just leave it unset". So for, non-error spans, the opentelemetry-datadog exporter does the right thing: it sets the datadog trace's status code to 0. However, for errors, the opentelemetry-datadog exporter sets the status_code to 2. This isn't explicitly discouraged by the available Datadog docs, but it causes something really interesting: the trace shows up with a "red" left border in Datadog APM (instead of a "green" one). The "Ok/Error" filter filters those traces correctly. However, half the UI is missing: when opening the trace, there's no '!' in the left-hand corner, there's no "Errors (1)" tab, and there's no detail of the error being shown in a user-friendly way. tl;dr In the Datadog backend, there's some code that does "status_code != 0", and some code that does "status_code == 1". The 2 value isn't set by their Go exporter, and so the opentelemetry-rust exporter should never use it. Co-authored-by: Amos Wenger <fasterthanlime@users.noreply.github.com>
1 parent 381be08 commit 1e47903

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

opentelemetry-datadog/src/exporter/model/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub(crate) mod tests {
127127
let traces = get_traces();
128128
let encoded = base64::encode(ApiVersion::Version03.encode("service_name", traces)?);
129129

130-
assert_eq!(encoded.as_str(), "kZGLpHR5cGWjd2Vip3NlcnZpY2Wsc2VydmljZV9uYW1lpG5hbWWpY29tcG9uZW50qHJlc291cmNlqHJlc291cmNlqHRyYWNlX2lkzwAAAAAAAAAHp3NwYW5faWTPAAAAAAAAAGOpcGFyZW50X2lkzwAAAAAAAAABpXN0YXJ00wAAAAAAAAAAqGR1cmF0aW9u0wAAAAA7msoApWVycm9y0gAAAAGkbWV0YYGpc3Bhbi50eXBlo3dlYg==");
130+
assert_eq!(encoded.as_str(), "kZGLpHR5cGWjd2Vip3NlcnZpY2Wsc2VydmljZV9uYW1lpG5hbWWpY29tcG9uZW50qHJlc291cmNlqHJlc291cmNlqHRyYWNlX2lkzwAAAAAAAAAHp3NwYW5faWTPAAAAAAAAAGOpcGFyZW50X2lkzwAAAAAAAAABpXN0YXJ00wAAAAAAAAAAqGR1cmF0aW9u0wAAAAA7msoApWVycm9y0gAAAACkbWV0YYGpc3Bhbi50eXBlo3dlYg==");
131131

132132
Ok(())
133133
}
@@ -137,7 +137,7 @@ pub(crate) mod tests {
137137
let traces = get_traces();
138138
let encoded = base64::encode(ApiVersion::Version05.encode("service_name", traces)?);
139139

140-
assert_eq!(encoded.as_str(), "kpWsc2VydmljZV9uYW1lo3dlYqljb21wb25lbnSocmVzb3VyY2Wpc3Bhbi50eXBlkZGczgAAAADOAAAAAs4AAAADzwAAAAAAAAAHzwAAAAAAAABjzwAAAAAAAAAB0wAAAAAAAAAA0wAAAAA7msoA0gAAAAGBzgAAAATOAAAAAYDOAAAAAQ==");
140+
assert_eq!(encoded.as_str(), "kpWsc2VydmljZV9uYW1lo3dlYqljb21wb25lbnSocmVzb3VyY2Wpc3Bhbi50eXBlkZGczgAAAADOAAAAAs4AAAADzwAAAAAAAAAHzwAAAAAAAABjzwAAAAAAAAAB0wAAAAAAAAAA0wAAAAA7msoA0gAAAACBzgAAAATOAAAAAYDOAAAAAQ==");
141141

142142
Ok(())
143143
}

opentelemetry-datadog/src/exporter/model/v03.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::exporter::model::Error;
22
use opentelemetry::sdk::export::trace;
3+
use opentelemetry::trace::StatusCode;
34
use opentelemetry::{Key, Value};
45
use std::time::SystemTime;
56

@@ -61,7 +62,13 @@ pub(crate) fn encode(
6162
rmp::encode::write_i64(&mut encoded, duration)?;
6263

6364
rmp::encode::write_str(&mut encoded, "error")?;
64-
rmp::encode::write_i32(&mut encoded, span.status_code as i32)?;
65+
rmp::encode::write_i32(
66+
&mut encoded,
67+
match span.status_code {
68+
StatusCode::Error => 1,
69+
_ => 0,
70+
},
71+
)?;
6572

6673
rmp::encode::write_str(&mut encoded, "meta")?;
6774
rmp::encode::write_map_len(&mut encoded, span.attributes.len() as u32)?;

opentelemetry-datadog/src/exporter/model/v05.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::exporter::intern::StringInterner;
22
use crate::exporter::Error;
33
use opentelemetry::sdk::export::trace;
4+
use opentelemetry::trace::StatusCode;
45
use opentelemetry::{Key, Value};
56
use std::time::SystemTime;
67

@@ -111,7 +112,13 @@ fn encode_traces(
111112
rmp::encode::write_u64(&mut encoded, span.parent_span_id.to_u64())?;
112113
rmp::encode::write_i64(&mut encoded, start)?;
113114
rmp::encode::write_i64(&mut encoded, duration)?;
114-
rmp::encode::write_i32(&mut encoded, span.status_code as i32)?;
115+
rmp::encode::write_i32(
116+
&mut encoded,
117+
match span.status_code {
118+
StatusCode::Error => 1,
119+
_ => 0,
120+
},
121+
)?;
115122
rmp::encode::write_map_len(&mut encoded, span.attributes.len() as u32)?;
116123
for (key, value) in span.attributes.iter() {
117124
rmp::encode::write_u32(&mut encoded, interner.intern(key.as_str()))?;

0 commit comments

Comments
 (0)