SerilogTracing is a tracing client alternative to the OpenTelemetry SDK. It integrates Serilog with the System.Diagnostics.Activity types provided by the .NET base class library. This makes it possible to:

  • Record traces generated by .NET system libraries and packages through any Serilog sink
  • Generate rich traces using Serilog APIs and idioms, that can still be observed by other consumers of the .NET APIs

See the sample application for a working example.

Installing SerilogTracing

The following setup configures SerilogTracing for logging and tracing.

At the terminal, or in the Visual Studio Package Manager Console, type:

dotnet add package SerilogTracing --prerelease
dotnet add package SerilogTracing.Expressions --prerelease
dotnet add package SerilogTracing.Instrumentation.AspNetCore --prerelease
dotnet add package SerilogTracing.Instrumentation.SqlClient --prerelease
dotnet add package SerilogTracing.Sinks.Seq --prerelease
dotnet add package Serilog.Sinks.Console

Then, configure the logger. If you installed Seq to the default port you can use http://your-seq-server:5341 as the Seq address; if you configured Seq to listen on a different port or hostname, enter those details in the WriteTo.SeqTracing() line.

using Serilog;
using Serilog.Events;
using Serilog.Templates.Themes;
using SerilogTracing;
using SerilogTracing.Expressions;
using SerilogTracing.Sinks.OpenTelemetry;

Log.Logger = new LoggerConfiguration()
    .Enrich.WithProperty("Application", typeof(Program).Assembly.GetName().Name)
      apiKey: "yeEZyL3SMcxEKUijBjN")

// External trace sources will be enabled until the returned handle is disposed.
using var _ = new ActivityListenerConfiguration()
// Important to call at exit so that batched events are flushed.

Setting the Application property is important because it makes distributed traces easier to interpret in Seq.

Using SerilogTracing

SerilogTracing automatically produces logs and traces for ASP.NET Core and HttpClient. Manually generate spans using extension methods on ILogger:

using var activity = Log.Logger.StartActivity("Compute {A} + {B}", a, b);
// ... on `Dispose()` the activity will be recorded as a span

Activities are represented by LoggerActivity instances.

LoggerActivity has a simple lifetime:

  • The activity is started using one of the ILogger.StartActivity() extensions,
  • Properties are added to the activity using LoggerActivity.AddProperty(), and
  • The activity is completed either implicitly, by IDisposable.Dispose(), or explicitly using LoggerActivity.Complete().

LoggerActivity.Complete() accepts optional LogEventLevel and Exception arguments.

Generate log events in the usual Serilog way:

Log.Information("Hello, {Name}!", Environment.UserName);