I have been experimenting with using opentelemetry this week and I would appreciate some advice.
I have instrumented an .net Core API application written in C# with the following opentelemetry libraries and initially installed Jaeger to collect and display the results. I have jaeger running in a docker container on my local machine.
The code I added to ConfigureServices in the StartUp.cs file is as follows:
services.AddOpenTelemetryTracing(builder =>
{
builder.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddSqlClientInstrumentation()
.AddSource(nameof(CORSBaseController))
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyAppAPI"))
.AddJaegerExporter(opts =>
{
opts.AgentHost = Configuration["Jaeger:AgentHost"];
opts.AgentPort = Convert.ToInt32(Configuration["Jaeger:AgentPort"]);
});
});
In the Jaeger front end when I search for traces received in the past hour I get two listed services after using the front end that connects to the API 'jaeger-query' and 'MyAppAPI'. I can drill into the 'MyAppAPI' and see the spans showing the telemetry data that has been collected. So far so good.
I installed the opentelemetry-collector-contrib on my machine. I used the contrib as I eventually want to export the results into newrelic and need their library. I started the controller using docker using the example docker-compose yaml file:
version: "3"
services:
# Jaeger
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686"
- "14268"
- "14250"
#Zipkin
zipkin:
image: openzipkin/zipkin
container_name: zipkin
ports:
- 9411:9411
otel-collector:
build:
context: ../..
dockerfile: examples/tracing/Dockerfile
command: ["--config=/etc/otel-collector-config.yml"]
volumes:
- ./otel-collector-config.yml:/etc/otel-collector-config.yml
ports:
- "1888:1888" # pprof extension
- "8888:8888" # Prometheus metrics exposed by the collector
- "8889:8889" # Prometheus exporter metrics
- "13133:13133" # health_check extension
- "9411" # Zipkin receiver
- "55679:55679" # zpages extension
depends_on:
- jaeger
- zipkin
# Expose the frontend on http://localhost:8081
frontend:
image: openzipkin/example-sleuth-webmvc
command: Frontend
environment:
JAVA_OPTS: -Dspring.zipkin.baseUrl=http://otel-collector:9511
ports:
- 8081:8081
depends_on:
- otel-collector
# Expose the backend on http://localhost:9000
backend:
image: openzipkin/example-sleuth-webmvc
command: Backend
environment:
JAVA_OPTS: -Dspring.zipkin.baseUrl=http://otel-collector:9511
ports:
- 9000:9000
depends_on:
- otel-collector
The otel-collector-config.yml file referenced in the docker compose file looks like the following exposing both 'otlp' and 'zipkin' as receivers.
receivers:
otlp:
protocols:
grpc:
zipkin:
exporters:
logging:
zipkin:
endpoint: "http://zipkin:9411/api/v2/spans"
processors:
batch:
extensions:
health_check:
pprof:
zpages:
service:
extensions: [pprof, zpages, health_check]
pipelines:
traces:
receivers: [otlp, zipkin]
exporters: [zipkin, logging]
processors: [batch]
I altered my code in my .Net project to the following to use the otlp exporter sending data to the collector as follows:
services.AddOpenTelemetryTracing(builder =>
{
builder.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddSqlClientInstrumentation()
.AddAspNetCoreInstrumentation()
.AddSource(nameof(CORSBaseController))
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyAppAPI"))
.AddZipkinExporter(opts =>
{
opts.Endpoint = new Uri("http://localhost:9411/api/v2/spans");
});
});
Now when I use my front end to send requests to the API and can no longer see the MyAppAPI as one of the services in jaeger (should have been using zipkin). All I can see is the jaeger-query spans that correspond with the time I am using the front end.
Edit: I have got this working. It was due to an incorrect call in the startup.cs file to the zipkin collector. Plus when I wrote out the question I realised I was exporting to zipkin not jaeger, so I can now see my traces in the zipkin front end on http://localhost:9411.
The code above has been corrected so it works.