opentelemetry-dotnet icon indicating copy to clipboard operation
opentelemetry-dotnet copied to clipboard

With AspNetCore 6, OtlpExporter fail to send trace if running on linux

Open mrioux3 opened this issue 3 years ago • 4 comments

Bug Report

OpenTelemetry 1.3.0 OpenTelemetry.Exporter.OpenTelemetryProtocol 1.3.0 OpenTelemetry.Extensions.Hosting 1.0.0-rc9.4 OpenTelemetry.Instrumentation.AspNetCore 1.0.0-rc9.4

Runtime version net6.0

Symptom

When running an AspNetCore 6 on linux, the OtlpExporter fail to send the traces to the exporter with no error message.

What is the expected behavior?

The trace should be sent to the otlpExporter when running under linux.

What is the actual behavior?

The trace is never sent when running with linux.

Reproduce

This is based on the code example from https://opentelemetry.io/docs/instrumentation/net/getting-started/

builder.Services.AddOpenTelemetryTracing(tracerProviderBuilder =>
{
    tracerProviderBuilder
                .AddSource(ServiceName)
                .SetResourceBuilder(ResourceBuilder.CreateDefault()
                        .AddService(serviceName: ServiceName, serviceVersion: ServiceVersion))
                .AddAspNetCoreInstrumentation()
                .AddOtlpExporter(opt =>
                {
                    opt.Endpoint = new Uri(endpoint);
                    opt.Protocol = OtlpExportProtocol.Grpc;
                });
});

var app = builder.Build();

var MyActivitySource = new ActivitySource(ServiceName, ServiceVersion);

app.MapGet("/hello", () =>
{
    // Track work inside of the request
    using var activity = MyActivitySource.StartActivity("Test");
    activity?.SetTag("Test", 100);

    return activity?.RootId;
});

Additional Context

This issue only happen on linux. The code work on Windows. This was tested on "Ubuntu 20.04.4 LTS" version "5.4.0-1055-kvm" and "5.10.16.3-microsoft-standard-WSL2"

Using the consoleexporter, I see the data showing up in the console and everything seems fine.

I also try to change the opentelemetry nuget to 1.2.0 and 1.4.0-alpha.2 and still had the issues with those versions. (the other nugets were updated to match)

mrioux3 avatar Aug 30 '22 22:08 mrioux3

For the exporter, can you try specifying the endpoint like so.

 otlpOptions.Endpoint = new Uri(endpoint + "/api/v1/traces"); 

mrblonde91 avatar Aug 31 '22 08:08 mrblonde91

For the exporter, can you try specifying the endpoint like so.

 otlpOptions.Endpoint = new Uri(endpoint + "/api/v1/traces"); 

I tried and that didn't work.

mrioux3 avatar Aug 31 '22 15:08 mrioux3

https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol#troubleshooting Follow the troubleshooting steps and can you get the logs, so we can figure out whats going on?

cijothomas avatar Sep 01 '22 19:09 cijothomas

Trying the self diagnostic in my main application, the only event that show up is System.Diagnostics.Tracing.EventPayload : 2022-09-01T19:58:56.8518308Z:{System.Diagnostics.Tracing.EventPayload} 2022-09-01T19:58:56.8518360Z:{System.Diagnostics.Tracing.EventPayload} 2022-09-01T19:58:56.8518408Z:{System.Diagnostics.Tracing.EventPayload}

The log file is filled with this event.

mrioux3 avatar Sep 01 '22 20:09 mrioux3

@cijothomas I'm having similiar issues, where publishing the application with -r win10-x64 everything works as expected, but with -r linux-x64 nothing is exported. I also tried creating the OTEL_DIAGNOSTICS.json file, but that also worked only on windows. Any ideas what could be the issue?

.NET SDK version: 7.0.202 Packages:

OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs 1.4.0-rc.4
OpenTelemetry.Exporter.OpenTelemetryProtocol 1.4.0
OpenTelemetry.Extensions.Hosting 1.4.0
OpenTelemetry.Instrumentation.AspNetCore 1.0.0-rc9.14
OpenTelemetry.Instrumentation.Http 1.0.0-rc9.14
OpenTelemetry.Instrumentation.Process 0.5.0-beta.2
OpenTelemetry.Instrumentation.SqlClient 1.0.0-rc9.13
OpenTelemetry.Instrumentation.Runtime 1.1.0-rc.2

