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

add support of other format for trace id #5735

Merged
merged 7 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
27 changes: 27 additions & 0 deletions .changesets/feat_bnjjj_feat_417.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
### Add support of other format for trace id in telemetry ([PR #5735](https://github.com/apollographql/router/pull/5735))

Currently we support datadog and otel traceID formats and decimal. However we would like to also support UUID.

Unify the two `TraceIdFormat` enums into a single enum that us used across selectors and experimental_expose_trace id.

Ensure the following formats are supported:

+ open_telemetry
+ hexadecimal (same as opentelemetry)
+ decimal
+ datadog
+ uuid (this has dashes)

Add support for logging to output using `TraceIdFormat`

```yaml
telemetry:
exporters:
logging:
stdout:
format:
json:
disaplay_trace_id: (true|false|open_telemetry|hexadecimal|decimal|datadog|uuid)
```

By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5735
Original file line number Diff line number Diff line change
Expand Up @@ -2114,6 +2114,17 @@ expression: "&schema"
],
"type": "string"
},
"DisplayTraceIdFormat": {
"anyOf": [
{
"$ref": "#/definitions/TraceIdFormat",
"description": "#/definitions/TraceIdFormat"
},
{
"type": "boolean"
}
]
},
"Enabled": {
"enum": [
"enabled"
Expand Down Expand Up @@ -2527,8 +2538,8 @@ expression: "&schema"
"type": "boolean"
},
"format": {
"$ref": "#/definitions/TraceIdFormat2",
"description": "#/definitions/TraceIdFormat2"
"$ref": "#/definitions/TraceIdFormat",
"description": "#/definitions/TraceIdFormat"
},
"header_name": {
"description": "Choose the header name to expose trace_id (default: apollo-trace-id)",
Expand Down Expand Up @@ -7146,27 +7157,16 @@ expression: "&schema"
"TraceIdFormat": {
"oneOf": [
{
"description": "Open Telemetry trace ID, a hex string.",
"description": "Format the Trace ID as a hexadecimal number\n\n(e.g. Trace ID 16 -> 00000000000000000000000000000010)",
"enum": [
"open_telemetry"
"hexadecimal"
],
"type": "string"
},
{
"description": "Datadog trace ID, a u64.",
"enum": [
"datadog"
],
"type": "string"
}
]
},
"TraceIdFormat2": {
"oneOf": [
{
"description": "Format the Trace ID as a hexadecimal number\n\n(e.g. Trace ID 16 -> 00000000000000000000000000000010)",
"enum": [
"hexadecimal"
"open_telemetry"
],
"type": "string"
},
Expand All @@ -7183,6 +7183,13 @@ expression: "&schema"
"datadog"
],
"type": "string"
},
{
"description": "UUID format with dashes (eg. 67e55044-10b1-426f-9247-bb680e5fe0c8)",
"enum": [
"uuid"
],
"type": "string"
}
]
},
Expand Down Expand Up @@ -8131,9 +8138,8 @@ expression: "&schema"
"type": "boolean"
},
"display_trace_id": {
"default": true,
"description": "Include the trace id (if any) with the log event. (default: true)",
"type": "boolean"
"$ref": "#/definitions/DisplayTraceIdFormat",
"description": "#/definitions/DisplayTraceIdFormat"
}
},
"type": "object"
Expand Down Expand Up @@ -8229,9 +8235,8 @@ expression: "&schema"
"type": "boolean"
},
"display_trace_id": {
"default": false,
"description": "Include the trace id (if any) with the log event. (default: false)",
"type": "boolean"
"$ref": "#/definitions/DisplayTraceIdFormat",
"description": "#/definitions/DisplayTraceIdFormat"
}
},
"type": "object"
Expand Down
25 changes: 23 additions & 2 deletions apollo-router/src/plugins/telemetry/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,21 +232,42 @@ pub(crate) struct ExposeTraceId {
pub(crate) format: TraceIdFormat,
}

#[derive(Clone, Default, Debug, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields, rename_all = "lowercase")]
#[derive(Clone, Default, Debug, Deserialize, JsonSchema, PartialEq, Eq)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub(crate) enum TraceIdFormat {
/// Format the Trace ID as a hexadecimal number
///
/// (e.g. Trace ID 16 -> 00000000000000000000000000000010)
#[default]
Hexadecimal,
/// Format the Trace ID as a hexadecimal number
///
/// (e.g. Trace ID 16 -> 00000000000000000000000000000010)
OpenTelemetry,
/// Format the Trace ID as a decimal number
///
/// (e.g. Trace ID 16 -> 16)
Decimal,

/// Datadog
Datadog,

/// UUID format with dashes
/// (eg. 67e55044-10b1-426f-9247-bb680e5fe0c8)
Uuid,
}

