diff --git a/opentelemetry-jaeger/src/exporter/mod.rs b/opentelemetry-jaeger/src/exporter/mod.rs index 087e11c459..8a526f84dd 100644 --- a/opentelemetry-jaeger/src/exporter/mod.rs +++ b/opentelemetry-jaeger/src/exporter/mod.rs @@ -623,11 +623,6 @@ fn build_span_tags( } } - // Ensure error status is set - if status_code == StatusCode::Error && !user_overrides.error { - tags.push(Key::new(ERROR).bool(true).into()) - } - if !user_overrides.span_kind { tags.push(Key::new(SPAN_KIND).string(kind.to_string()).into()); } @@ -636,8 +631,31 @@ fn build_span_tags( tags.push(KeyValue::new(STATUS_CODE, status_code as i64).into()); } - if !user_overrides.status_message { - tags.push(Key::new(STATUS_MESSAGE).string(status_message).into()); + if status_code != StatusCode::Unset { + // Ensure error status is set + if status_code == StatusCode::Error { + tags.push(Key::new(ERROR).bool(true).into()); + } + tags.push( + Key::new(OTEL_STATUS_CODE) + .string::(status_code.into()) + .into(), + ); + // set status message if there is one + if status_message.len() > 0 { + if !user_overrides.status_message { + tags.push( + Key::new(STATUS_MESSAGE) + .string(status_message.clone()) + .into(), + ); + } + tags.push( + Key::new(OTEL_STATUS_DESCRIPTION) + .string(status_message) + .into(), + ); + } } Some(tags) @@ -647,6 +665,8 @@ const ERROR: &str = "error"; const SPAN_KIND: &str = "span.kind"; const STATUS_CODE: &str = "status.code"; const STATUS_MESSAGE: &str = "status.message"; +const OTEL_STATUS_CODE: &str = "otel.status_code"; +const OTEL_STATUS_DESCRIPTION: &str = "otel.status_description"; #[derive(Default)] struct UserOverrides { diff --git a/opentelemetry-zipkin/src/exporter/model/mod.rs b/opentelemetry-zipkin/src/exporter/model/mod.rs index 2d0d7de43f..9eb7fd356c 100644 --- a/opentelemetry-zipkin/src/exporter/model/mod.rs +++ b/opentelemetry-zipkin/src/exporter/model/mod.rs @@ -12,11 +12,10 @@ pub(crate) mod span; use endpoint::Endpoint; -/// Instrument Library name MUST be reported in Jaeger Span tags with the following key const INSTRUMENTATION_LIBRARY_NAME: &str = "otel.library.name"; - -/// Instrument Library version MUST be reported in Jaeger Span tags with the following key const INSTRUMENTATION_LIBRARY_VERSION: &str = "otel.library.version"; +const OTEL_ERROR_DESCRIPTION: &str = "error"; +const OTEL_STATUS_CODE: &str = "otel.status_code"; /// Converts `Event` into an `annotation::Annotation` impl Into for Event { @@ -88,15 +87,17 @@ pub(crate) fn into_zipkin_span(local_endpoint: Endpoint, span_data: trace::SpanD ] .iter() .filter_map(|(key, val)| val.map(|val| KeyValue::new(*key, val))), - ), + ) + .filter(|kv| kv.key.as_str() == "error" && kv.value.as_str() == "false"), ); if let Some(status_code) = from_statuscode_to_str(span_data.status_code) { - tags.insert("otel.status_code".into(), status_code.into()); + if status_code == "ERROR" { + tags.insert(OTEL_ERROR_DESCRIPTION.into(), span_data.status_message); + } + tags.insert(OTEL_STATUS_CODE.into(), status_code.into()); } - tags.insert("otel.status_description".into(), span_data.status_message); - span::Span::builder() .trace_id(span_data.span_context.trace_id().to_hex()) .parent_id(span_data.parent_span_id.to_hex()) diff --git a/opentelemetry/src/api/trace/span.rs b/opentelemetry/src/api/trace/span.rs index 390993ddf2..abfba20f84 100644 --- a/opentelemetry/src/api/trace/span.rs +++ b/opentelemetry/src/api/trace/span.rs @@ -123,7 +123,7 @@ pub trait Span: fmt::Debug + 'static + Send + Sync { fn set_attribute(&self, attribute: KeyValue); /// Sets the status of the `Span`. If used, this will override the default `Span` - /// status, which is `OK`. + /// status, which is `Unset`. `message` MUST be ignored when the status is `OK` or `Unset` /// /// Only the value of the last call will be recorded, and implementations are free /// to ignore previous calls. @@ -241,7 +241,7 @@ impl fmt::Display for SpanKind { /// It's composed of a canonical code in conjunction with an optional /// descriptive message. #[cfg_attr(feature = "serialize", derive(Deserialize, Serialize))] -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Copy)] pub enum StatusCode { /// The default status. Unset = 0, @@ -250,3 +250,13 @@ pub enum StatusCode { /// The operation contains an error. Error = 2, } + +impl Into for StatusCode { + fn into(self) -> String { + match self { + StatusCode::Unset => "".to_string(), + StatusCode::Ok => "OK".to_string(), + StatusCode::Error => "Error".to_string(), + } + } +} diff --git a/opentelemetry/src/sdk/trace/span.rs b/opentelemetry/src/sdk/trace/span.rs index 8fc8e042f4..ffeab0d45d 100644 --- a/opentelemetry/src/sdk/trace/span.rs +++ b/opentelemetry/src/sdk/trace/span.rs @@ -129,11 +129,13 @@ impl crate::trace::Span for Span { } /// Sets the status of the `Span`. If used, this will override the default `Span` - /// status, which is `Unset`. + /// status, which is `Unset`. `message` MUST be ignored when the status is `OK` or `Unset` fn set_status(&self, code: StatusCode, message: String) { self.with_data(|data| { + if code == StatusCode::Error { + data.status_message = message; + } data.status_code = code; - data.status_message = message }); }