This repository contains an example about how to use opentelemetry for tracing when we have a bunch of distributed applications
The repository contains the following applications:
-
App1.WebApi is a NET 8 API with 2 endpoints.
- The /http endpoint makes an HTTP request to the App2 "/dummy" endpoint.
- The /publish-message endpoint queues a message into a Rabbit queue named "sample".
-
App2.RabbitConsumer.Console is a NET 8 console application.
- Dequeues messages from the Rabbit "sample" queue and makes a HTTP request to the App3 "/sql-to-event" endpoint with the content of the message.
-
App3.WebApi is a NET 8 Minimal API with 2 endpoints
- The /dummy endpoint returns a fixed "Ok" response.
- The /sql-to-event endpoint receives a message via HTTP POST, stores it in a MSSQL Server and afterwards publishes the message as an event into a RabbitMq queue named "sample_2".
-
App4.RabbitConsumer.HostedService is a NET 8 Worker Service.
- A Hosted Service reads the messages from the Rabbitmq "sample_2" queue and stores it into a Redis cache database.
The apps are using the following package versions:
<PackageReference Include="OpenTelemetry" Version="1.8.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.8.1" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.8.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.8.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.8.1" />
<PackageReference Include="OpenTelemetry.Instrumentation.SqlClient" Version="1.8.0-beta.1" />
<PackageReference Include="ZiggyCreatures.FusionCache.OpenTelemetry" Version="1.0.0" />- Jaeger
- MSSQL Server
- RabbitMq
- Redis Cache
The repository contains a docker-compose file that starts up the 4 apps and also the external dependencies.
There is a little caveat in the docker-compose:
- You can control the order of service startup and shutdown with the depends_on option. However, for startup Compose does not wait until a container is “ready” only until it’s running.
That's a problem because both App3 and App4 need to wait for the rabbitMq container to be ready. To avoid this problem the docker-compose is overwriting the "entrypoint" for both apps and executing a shell script that makes both apps sleep 30 seconds before starting up.
If you don't want to use the docker-compose file, you can use docker to start the dependencies one by one.
- Run a Jaeger image:
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-e COLLECTOR_OTLP_ENABLED=true \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
-p 14250:14250 \
-p 14268:14268 \
-p 14269:14269 \
-p 9411:9411 \
jaegertracing/all-in-one:latest- Run a Rabbitmq image:
docker run -d --name some-rabbit \
-p 15672:15672 \
-p 5672:5672 \
rabbitmq:3.13.1-management- Run a MSSQL Server
docker run -e "ACCEPT_EULA=Y" \
-e "SA_PASSWORD=Pass@Word1" \
-p 1433:1433 \
-d mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04- Run a Redis immage:
docker run -d --name some-redis \
-p "6379:6379" \
redis:7.2.4If you open Jaeger, you are going to see something like this
- Updated apps to .NET 8.
- Updated
OpenTelemetrypackages to the latest available version. This update also addresses several known security vulnerabilities. - Updated
System.Data.SqlClientto the latest available version to mitigate known security vulnerabilities. - From this point forward,
App 1will function as a .NET 8 API that utilizes Controllers, whileApp 3will operate as a minimal API without controllers. - Deleted
Startup.csfrom both App 1 and App 3. App 1andApp 3now employ the newerWebApplication.CreateBuildermethod for application construction, replacing the previousWebHost.CreateDefaultBuildermethod.App 4now utilizes the newerHost.CreateApplicationBuildermethod to construct aHost, replacing the previousHost.CreateDefaultBuildermethod.- Implemented the C# 12 primary constructor feature across all apps.
- Updated Dockerfile base image from
Bullseyedistro (Debian 11) toBookwormdistro (Debian 12). App 4now employs the FusionCache library with a Redis Backplane, replacing the use ofIDistributedCache.- Updated the
docker-composefile to utilize the latest image versions of RabbitMQ, Redis, and Jaeger.
- Updated apps to .NET 7.
- Updated
OpenTelemetrypackages to the latest version. - Fix breaking changes on the apps due to the
OpenTelemetrypackages upgrade. - Removed the
OpenTelemetry.Exporter.JaegerNuGet package from the apps because it has been deprecated. It has been replaced by theOpenTelemetry.Exporter.OpenTelemetryProtocolpackage. - Updated the
RabbitMQ.ClientNuGet package to the latest version. - Updated the
docker-composefile to use the newest image versions of rabbitmq, redis and jaeger. Also the jaeger image is configured so can it can receive OpenTelemetry trace data via the OpenTelemetry Protocol.