impl TraceIdFormat {
pub(crate) fn format(&self, trace_id: TraceId) -> String {
match self {
TraceIdFormat::Hexadecimal | TraceIdFormat::OpenTelemetry => {
format!("{:032x}", trace_id)
}
TraceIdFormat::Decimal => format!("{}", u128::from_be_bytes(trace_id.to_bytes())),
TraceIdFormat::Datadog => trace_id.to_datadog(),
TraceIdFormat::Uuid => Uuid::from_bytes(trace_id.to_bytes()).to_string(),
}
}
}

/// Apollo usage report signature normalization algorithm
Expand Down
42 changes: 38 additions & 4 deletions apollo-router/src/plugins/telemetry/config_new/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use serde::Deserializer;

use crate::configuration::ConfigurationError;
use crate::plugins::telemetry::config::AttributeValue;
use crate::plugins::telemetry::config::TraceIdFormat;
use crate::plugins::telemetry::config_new::experimental_when_header::HeaderLoggingCondition;
use crate::plugins::telemetry::resource::ConfigResource;
use crate::services::SupergraphRequest;
Expand Down Expand Up @@ -335,11 +336,44 @@ pub(crate) struct JsonFormat {
/// Include the resource with the log event. (default: true)
pub(crate) display_resource: bool,
/// Include the trace id (if any) with the log event. (default: true)
pub(crate) display_trace_id: bool,
pub(crate) display_trace_id: DisplayTraceIdFormat,
/// Include the span id (if any) with the log event. (default: true)
pub(crate) display_span_id: bool,
}

#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Eq)]
#[serde(deny_unknown_fields, rename_all = "snake_case", untagged)]
pub(crate) enum DisplayTraceIdFormat {
// /// Format the Trace ID as a hexadecimal number
// ///
// /// (e.g. Trace ID 16 -> 00000000000000000000000000000010)
// #[default]
// Hexadecimal,
// /// Format the Trace ID as a hexadecimal number
// ///
// /// (e.g. Trace ID 16 -> 00000000000000000000000000000010)
// OpenTelemetry,
// /// Format the Trace ID as a decimal number
// ///
// /// (e.g. Trace ID 16 -> 16)
// Decimal,

// /// Datadog
// Datadog,

// /// UUID format with dashes
// /// (eg. 67e55044-10b1-426f-9247-bb680e5fe0c8)
// Uuid,
TraceIdFormat(TraceIdFormat),
Bool(bool),
}

impl Default for DisplayTraceIdFormat {
fn default() -> Self {
Self::TraceIdFormat(TraceIdFormat::default())
}
}

impl Default for JsonFormat {
fn default() -> Self {
JsonFormat {
Expand All @@ -353,7 +387,7 @@ impl Default for JsonFormat {
display_current_span: false,
display_span_list: true,
display_resource: true,
display_trace_id: true,
display_trace_id: DisplayTraceIdFormat::Bool(true),
display_span_id: true,
}
}
Expand Down Expand Up @@ -389,7 +423,7 @@ pub(crate) struct TextFormat {
/// Include all of the containing span information with the log event. (default: true)
pub(crate) display_span_list: bool,
/// Include the trace id (if any) with the log event. (default: false)
pub(crate) display_trace_id: bool,
pub(crate) display_trace_id: DisplayTraceIdFormat,
/// Include the span id (if any) with the log event. (default: false)
pub(crate) display_span_id: bool,
}
Expand All @@ -410,7 +444,7 @@ impl Default for TextFormat {
display_resource: false,
display_current_span: true,
display_span_list: true,
display_trace_id: false,
display_trace_id: DisplayTraceIdFormat::Bool(false),
display_span_id: false,
}
}
Expand Down
51 changes: 33 additions & 18 deletions apollo-router/src/plugins/telemetry/config_new/selectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ use crate::plugins::cache::entity::CacheSubgraph;
use crate::plugins::cache::metrics::CacheMetricContextKey;
use crate::plugins::demand_control::CostContext;
use crate::plugins::telemetry::config::AttributeValue;
use crate::plugins::telemetry::config::TraceIdFormat;
use crate::plugins::telemetry::config_new::cost::CostValue;
use crate::plugins::telemetry::config_new::get_baggage;
use crate::plugins::telemetry::config_new::instruments::Event;
use crate::plugins::telemetry::config_new::instruments::InstrumentValue;
use crate::plugins::telemetry::config_new::instruments::Standard;
use crate::plugins::telemetry::config_new::trace_id;
use crate::plugins::telemetry::config_new::DatadogId;
use crate::plugins::telemetry::config_new::Selector;
use crate::plugins::telemetry::config_new::ToOtelValue;
use crate::query_planner::APOLLO_OPERATION_ID;
Expand All @@ -33,15 +33,6 @@ use crate::services::FIRST_EVENT_CONTEXT_KEY;
use crate::spec::operation_limits::OperationLimits;
use crate::Context;

#[derive(Deserialize, JsonSchema, Clone, Debug, PartialEq)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub(crate) enum TraceIdFormat {
/// Open Telemetry trace ID, a hex string.
OpenTelemetry,
/// Datadog trace ID, a u64.
Datadog,
}

