When you create distributed services you have to find tools and libraries which will help you collect and visualize steps your service produces. If you have only one service it is quite easy just write logs using .NET Core build-in logging. When you have to call multiple external services than all steps between multiple services have to be somehow correlated. To solve this task distributed tracing comes to help us, also known as end-to-end tracing.💡
Exists project calls OpenTracing. OpenTracing is vendor-neutral APIs and instrumentation for distributed tracing. This project is a Cloud Native Computing Foundation sandbox project. Not so long time ago two projects OpenCensus and OpenTracing have merged to form OpenTelemetry. 🤝

OpenTelemetry provides a single set of APIs, libraries, agents, and collector services to capture distributed traces and metrics from your application. You can analyze them using Prometheus, Jaeger, and other observability tools..
You can follow OpenTelemetry project status here https://opentelemetry.io/project-status/. Current version for .NET Core is 0.2.0-alpha.
In the following steps, I will try to build a simple example project to show how you can use OpenTelemetry libraries and Zipkin distributed tracing system.
Build steps:
- Install prerequisite tools
- Create a Web API project
- Run Zipkin using Docker
- Call and trace external Weather API
Prerequisites 🔨
Tools you have to install before create this example project:
- Docker - https://docs.docker.com/install/
- .NET Core 3.1 SDK - https://dotnet.microsoft.com/download/dotnet-core/3.1
- Visual Studio Code - https://code.visualstudio.com/
Create a Web API project
Create a new .NET Core Web API project by using the Windows command prompt.
dotnet new webapi -n WeatherApiOpen newly created application using Visual Studio Code by File -> Open Folder.
Add OpenTelemetry NuGet packages 📦
Open file WeatherApi.csproj and add several elements.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<!--OpenTelemetry packages from https://www.myget.org/F/opentelemetry/api/v3/index.json-->
<PackageReference Include="OpenTelemetry.Collector.AspNetCore" Version="0.2.0-alpha.222" />
<PackageReference Include="OpenTelemetry.Collector.Dependencies" Version="0.2.0-alpha.222" />
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" Version="0.2.0-alpha.222" />
<PackageReference Include="OpenTelemetry.Hosting" Version="0.2.0-alpha.222" />
</ItemGroup>
</Project>
After saving WeatherApi.csproj file you have to restore packages by executing the following command. You have to specify -s argument because OpenTelemetry packages are published not in https://nuget.org.
dotnet restore -s https://www.myget.org/F/opentelemetry/api/v3/index.jsonWhen packages restore completed you are ready to use OpenTelemetry libraries. 🎉
Configure OpenTelemetry 🔧
Inside Startup.cs file method ConfigureServices need to add OpenTelemetry configuration code. The configuration contains sampler AlwaysOnSampler which means that all steps will be sent to Zipkin.
using OpenTelemetry.Trace.Samplers;
using OpenTelemetry.Trace.Configuration;
namespace WeatherApi
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddOpenTelemetry(builder =>
{
builder
.SetSampler(new AlwaysOnSampler())
.UseZipkin(options =>
{
options.ServiceName = "WeatherApi";
})
.AddRequestCollector()
.AddDependencyCollector();
});
}Run Zipkin using Docker
To run Zipkin on your local machine using Docker you have to pull and run by executing commands. ⚙️
docker pull openzipkin/zipkin
docker run -d -p 9411:9411 openzipkin/zipkinAfter executing commands you can open Zipkin user interface http://localhost:9411/zipkin/.

Press button Try Lens UI it switches to a more modern and user-friendly mode of Zipkin.
Then try to run you WeatherApi using Visual Studio Code by pressing F5 and open address https://localhost:5001/weatherforecast, execute it multiple times 🤞. When you look at Zipkin you will see all requests are traced 🎉.

Call and trace external Weather API ⛅
I choose free Weather API https://www.metaweather.com/api/. By executing https://www.metaweather.com/api/location/565346/ you get weather Json.
Add Meta Weather API call
Modify Startup.cs file method ConfigureServices by enabling HttpClient services.AddHttpClient();.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHttpClient();Change controller code WeatherForecastController.cs by following.
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace WeatherApi.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly ILogger<WeatherForecastController> _logger;
private readonly IHttpClientFactory _clientFactory;
public WeatherForecastController(
ILogger<WeatherForecastController> logger,
IHttpClientFactory clientFactory)
{
_logger = logger;
_clientFactory = clientFactory;
}
[HttpGet]
public async Task<HttpResponseMessage> Get()
{
var client = _clientFactory.CreateClient();
client.BaseAddress = new Uri("https://www.metaweather.com");
return await client.GetAsync("/api/location/565346/");
}
}
}After you execute multiple times https://localhost:5001/weatherforecast you will see inside Zipkin child trace entries. Click on some to view details OpenTelemetry library produce for us. 😉

This is impressive that with few libraries we can get so much information out of the box. And all external calls of our Weather API also are traced and we can easily analyse each step of our service! 🚀

Happy tracing and performance analysis, amazing tools are coming! ⏱️
[eof]