-
Notifications
You must be signed in to change notification settings - Fork 411
Expand file tree
/
Copy pathREADME.md
More file actions
277 lines (221 loc) · 11.1 KB
/
Copy pathREADME.md
File metadata and controls
277 lines (221 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# SqlClient Instrumentation for OpenTelemetry
[](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient)
[](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient)
[](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.SqlClient)
This is an [Instrumentation
Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library),
which instruments
[Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient)
and
[System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient)
and collects traces about database operations.
> [!WARNING]
> Instrumentation is not working with `Microsoft.Data.SqlClient` v3.* due to
the [issue](https://github.com/dotnet/SqlClient/pull/1258). It was fixed in 4.0
and later.
<!-- This comment is to make sure the two notes above and below are not merged -->
> [!CAUTION]
> This component is based on the OpenTelemetry semantic conventions for
[traces](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md).
These conventions are
[Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md),
and hence, this package is a [pre-release](../../VERSIONING.md#pre-releases).
Until a [stable
version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md)
is released, there can be breaking changes. You can track the progress from
[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23).
## Steps to enable OpenTelemetry.Instrumentation.SqlClient
### Step 1: Install Package
Add a reference to the
[`OpenTelemetry.Instrumentation.SqlClient`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient)
package. Also, add any other instrumentations & exporters you will need.
```shell
dotnet add package --prerelease OpenTelemetry.Instrumentation.SqlClient
```
### Step 2: Enable SqlClient Instrumentation at application startup
SqlClient instrumentation must be enabled at application startup.
The following example demonstrates adding SqlClient instrumentation to a console
application. This example also sets up the OpenTelemetry Console exporter, which
requires adding the package
[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md)
to the application.
```csharp
using OpenTelemetry.Trace;
public class Program
{
public static void Main(string[] args)
{
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSqlClientInstrumentation()
.AddConsoleExporter()
.Build();
}
}
```
For an ASP.NET Core application, adding instrumentation is typically done in the
`ConfigureServices` of your `Startup` class. Refer to documentation for
[OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md).
For an ASP.NET application, adding instrumentation is typically done in the
`Global.asax.cs`. Refer to the documentation for
[OpenTelemetry.Instrumentation.AspNet](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.AspNet/README.md).
## Advanced configuration
This instrumentation can be configured to change the default behavior by using
`SqlClientTraceInstrumentationOptions`.
### Capturing database statements
The `SqlClientTraceInstrumentationOptions` class exposes two properties that can
be used to configure how the
[`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes)
attribute is captured upon execution of a query but the behavior depends on the
runtime used.
#### .NET and .NET Core
On .NET and .NET Core, two properties are available:
`SetDbStatementForStoredProcedure` and `SetDbStatementForText`. These properties
control capturing of `CommandType.StoredProcedure` and `CommandType.Text`
respectively.
`SetDbStatementForStoredProcedure` is _true_ by default and will set
[`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes)
attribute to the stored procedure command name.
`SetDbStatementForText` is _false_ by default (to prevent accidental capture of
sensitive data that might be part of the SQL statement text). When set to
`true`, the instrumentation will set
[`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes)
attribute to the text of the SQL command being executed.
To disable capturing stored procedure commands use configuration like below.
```csharp
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSqlClientInstrumentation(
options => options.SetDbStatementForStoredProcedure = false)
.AddConsoleExporter()
.Build();
```
To enable capturing of `sqlCommand.CommandText` for `CommandType.Text` use the
following configuration.
```csharp
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSqlClientInstrumentation(
options => options.SetDbStatementForText = true)
.AddConsoleExporter()
.Build();
```
#### .NET Framework
On .NET Framework, the `SetDbStatementForText` property controls whether or not
this instrumentation will set the
[`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes)
attribute to the text of the `SqlCommand` being executed. This could either be
the name of a stored procedure (when `CommandType.StoredProcedure` is used) or
the full text of a `CommandType.Text` query. `SetDbStatementForStoredProcedure`
is ignored because on .NET Framework there is no way to determine the type of
command being executed.
Since `CommandType.Text` might contain sensitive data, all SQL capturing is
_disabled_ by default to protect against accidentally sending full query text to
a telemetry backend. If you are only using stored procedures or have no
sensitive data in your `sqlCommand.CommandText`, you can enable SQL capturing
using the options like below:
```csharp
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSqlClientInstrumentation(
options => options.SetDbStatementForText = true)
.AddConsoleExporter()
.Build();
```
> [!NOTE]
> When using the built-in `System.Data.SqlClient` only stored procedure
command names will ever be captured. When using the `Microsoft.Data.SqlClient`
NuGet package (v1.1+) stored procedure command names, full query text, and other
command text will be captured.
### EnableConnectionLevelAttributes
> [!NOTE]
> EnableConnectionLevelAttributes is supported on all runtimes.
By default, `EnabledConnectionLevelAttributes` is disabled and this
instrumentation sets the `peer.service` attribute to the
[`DataSource`](https://docs.microsoft.com/dotnet/api/system.data.common.dbconnection.datasource)
property of the connection. If `EnabledConnectionLevelAttributes` is enabled,
the `DataSource` will be parsed and the server name will be sent as the
`net.peer.name` or `net.peer.ip` attribute, the instance name will be sent as
the `db.mssql.instance_name` attribute, and the port will be sent as the
`net.peer.port` attribute if it is not 1433 (the default port).
The following example shows how to use `EnableConnectionLevelAttributes`.
```csharp
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSqlClientInstrumentation(
options => options.EnableConnectionLevelAttributes = true)
.AddConsoleExporter()
.Build();
```
### Enrich
> [!NOTE]
> Enrich is supported on .NET and .NET Core runtimes only.
This option can be used to enrich the activity with additional information from
the raw `SqlCommand` object. The `Enrich` action is called only when
`activity.IsAllDataRequested` is `true`. It contains the activity itself (which
can be enriched), the name of the event, and the actual raw object.
Currently there is only one event name reported, "OnCustom". The actual object
is `Microsoft.Data.SqlClient.SqlCommand` for `Microsoft.Data.SqlClient` and
`System.Data.SqlClient.SqlCommand` for `System.Data.SqlClient`.
The following code snippet shows how to add additional tags using `Enrich`.
```csharp
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSqlClientInstrumentation(opt => opt.Enrich
= (activity, eventName, rawObject) =>
{
if (eventName.Equals("OnCustom"))
{
if (rawObject is SqlCommand cmd)
{
activity.SetTag("db.commandTimeout", cmd.CommandTimeout);
}
};
})
.Build();
```
[Processor](../../docs/trace/extending-the-sdk/README.md#processor), is the
general extensibility point to add additional properties to any activity. The
`Enrich` option is specific to this instrumentation, and is provided to get
access to `SqlCommand` object.
### RecordException
> [!NOTE]
> RecordException is supported on .NET and .NET Core runtimes only.
This option can be set to instruct the instrumentation to record SqlExceptions
as Activity
[events](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md).
The default value is `false` and can be changed by the code like below.
```csharp
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSqlClientInstrumentation(
options => options.RecordException = true)
.AddConsoleExporter()
.Build();
```
### Filter
> [!NOTE]
> Filter is supported on .NET and .NET Core runtimes only.
This option can be used to filter out activities based on the properties of the
`SqlCommand` object being instrumented using a `Func<object, bool>`. The
function receives an instance of the raw `SqlCommand` and should return `true`
if the telemetry is to be collected, and `false` if it should not. The parameter
of the Func delegate is of type `object` and needs to be cast to the appropriate
type of `SqlCommand`, either `Microsoft.Data.SqlClient.SqlCommand` or
`System.Data.SqlClient.SqlCommand`. The example below filters out all commands
that are not stored procedures.
```csharp
using var traceProvider = Sdk.CreateTracerProviderBuilder()
.AddSqlClientInstrumentation(
opt =>
{
opt.Filter = cmd =>
{
if (cmd is SqlCommand command)
{
return command.CommandType == CommandType.StoredProcedure;
}
return false;
};
})
.AddConsoleExporter()
.Build();
{
```
## References
* [OpenTelemetry Project](https://opentelemetry.io/)
* [OpenTelemetry semantic conventions for database
calls](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md)