#[derive(Deserialize, JsonSchema, Clone, Debug, PartialEq)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub(crate) enum OperationName {
Expand Down Expand Up @@ -681,13 +672,7 @@ impl Selector for RouterSelector {
.map(opentelemetry::Value::from),
RouterSelector::TraceId {
trace_id: trace_id_format,
} => trace_id().map(|id| {
match trace_id_format {
TraceIdFormat::OpenTelemetry => id.to_string(),
TraceIdFormat::Datadog => id.to_datadog(),
}
.into()
}),
} => trace_id().map(|id| trace_id_format.format(id).into()),
RouterSelector::Baggage {
baggage, default, ..
} => get_baggage(baggage).or_else(|| default.maybe_to_otel_value()),
Expand Down Expand Up @@ -2378,7 +2363,7 @@ mod test {
let subscriber = tracing_subscriber::registry().with(otel::layer());
subscriber::with_default(subscriber, || {
let selector = RouterSelector::TraceId {
trace_id: TraceIdFormat::OpenTelemetry,
trace_id: TraceIdFormat::Hexadecimal,
};
assert_eq!(
selector.on_request(
Expand Down Expand Up @@ -2427,6 +2412,36 @@ mod test {
.unwrap(),
opentelemetry::Value::String("42".into())
);

let selector = RouterSelector::TraceId {
trace_id: TraceIdFormat::Uuid,
};

assert_eq!(
selector
.on_request(
&crate::services::RouterRequest::fake_builder()
.build()
.unwrap(),
)
.unwrap(),
opentelemetry::Value::String("00000000-0000-0000-0000-00000000002a".into())
);

let selector = RouterSelector::TraceId {
trace_id: TraceIdFormat::Decimal,
};

assert_eq!(
selector
.on_request(
&crate::services::RouterRequest::fake_builder()
.build()
.unwrap(),
)
.unwrap(),
opentelemetry::Value::String("42".into())
);
});
}

Expand Down
25 changes: 22 additions & 3 deletions apollo-router/src/plugins/telemetry/formatters/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use super::EventFormatter;
use super::APOLLO_PRIVATE_PREFIX;
use super::EXCLUDED_ATTRIBUTES;
use crate::plugins::telemetry::config::AttributeValue;
use crate::plugins::telemetry::config::TraceIdFormat;
use crate::plugins::telemetry::config_new::logging::DisplayTraceIdFormat;
use crate::plugins::telemetry::config_new::logging::JsonFormat;
use crate::plugins::telemetry::dynamic_attribute::EventAttributes;
use crate::plugins::telemetry::dynamic_attribute::LogAttributes;
Expand Down Expand Up @@ -227,12 +229,29 @@ where

if let Some(ref span) = current_span {
if let Some((trace_id, span_id)) = get_trace_and_span_id(span) {
if self.config.display_trace_id {
let trace_id = match self.config.display_trace_id {
DisplayTraceIdFormat::Bool(true)
| DisplayTraceIdFormat::TraceIdFormat(TraceIdFormat::Hexadecimal)
| DisplayTraceIdFormat::TraceIdFormat(TraceIdFormat::OpenTelemetry) => {
Some(TraceIdFormat::Hexadecimal.format(trace_id))
}
DisplayTraceIdFormat::TraceIdFormat(TraceIdFormat::Decimal) => {
Some(TraceIdFormat::Decimal.format(trace_id))
}
DisplayTraceIdFormat::TraceIdFormat(TraceIdFormat::Datadog) => {
Some(TraceIdFormat::Datadog.format(trace_id))
}
DisplayTraceIdFormat::TraceIdFormat(TraceIdFormat::Uuid) => {
Some(TraceIdFormat::Uuid.format(trace_id))
}
DisplayTraceIdFormat::Bool(false) => None,
};
if let Some(trace_id) = trace_id {
serializer
.serialize_entry("trace_id", &trace_id.to_string())
.serialize_entry("trace_id", &trace_id)
.unwrap_or(());
}
if self.config.display_trace_id {
if self.config.display_span_id {
serializer
.serialize_entry("span_id", &span_id.to_string())
.unwrap_or(());
Expand Down
Loading
Loading