Skip to content

Latest commit

 

History

History
196 lines (159 loc) · 8.29 KB

README.md

File metadata and controls

196 lines (159 loc) · 8.29 KB

OpenTelemetry .NET Traces

Table of Contents

Best Practices

The following tutorials have demonstrated the best practices for using traces with OpenTelemetry .NET:

Package Version

✔️ You should always use the System.Diagnostics.Activity APIs from the latest stable version of System.Diagnostics.DiagnosticSource package, regardless of the .NET runtime version being used:

  • If you are using the latest stable version of OpenTelemetry .NET SDK, you do not have to worry about the version of System.Diagnostics.DiagnosticSource package because it is already taken care of for you via package dependency.
  • The .NET runtime team is holding a high bar for backward compatibility on System.Diagnostics.DiagnosticSource even during major version bumps, so compatibility is not a concern here.

Tracing API

ActivitySource

🛑 You should avoid creating System.Diagnostics.ActivitySource too frequently. ActivitySource is fairly expensive and meant to be reused throughout the application. For most applications, it can be modeled as static readonly field (e.g. Program.cs) or singleton via dependency injection (e.g. Instrumentation.cs).

✔️ You should use dot-separated UpperCamelCase as the ActivitySource.Name. In many cases, using the fully qualified class name might be a good option.

static readonly ActivitySource MyActivitySource = new("MyCompany.MyProduct.MyLibrary");

Activity

✔️ You should check Activity.IsAllDataRequested before setting Tags for better performance.

using (var activity = MyActivitySource.StartActivity("SayHello"))
{
    if (activity != null && activity.IsAllDataRequested == true)
    {
        activity.SetTag("http.url", "http://www.mywebsite.com");
    }
}

✔️ You should use Activity.SetTag to set attributes.

✔️ You should finish/stop the activity properly. This can be done implicitly via a using statement, which is recommended. You can also explicitly call Activity.Dispose or Activity.Stop.

Note

Activities which are not yet finished/stopped will not be exported.

🛑 You should avoid calling Activity.AddEvent in a loop. Activities are not designed to handle hundreds or thousands of events, a better model is to use correlated logs or Activity.Links.

Warning

The following code is not modeling Activity.Events correctly, and is very likely to have usability and performance problems.

private static async Task Test()
{
    Activity activity = Activity.Current;

    while (true)
    {
        activity.AddEvent(new ActivityEvent("Processing background task."));
        await Task.Delay(1000);
    }
}

TracerProvider Management

🛑 You should avoid creating TracerProvider instances too frequently, TracerProvider is fairly expensive and meant to be reused throughout the application. For most applications, one TracerProvider instance per process would be sufficient.

✔️ You should properly manage the lifecycle of TracerProvider instances if they are created by you.

Here is the rule of thumb when managing the lifecycle of TracerProvider:

Correlation

In OpenTelemetry, traces are automatically correlated to logs and can be correlated to metrics via exemplars.

Manually creating Activities

As shown in the getting started guide, it is very easy to manually create Activity. Due to this, it can be tempting to create too many activities (eg: for each method call). In addition to being expensive, excessive activities can also make trace visualization harder. Instead of manually creating Activity, check if you can leverage instrumentation libraries, such as ASP.NET Core, HttpClient which will not only create and populate Activity with tags(attributes), but also take care of propagating/restoring the context across process boundaries. If the Activity produced by the instrumentation library is missing some information you need, it is generally recommended to enrich the existing Activity with that information, as opposed to creating a new one.

Modelling static tags as Resource

Tags such as MachineName, Environment etc. which are static throughout the process lifetime should be modelled as Resource, instead of adding them to each Activity. Refer to this doc for details and examples.

Common issues that lead to missing traces

  • The ActivitySource used to create the Activity is not added to the TracerProvider. Use AddSource method to enable the activity from a given ActivitySource.
  • TracerProvider is disposed too early. You need to ensure that the TracerProvider instance is kept active for traces to be collected. In a typical application, a single TracerProvider is built at application startup, and is disposed of at application shutdown. For an ASP.NET Core application, use AddOpenTelemetry and WithTraces methods from the OpenTelemetry.Extensions.Hosting package to correctly setup TracerProvider. Here is a sample ASP.NET Core app for reference. For simpler applications such as Console apps, refer to this example.
  • TODO: Sampling