VMelnalksnis avatar Mar 25 '23 16:03 VMelnalksnis

@utpilla Please take a look!

cijothomas avatar Mar 29 '23 19:03 cijothomas

Trying the self diagnostic in my main application, the only event that show up is System.Diagnostics.Tracing.EventPayload : 2022-09-01T19:58:56.8518308Z:{System.Diagnostics.Tracing.EventPayload} 2022-09-01T19:58:56.8518360Z:{System.Diagnostics.Tracing.EventPayload} 2022-09-01T19:58:56.8518408Z:{System.Diagnostics.Tracing.EventPayload}

The log file is filled with this event.

https://github.com/open-telemetry/opentelemetry-dotnet/pull/5046 fixes the issue!

cijothomas avatar Nov 14 '23 00:11 cijothomas

https://github.com/open-telemetry/opentelemetry-dotnet/pull/5046 fixes the self-diagnostics, which will help understand the root cause of the issue reported here.

cijothomas avatar Nov 14 '23 00:11 cijothomas

We have same problem in our application. Even after updating from .net 6.0 to .net 8.0. Application is using AspNetCore.

Packages:

OpenTelemetry(1.70)
OpenTelemetryApi(1.70) 
OpenTelemetryApi.ProviderBuilderExtensions(1.70) 
OpenTelemetry.Exporter.OpenTelemetryProtocol(1.70) 
OpenTelemetry.Exporter.PrometheusAspNetCore(1.7.0-rc.1)
OpenTelemetry.Extensions.Hosting(1.70) 
OpenTelemetry.lnstrumentation.AspNetCore(1.70) 
OpenTelemetry.lnstrumentation.Http(1.70) 
OpenTelemetry.lnstrumentation.Process(0.5.0-beta.3) 
OpenTelemetry.lnstrumentation.Runtime(1.70) 

Configuration:

.AddOpenTelemetry()
.WithTracing(
	tracerProviderBuilder =>
		tracerProviderBuilder
			.AddSource(opts.ServiceName)
			.SetSampler(new AlwaysOnSampler())
			.AddAspNetCoreInstrumentation((options) =>
			{
				options.RecordException = true;
			})
			.AddHttpClientInstrumentation((options =>
			{
				options.RecordException = true;
			}))
			.AddOtlpExporter())

After adding OTEL_DIAGNOSTICS.json and setting log level to Verbose I can see that Activities start and end:

