Skip to content

OpenTelemetry Protocol cannot export spans with empty display name #4757

@Kielek

Description

@Kielek

Steps to reproduce

Execute program based on follworing snippet with Npgsql 7.0.0-rc.1 or newer (including 7.0.0).

       using var tracerProvider = Sdk.CreateTracerProviderBuilder()
            .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("npgsql-tester"))
            .SetSampler(new AlwaysOnSampler())
            // This optional activates tracing for your application, if you trace your own activities:
            .AddSource("Npgsql") // or.AddNpgsql() if you are using Npgsql.OpenTelemetry package
            // This prints tracing data to the console:
            .AddConsoleExporter()
            .AddOtlpExporter()
            .Build();

        var postgresPort = GetNpgsqlPort(args);

        var connString = $"Server=127.0.0.1;Port={postgresPort};User ID=postgres";

        await using var conn = new NpgsqlConnection(connString);
        await conn.OpenAsync();

        using var cmd = new NpgsqlCommand(@"SELECT 123;", conn);
        await using var reader = await cmd.ExecuteReaderAsync();
        while (await reader.ReadAsync())
        {
            Console.WriteLine(reader.GetInt32(0));
        }

For dependencies:

    <PackageReference Include="Npgsql" Version="7.0.0-rc.1" />
    <PackageReference Include="OpenTelemetry" Version="1.3.1" />
    <PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.3.1" />
    <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.3.1" />

The issue

If you are executing command without database name, like SELECT 123 it produces Activity (Span) with Display Name set to null.
It leads to an issue while exporting by OpenTelemetry Protocol (OTLP) which is standard protocol for OpenTelemetry.

[2022-11-15T07:27:42.5625831Z] [Error] EventSource=OpenTelemetry-Exporter-OpenTelemetryProtocol, Message=Unknown error in export method: System.ArgumentNullException: Value cannot be null. (Parameter 'value')
   at Google.Protobuf.ProtoPreconditions.CheckNotNull[T](T value, String name)
   at Opentelemetry.Proto.Trace.V1.Span.set_Name(String value)
   at OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ActivityExtensions.AddBatch(ExportTraceServiceRequest request, Resource processResource, Batch`1& activityBatch)
   at OpenTelemetry.Exporter.OtlpTraceExporter.Export(Batch`1& activityBatch) 

It can be easily tested with OpenTelemetry.Exporter.Console:

Results for Npgsql 7.0.0-rc.1

Activity.TraceId:          7eed72af89af4e40fb84b64102f3821a
Activity.SpanId:           3af9686dad354394
Activity.TraceFlags:           Recorded
Activity.ActivitySourceName: Npgsql
Activity.DisplayName: 
Activity.Kind:        Client
Activity.StartTime:   2022-11-15T07:43:28.8482469Z
Activity.Duration:    00:00:00.0272395
Activity.Tags:
    db.system: postgresql
    db.connection_string: Host=127.0.0.1;Port=53589;Username=postgres
    db.user: postgres
    db.statement: SELECT 123;
    db.connection_id: 91
    net.transport: ip_tcp
    net.peer.ip: 127.0.0.1
    net.peer.port: 53589
    net.peer.name: 127.0.0.1
   StatusCode : OK
Activity.Events:
    received-first-response [11/15/2022 7:43:28 AM +00:00]
Resource associated with Activity:
    telemetry.auto.version: 0.4.0
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.3.1.622
    service.name: unknown_service:dotnet

Results for Npgsql 7.0.0-preview.7:

Activity.TraceId:          0990e1478e0642fed4f707d380951abb
Activity.SpanId:           64c9d9af40c3b6ca
Activity.TraceFlags:           Recorded
Activity.ActivitySourceName: Npgsql
Activity.DisplayName: postgres
Activity.Kind:        Client
Activity.StartTime:   2022-11-15T07:54:36.2016112Z
Activity.Duration:    00:00:00.0275490
Activity.Tags:
    db.system: postgresql
    db.connection_string: Host=127.0.0.1;Port=53944;Username=postgres
    db.user: postgres
    db.name: postgres
    db.statement: SELECT 123;
    db.connection_id: 91
    net.transport: ip_tcp
    net.peer.ip: 127.0.0.1
    net.peer.port: 53944
    net.peer.name: 127.0.0.1
   StatusCode : OK
Activity.Events:
    received-first-response [11/15/2022 7:54:36 AM +00:00]
Resource associated with Activity:
    telemetry.auto.version: 0.4.0
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.3.1.622
    service.name: unknown_service:dotnet

It is probably introduced by ee8a378

In fact old behavior was also not ideal. The name should be called SELECT if there is no possibility to determine db.name and db.table. Please check the specification: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md?plain=1#L24-L32

Further technical details

Npgsql version: 7.0.0-rc.1, 7.0.0-rc.2, or 7.0.0.
PostgreSQL version: docker linux image: postgres:14.4

Other details about my project setup:
Found by OpenTelemetry Automatic Instrumentation .NET tests. More details you can find under open-telemetry/opentelemetry-dotnet-instrumentation#1611

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions