Table of Contents
The following tutorials have demonstrated the best practices for using traces with OpenTelemetry .NET:
✔️ 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.
🛑 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");
✔️ 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);
}
}
🛑 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
:
- If you are building an application with dependency injection
(DI)
(e.g. ASP.NET Core and .NET
Worker), in most
cases you should create the
TracerProvider
instance and let DI manage its lifecycle. Refer to the Getting Started with OpenTelemetry .NET Traces in 5 Minutes - ASP.NET Core Application tutorial to learn more. - If you are building an application without DI, create a
TracerProvider
instance and manage the lifecycle explicitly. Refer to the Getting Started with OpenTelemetry .NET Traces in 5 Minutes - Console Application tutorial to learn more. - If you forget to dispose the
TracerProvider
instance before the application ends, activities might get dropped due to the lack of proper flush. - If you dispose the
TracerProvider
instance too early, any subsequent activities will not be collected.
In OpenTelemetry, traces are automatically correlated to logs and can be correlated to metrics via exemplars.
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.
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.
- The
ActivitySource
used to create theActivity
is not added to theTracerProvider
. UseAddSource
method to enable the activity from a givenActivitySource
. TracerProvider
is disposed too early. You need to ensure that theTracerProvider
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, useAddOpenTelemetry
andWithTraces
methods from theOpenTelemetry.Extensions.Hosting
package to correctly setupTracerProvider
. Here is a sample ASP.NET Core app for reference. For simpler applications such as Console apps, refer to this example.- TODO: Sampling