Skip to content

Commit ebb3524

Browse files
authored
Improve tracing doc (#5310)
1 parent a31bca8 commit ebb3524

File tree

1 file changed

+114
-14
lines changed

1 file changed

+114
-14
lines changed

Diff for: docs/trace/README.md

+114-14
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,119 @@
11
# OpenTelemetry .NET Traces
22

3+
<!-- markdownlint-disable MD033 -->
4+
<details>
5+
<summary>Table of Contents</summary>
6+
7+
* [Best Practices](#best-practices)
8+
* [Package Version](#package-version)
9+
* [Tracing API](#tracing-api)
10+
* [TracerProvider Management](#tracerprovider-management)
11+
* [Correlation](#correlation)
12+
13+
</details>
14+
<!-- markdownlint-enable MD033 -->
15+
316
## Best Practices
417

5-
### ActivitySource should be singleton
18+
The following tutorials have demonstrated the best practices for while using
19+
traces with OpenTelemetry .NET:
20+
21+
* [Getting Started - ASP.NET Core
22+
Application](./getting-started-aspnetcore/README.md)
23+
* [Getting Started - Console Application](./getting-started-console/README.md)
24+
25+
## Package Version
26+
27+
:heavy_check_mark: You should always use the
28+
[System.Diagnostics.Activity](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity)
29+
APIs from the latest stable version of
30+
[System.Diagnostics.DiagnosticSource](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource/)
31+
package, regardless of the .NET runtime version being used:
32+
33+
* If you're using the latest stable version of [OpenTelemetry .NET
34+
SDK](../../src/OpenTelemetry/README.md), you don't have to worry about the
35+
version of `System.Diagnostics.DiagnosticSource` package because it is already
36+
taken care of for you via [package
37+
dependency](../../Directory.Packages.props).
38+
* The .NET runtime team is holding a high bar for backward compatibility on
39+
`System.Diagnostics.DiagnosticSource` even during major version bumps, so
40+
compatibility is not a concern here.
41+
42+
## Tracing API
43+
44+
:stop_sign: You should avoid creating
45+
[`ActivitySource`](https://learn.microsoft.com/dotnet/api/system.diagnostics.activitysource)
46+
too frequently. `ActivitySource` is fairly expensive and meant to be reused
47+
throughout the application. For most applications, it can be modeled as static
48+
readonly field (e.g. [Program.cs](./getting-started-console/Program.cs)) or
49+
singleton via dependency injection (e.g.
50+
[Instrumentation.cs](../../examples/AspNetCore/Instrumentation.cs)).
51+
52+
:heavy_check_mark: You should use dot-separated
53+
[UpperCamelCase](https://en.wikipedia.org/wiki/Camel_case) as the
54+
[`ActivitySource.Name`](https://learn.microsoft.com/dotnet/api/system.diagnostics.activitysource.name).
55+
In many cases, using the fully qualified class name might be a good option.
56+
57+
```csharp
58+
static readonly ActivitySource MyActivitySource = new("MyCompany.MyProduct.MyLibrary");
59+
```
60+
61+
:heavy_check_mark: You should check
62+
[`Activity.IsAllDataRequested`](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.isalldatarequested)
63+
before [setting
64+
Tags](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.settag)
65+
for better performance.
66+
67+
```csharp
68+
using (var activity = MyActivitySource.StartActivity("SayHello"))
69+
{
70+
if (activity != null && activity.IsAllDataRequested == true)
71+
{
72+
activity.SetTag("http.url", "http://www.mywebsite.com");
73+
}
74+
}
75+
```
76+
77+
:heavy_check_mark: You should use
78+
[Activity.SetTag](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.settag)
79+
to [set
80+
attributes](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-attributes).
81+
82+
## TracerProvider Management
83+
84+
:stop_sign: You should avoid creating `TracerProvider` instances too frequently,
85+
`TracerProvider` is fairly expensive and meant to be reused throughout the
86+
application. For most applications, one `TracerProvider` instance per process
87+
would be sufficient.
88+
89+
:heavy_check_mark: You should properly manage the lifecycle of `TracerProvider`
90+
instances if they are created by you.
91+
92+
Here is the rule of thumb when managing the lifecycle of `TracerProvider`:
93+
94+
* If you are building an application with [dependency injection
95+
(DI)](https://learn.microsoft.com/dotnet/core/extensions/dependency-injection)
96+
(e.g. [ASP.NET Core](https://learn.microsoft.com/aspnet/core) and [.NET
97+
Worker](https://learn.microsoft.com/dotnet/core/extensions/workers)), in most
98+
cases you should create the `TracerProvider` instance and let DI manage its
99+
lifecycle. Refer to the [Getting Started with OpenTelemetry .NET Traces in 5
100+
Minutes - ASP.NET Core Application](./getting-started-aspnetcore/README.md)
101+
tutorial to learn more.
102+
* If you are building an application without DI, create a `TracerProvider`
103+
instance and manage the lifecycle explicitly. Refer to the [Getting Started
104+
with OpenTelemetry .NET Traces in 5 Minutes - Console
105+
Application](./getting-started-console/README.md) tutorial to learn more.
106+
* If you forget to dispose the `TracerProvider` instance before the application
107+
ends, activities might get dropped due to the lack of proper flush.
108+
* If you dispose the `TracerProvider` instance too early, any subsequent
109+
activities will not be collected.
110+
111+
## Correlation
6112

7-
`ActivitySource` SHOULD only be created once and reused throughout the
8-
application lifetime. This
9-
[example](./getting-started-console/Program.cs) shows how
10-
`ActivitySource` is created as a `static` field and then used in the
11-
application. You could also look at this ASP.NET Core
12-
[example](../../examples/AspNetCore/Program.cs) which shows a more Dependency
13-
Injection friendly way of doing this by extracting the `ActivitySource` into a
14-
dedicated class called
15-
[Instrumentation](../../examples/AspNetCore/Instrumentation.cs) which is then
16-
added as a `Singleton` service.
113+
In OpenTelemetry, traces are automatically [correlated to
114+
logs](../logs/README.md#log-correlation) and can be [correlated to
115+
metrics](../metrics/README.md#metrics-correlation) via
116+
[exemplars](../metrics/exemplars/README.md).
17117

18118
### Manually creating Activities
19119

@@ -41,10 +141,10 @@ examples.
41141

42142
## Common issues that lead to missing traces
43143

44-
- The `ActivitySource` used to create the `Activity` is not added to the
144+
* The `ActivitySource` used to create the `Activity` is not added to the
45145
`TracerProvider`. Use `AddSource` method to enable the activity from a given
46146
`ActivitySource`.
47-
- `TracerProvider` is disposed too early. You need to ensure that the
147+
* `TracerProvider` is disposed too early. You need to ensure that the
48148
`TracerProvider` instance is kept active for traces to be collected. In a
49149
typical application, a single TracerProvider is built at application startup,
50150
and is disposed of at application shutdown. For an ASP.NET Core application,
@@ -54,4 +154,4 @@ examples.
54154
app](../../examples/AspNetCore/Program.cs) for reference. For simpler
55155
applications such as Console apps, refer to this
56156
[example](../../docs/trace/getting-started-console/Program.cs).
57-
- TODO: Sampling
157+
* TODO: Sampling

0 commit comments

Comments
 (0)