---
title: "Automatic Instrumentation"
description: "Learn what transactions are captured after tracing is enabled."
url: https://docs.sentry.io/platforms/dotnet/guides/aspnet/tracing/instrumentation/automatic-instrumentation/
---

# Automatic Instrumentation | Sentry for ASP.NET

## [Propagating a Trace](https://docs.sentry.io/platforms/dotnet/guides/aspnet/tracing/instrumentation/automatic-instrumentation.md#propagating-a-trace)

If you are using Sentry's ASP.NET Core integration, trace propagation is enabled automatically on all clients created by an HTTP client factory. Read more about it [here](https://docs.sentry.io/platforms/dotnet/guides/aspnetcore/tracing/instrumentation/automatic-instrumentation.md).

Sentry SDK provides a custom HTTP handler, `SentryHttpMessageHandler`. This handler can be used inside `HttpClient` to automatically propagate traces and create spans to track outgoing requests.

To use it, create an instance of `HttpClient` by passing an instance of `SentryHttpMessageHandler` as a constructor parameter:

```csharp
var httpHandler = new SentryHttpMessageHandler();
var httpClient = new HttpClient(httpHandler);

var response = await httpClient.GetStringAsync("https://example.com");
```

Upon sending a request to `https://example.com`, the instrumented HTTP client will:

* Populate the `sentry-trace` header on the request. This allows peer service to start a transaction by linking it to the current (assuming it's also instrumented with Sentry).
* Start a span named `GET https://example.com` which will track the corresponding HTTP operation on the current transaction.

To avoid depleting performance quota, Sentry will only create request spans if there's an active transaction on the scope. If there's no active transaction, you'll need to create one before making an HTTP request for request tracing to work:

```csharp
  var transaction = SentrySdk.StartTransaction("tutorial", "example");
  SentrySdk.ConfigureScope(scope => scope.Transaction = transaction);

  // The SentryHttpMessageHandler will automatically create a span for the request
  var response = await httpClient.GetStringAsync("https://example.com");

  transaction.Finish();
```

Additionally, `SentryHttpMessageHandler` also inherits from `DelegatingHandler` which allows you to chain it together with other handlers. For example:

```csharp
var innerHttpHandler = new HttpClientHandler();
var sentryHttpHandler = new SentryHttpMessageHandler(innerHttpHandler);
var httpClient = new HttpClient(sentryHttpHandler);
```

## [DiagnosticSource Integration](https://docs.sentry.io/platforms/dotnet/guides/aspnet/tracing/instrumentation/automatic-instrumentation.md#diagnosticsource-integration)

Starting with version 3.9.0, the SDK automatically integrates with Entity Framework Core and SQLClient whenever available. Those integrations are automatically activated if your project matches one of the following conditions:

* Includes `Sentry.AspNet` 3.9.0 or higher
* Includes `Sentry.AspNetCore` 3.9.0 or higher
* Includes `Sentry` 3.9.0 and targets .NET Core 3.0 or higher (for example, .NET 5)

If you don't want to have this integration, you can disable it on `SentryOptions` by calling `DisableDiagnosticSourceIntegration();`

```csharp
options.DisableDiagnosticSourceIntegration();
```

If your project doesn't match any of the conditions above, (for example, it targets .NET Framework 4.6.1 and uses only the `Sentry` package), you can still manually activate those instrumentations by including the package `Sentry.DiagnosticSource` and enabling it during on the SDK's initialization.

```csharp
// Requires NuGet package: Sentry.DiagnosticSource
options.AddDiagnosticSourceIntegration();
```

### [Entity Framework Core Integration](https://docs.sentry.io/platforms/dotnet/guides/aspnet/tracing/instrumentation/automatic-instrumentation.md#entity-framework-core-integration)

This integration is part of the `DiagnosticSource` integration and will automatically create spans for EF Core queries for the following operations:

`Query compiling`

Occurs when EF Core optimizes a query. It then caches it so that future queries with the same input get reused. The parameters for this span are:

* Operation: `db.query_compiler`

* Description: The query to be compiled

`Database connection`

Represents the lifecycle of a database connection. One connection may contain one or more query execution spans, and, in some circumstances, may not be registered, due to the nature of the EF Core event model. The parameters for this span are:

* Operation: `db.connection`

`Query Execution`

Happens during the execution of a query. It represents how long a query took to be executed The parameters for this span are:

* Operation: `db.query`

* Description: The query to be executed.

### [SQLClient Integration](https://docs.sentry.io/platforms/dotnet/guides/aspnet/tracing/instrumentation/automatic-instrumentation.md#sqlclient-integration)

This integration is part of the DiagnosticSource integration and will automatically create spans for SQLClient operations, the integrated operations are:

`Database connection`

Represents the lifecycle of a database connection. One connection may contain one or more query execution spans. The parameters for this span are:

* Operation: `db.connection`

* `db.connection_id`: The Connection ID from the connection.

* `db.operation_id`: The Operation ID from the connection.

* `rows_sent`: The number of rows sent during the connection.

* `bytes_received`: The amount of data (in bytes) received during the connection.

* `bytes_sent`: The amount of data (in bytes) sent during the connection.

`Query Execution`

Happens during the execution of a query. It represents how long a query took to be executed. The parameters for this span are:

* Operation: `db.query`

* Description: The query to be executed.

* `db.operation_id`: The Operation ID from the connection.
