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. 🤝

https://opentelemetry.io/
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:

Create a Web API project

Create a new .NET Core Web API project by using the Windows command prompt.

dotnet new webapi -n WeatherApi
Command to create new empty web api application

Open 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>
OpenTracing NuGet packages

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.json

When 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();
            });
        }
Startup.cs configure OpenTelemetry 

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/zipkin
Run Zipkin inside Docker locally

After executing commands you can open Zipkin user interface http://localhost:9411/zipkin/.

Zipkin user interface

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 🎉.

Zipkin sample tracing list

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();
Startup.cs HttpClient configuration

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/");
        }
    }
}
WeatherForecastController code

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! 🚀

Tracing details with Weather API call

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

[eof]