open-telemetry / opentelemetry-rust

The Rust OpenTelemetry implementation
https://opentelemetry.io
Apache License 2.0
1.83k stars 425 forks source link

How to change the DataDog primary operation name #1337

Open gliderkite opened 11 months ago

gliderkite commented 11 months ago

I have a set of spans that I can use to monitor my HTTP services in DataDog, and I make use of a OTLP pipeline

opentelemetry_otlp::new_pipeline()
    .tracing()
    .with_exporter(
        opentelemetry_otlp::new_exporter()
            .tonic()
...

I use axum as web server and add a TraceLayer to create a new span every time I get a request. I can then see the trace and related spans in DataDog that are shown as follow

Screenshot 2023-11-02 at 12 08 14

I couldn't find a way to change/update what I think is the primary operation of the services, that is displayed for each span as opentelemetry_otlp.<kind>, making the whole thing quite noisy, to the point where short span names are not displayed because the primary operation name takes all the space available.

I was able to set the kind by setting the span attribute otel.kind when this is created, for example:

let span = info_span!(
    "http_request",
    "http.method" = ?request.method(),
    "http.version" = ?request.version(),
    "headers" = ?request.headers(),
    "otel.kind" = "server",
);

Is there a way to change what is shown in DataDog as opentelemetry_otlp (that seems to be the otel.library.name)?

hdost commented 11 months ago

What you may want to consider is setting http.route https://opentelemetry.io/docs/specs/semconv/attributes-registry/http/, that should be more related to the Primary operation. However, this is interesting because it seems like something isn't getting translated correctly. Do you have a minimal working example?

gliderkite commented 11 months ago

What you may want to consider is setting http.route https://opentelemetry.io/docs/specs/semconv/attributes-registry/http/, that should be more related to the Primary operation. However, this is interesting because it seems like something isn't getting translated correctly. Do you have a minimal working example?

I do actually already set the http.route, I just omitted it in the example above for brevity

TraceLayer::new_for_http()
    .make_span_with(|request: &Request<_>| {
        let route = request
            .extensions()
            .get::<MatchedPath>()
            .map(MatchedPath::as_str);

        info_span!(
            "http_request",
            "http.method" = ?request.method(),
            "http.route" = route,
            "http.status_code" = Empty,
            "http.version" = ?request.version(),
            "otel.kind" = "server",
            "headers" = ?request.headers(),
        )
    }

I do not have a minimal working example as this is not code I can share in full, but if it helps it'd be relatively easy to extract the main parts, please let me know if there is anything in specific you'd want me to share. Thanks.