2024-01-11T12:28:34.1408035Z:Activity started. Name = '{0}', Id = '{1}'.{System.Net.Http.HttpRequestOut}{00-37c74d2fc18b6f9716f083254a21d5b3-a5a7b995310df765-01}
2024-01-11T12:28:34.1476990Z:Activity stopped. Name = '{0}', Id = '{1}'.{POST}{00-37c74d2fc18b6f9716f083254a21d5b3-a5a7b995310df765-01}
2024-01-11T12:28:34.1983849Z:Activity started. Name = '{0}', Id = '{1}'.{System.Net.Http.HttpRequestOut}{00-37c74d2fc18b6f9716f083254a21d5b3-717228a8dff2f2f9-01}
2024-01-11T12:28:34.2039340Z:Activity stopped. Name = '{0}', Id = '{1}'.{POST}{00-37c74d2fc18b6f9716f083254a21d5b3-717228a8dff2f2f9-01}
2024-01-11T12:28:34.2329163Z:Activity started. Name = '{0}', Id = '{1}'.{#####}{00-37c74d2fc18b6f9716f083254a21d5b3-0382e85fd4bcba28-01}
2024-01-11T12:28:34.2446729Z:Activity started. Name = '{0}', Id = '{1}'.{System.Net.Http.HttpRequestOut}{00-37c74d2fc18b6f9716f083254a21d5b3-22fc042a507dee41-01}
2024-01-11T12:28:35.2179964Z:Activity stopped. Name = '{0}', Id = '{1}'.{POST}{00-37c74d2fc18b6f9716f083254a21d5b3-22fc042a507dee41-01}
2024-01-11T12:28:35.2223925Z:Activity stopped. Name = '{0}', Id = '{1}'.{#####}{00-37c74d2fc18b6f9716f083254a21d5b3-0382e85fd4bcba28-01}
2024-01-11T12:28:35.2726035Z:Activity stopped. Name = '{0}', Id = '{1}'.{POST calling/v1/callouts}{00-37c74d2fc18b6f9716f083254a21d5b3-c38e450d63a0e3b6-01}

From other app on same host, written in .net 8.0 with Minimal API, with same configuration, tracing IS working.

aburok avatar Jan 11 '24 12:01 aburok

Workaround

Solution that worked for me was to switch to Zipkin Exporter, which exports spans/activities as JSON over HTTP.

tracerProviderBuilder.AddZipkinExporter(builder =>
{
    builder.Endpoint = new Uri("http://localhost:9411/api/v2/spans");
});

We are using open telemetry collectors on Kubernetes which allows to configure a zipkin receiver.

Open telemetry collector transform the Zipkin format into in internal open telemetry format and can push that span/acitivity to any other desitnation

aburok avatar Jan 12 '24 10:01 aburok

@aburok Can you collect the self diagnostics logs for at least 1 minute and share?

cijothomas avatar Jan 12 '24 16:01 cijothomas

@cijothomas unfortunately I was not able to gathet any open telemetry self diagnostic logs on linux. Even when add OTEL_DIAGNOSTICS.json file in application directory and setting log level to debug, log files do not appear in the linux container. I have made sure that application has right to write to file system.

Self diagnostic logs work fine on windows though. But on windows the problem with exporter does not occur.

aburok avatar Jan 12 '24 18:01 aburok

Weird that the logs are not captured with self-diag!

Could you use an alternate tool to collect the logs? https://learn.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-trace is cross platform and can be used to collect logs.

The following should do the trick!

dotnet-trace collect --process-id <PID> --providers OpenTelemetry-Exporter-OpenTelemetryProtocol,OpenTelemetry-Sdk

cijothomas avatar Jan 12 '24 22:01 cijothomas

@cijothomas I have run a dotnet-trace command and have following trace info for both Zipkin and Otlp Exporters: image

Is this info enough for you ? Also it would be useful to have logs for OpenTelemetry working on Linux docker containers. So far I was not able to make them work on Linux containers. Logs for OpenTelemetry worked fine on Windows though.

aburok avatar Jan 18 '24 20:01 aburok

Is this info enough for you ? No. Need to get the actual logs..Can you attach the logs file? The screenshot is showing perf graph only, which won't help with understanding why OTLPExporter is failing!

cijothomas avatar Jan 18 '24 21:01 cijothomas

I have found log:

Provider Name/Event Name	Text	Timestamp (ms)
OpenTelemetry-Exporter-OpenTelemetryProtocol/FailedToReachCollector	[rawCollectorUri, http://opentelemetry_collector:4317/v1/traces], [ex, System.Net.Http.HttpRequestException: An error occurred while sending the request.
 ---> System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer.
 ---> System.Net.Sockets.SocketException (104): Connection reset by peer
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Http.HttpConnection.FillAsync(Boolean async)
   at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean async, Boolean foldedHeadersAllowed)
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.SocketsHttpHandler.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClientHandler.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpMessageInvoker.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient.BaseOtlpHttpExportClient`1.SendExportRequest(TRequest request, CancellationToken cancellationToken)]	12725

Btw I am using http/protobuf as a protocol.

The collector is up and running with following configuration:

receivers:
  otlp:
    protocols:
      grpc:
      http:
exporters:
  debug:
    verbosity: detailed
service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [debug]

No traces are reaching the collector.

aburok avatar Jan 19 '24 07:01 aburok

I have finally managed to make it working: setting protocol to http/protobuf and setting the endpoint to OTEL_EXPORTER_OTLP_ENDPOINT=http://opentelemetry_collector:4318/v1/traces did the trick.

aburok avatar Jan 19 '24 07:01 aburok

Closing this issue as the issue is resolved. Please reopen/create a new one, if further help is needed.

cijothomas avatar Feb 09 '24 21:02 cijothomas