1
1
# OpenTelemetry .NET Traces
2
2
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
+
3
16
## Best Practices
4
17
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
6
112
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 ) .
17
117
18
118
### Manually creating Activities
19
119
@@ -41,10 +141,10 @@ examples.
41
141
42
142
## Common issues that lead to missing traces
43
143
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
45
145
` TracerProvider ` . Use ` AddSource ` method to enable the activity from a given
46
146
` 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
48
148
` TracerProvider ` instance is kept active for traces to be collected. In a
49
149
typical application, a single TracerProvider is built at application startup,
50
150
and is disposed of at application shutdown. For an ASP.NET Core application,
@@ -54,4 +154,4 @@ examples.
54
154
app] ( ../../examples/AspNetCore/Program.cs ) for reference. For simpler
55
155
applications such as Console apps, refer to this
56
156
[ example] ( ../../docs/trace/getting-started-console/Program.cs ) .
57
- - TODO: Sampling
157
+ * TODO: Sampling
0 commit comments