

Version 4 (V4) of the AWS SDK for .NET has been released\$1

For information about breaking changes and migrating your applications, see the [migration topic](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html).

 [https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html)

# Observability
<a name="observability"></a>

Observability is the extent to which a system's current state can be inferred from the data it emits. The data emitted is commonly referred to as telemetry.

The AWS SDK for .NET can provide two common telemetry signals, metrics and traces, as well as logging. You can wire up a [TelemetryProvider](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/Runtime/TTelemetryProvider.html) to send telemetry data to an observability backend (such as [AWS X-Ray](https://docs.aws.amazon.com/xray/?icmpid=docs_homepage_devtools) or [Amazon CloudWatch](https://docs.aws.amazon.com/cloudwatch/?icmpid=docs_homepage_mgmtgov)) and then act on it.

By default, telemetry signals are disabled in the SDK. This topic explains how to enable and configure telemetry output.

## Additional resources
<a name="observability-resources"></a>

For more information about enabling and using observability, see the following resources:
+ [OpenTelemetry](https://opentelemetry.io/)
+ The blog post [Enhancing Observability in the AWS SDK for .NET with OpenTelemetry](https://aws.amazon.com/blogs/developer/enhancing-observability-in-the-aws-sdk-for-net-with-opentelemetry/).
+ The blog post [Announcing the general availability of AWS .NET OpenTelemetry libraries](https://aws.amazon.com/blogs/dotnet/announcing-the-general-availability-of-aws-net-opentelemetry-libraries/).
+ [Exporters for OpenTelemetry](https://opentelemetry.io/docs/languages/net/exporters/)
+ For examples of observability in the AWS Tools for PowerShell, see [Observability](https://docs.aws.amazon.com/powershell/latest/userguide/observability.html) in the [Tools for PowerShell User Guide](https://docs.aws.amazon.com/powershell/latest/userguide/).

## Configure a `TelemetryProvider`
<a name="observability-conf-telemetry-provider"></a>

You can configure a `TelemetryProvider` in your application globally for all service clients or for individual clients, as shown in the following examples. The [Telemetry providers](observability-telemetry-providers.md) section contains information about telemetry implementations, including information about implementations that are provided with the SDK.

### Configure the default global telemetry provider
<a name="observability-conf-telemetry-provider-global"></a>

By default, every service client attempts to use the globally available telemetry provider. This way, you can set the provider once, and all clients will use it. This should be done only once, before you create any service clients.

The following code snippet shows you how to set the global telemetry provider. It then creates an Amazon S3 service client and tries to perform an operation that fails. The code adds both tracing and metrics to the application. This code uses the following NuGet packages: `OpenTelemetry.Exporter.Console` and `OpenTelemetry.Instrumentation.AWS`.

**Note**  
If you're using AWS IAM Identity Center for authentication, be sure to also add `AWSSDK.SSO` and `AWSSDK.SSOOIDC`.

```
using Amazon.S3;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

Sdk.CreateTracerProviderBuilder()
    .ConfigureResource(e => e.AddService("DemoOtel"))
    .AddAWSInstrumentation()
    .AddConsoleExporter()
    .Build();

Sdk.CreateMeterProviderBuilder()
    .ConfigureResource(e => e.AddService("DemoOtel"))
    .AddAWSInstrumentation()
    .AddConsoleExporter()
    .Build();

var s3Client = new AmazonS3Client();

try
{
    var listBucketsResponse = await s3Client.ListBucketsAsync();
    // Attempt to delete a bucket that doesn't exist.
    var deleteBucketResponse = await s3Client.DeleteBucketAsync("amzn-s3-demo-bucket");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

Console.Read();
```

### Configure a telemetry provider for a specific service client
<a name="observability-conf-telemetry-provider-client"></a>

You can configure an individual service client with a specific telemetry provider (other than the global one). To do so, use the `TelemetryProvider` class of the Config object of a service client constructor. For example, see [AmazonS3Config](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TS3Config.html) and look for the `TelemetryProvider` property. See [Telemetry providers](observability-telemetry-providers.md) for information about custom telemetry implementations.

**Topics**
+ [

## Additional resources
](#observability-resources)
+ [

## Configure a `TelemetryProvider`
](#observability-conf-telemetry-provider)
+ [

# Metrics
](observability-metrics.md)
+ [

# Telemetry providers
](observability-telemetry-providers.md)

# Metrics
<a name="observability-metrics"></a>

The following table lists the telemetry metrics that the SDK emits. [Configure a telemetry provider](observability.md#observability-conf-telemetry-provider) to make the metrics observable.


**What metrics are emitted?**  

| Metric name | Units | Type | Attributes | Description | 
| --- | --- | --- | --- | --- | 
| client.call.duration | s | Histogram | rpc.service, rpc.method | Overall call duration (including retries and time to send or receive request and response body) | 
| client.uptime | s | Histogram | rpc.service | The amount of time since a client was created | 
| client.call.attempts | \$1attempt\$1 | MonotonicCounter | rpc.service, rpc.method | The number of attempts for an individual operation | 
| client.call.errors | \$1error\$1 | MonotonicCounter | rpc.service, rpc.method, exception.type | The number of errors for an operation | 
| client.call.attempt\$1duration | s | Histogram | rpc.service, rpc.method | The time it takes to connect to the service, send the request, and get back HTTP status code and headers (including time queued waiting to be sent) | 
| client.call.resolve\$1endpoint\$1duration | s | Histogram | rpc.service, rpc.method | The time it takes to resolve an endpoint (endpoint resolver, not DNS) for the request | 
| client.call.serialization\$1duration | s | Histogram | rpc.service, rpc.method | The time it takes to serialize a message body | 
| client.call.deserialization\$1duration | s | Histogram | rpc.service, rpc.method | The time it takes to deserialize a message body | 
| client.call.auth.signing\$1duration | s | Histogram | rpc.service, rpc.method | The time it takes to sign a request | 
| client.call.auth.resolve\$1identity\$1duration | s | Histogram | rpc.service, rpc.method | The time it takes to acquire an identity (such as AWS credentials or a bearer token) from an Identity Provider | 
| client.http.bytes\$1sent | By | MonotonicCounter | server.address | The total number of bytes sent by the HTTP client | 
| client.http.bytes\$1received | By | MonotonicCounter | server.address | The total number of bytes received by the HTTP client | 

Following are the column descriptions:
+ **Metric name**–The name of the emitted metric.
+ **Units**–The unit of measure for the metric. Units are given in the [UCUM](https://unitsofmeasure.org/ucum) case sensitive ("c/s") notation.
+ **Type**–The type of instrument used to capture the metric.
+ **Attributes**–The set of attributes (dimensions) emitted with the metric.
+ **Description**–A description of what the metric is measuring.

# Telemetry providers
<a name="observability-telemetry-providers"></a>

The SDK provides an implementation of [OpenTelemetry](https://opentelemetry.io/) as a telemetry provider, which is described in the [next section](observability-telemetry-providers-otel.md).

If you have specific telemetry requirements, already have a telemetry solution in mind, or need fine-grained control over how telemetry data is captured and processed, you can also implement your own telemetry provider.

Register your own implementation with the [TelemetryProvider](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/Runtime/TTelemetryProvider.html) class. The following is a simple example of how to register your own `TracerProvider` and `MeterProvider`.

```
using Amazon;
using Amazon.Runtime.Telemetry;
using Amazon.Runtime.Telemetry.Metrics;
using Amazon.Runtime.Telemetry.Tracing;

public class CustomTracerProvider : TracerProvider
{
    // Implement custom tracing logic here
}
public class CustomMeterProvider : MeterProvider
{
    // Implement custom metrics logic here
}

// Register custom implementations
AWSConfigs.TelemetryProvider.RegisterTracerProvider(new CustomTracerProvider());
AWSConfigs.TelemetryProvider.RegisterMeterProvider(new CustomMeterProvider());
```

**Topics**
+ [OpenTelemetry](observability-telemetry-providers-otel.md)

# Configure the OpenTelemetry-based telemetry provider
<a name="observability-telemetry-providers-otel"></a>

The AWS SDK for .NET includes an implementation of an OpenTelemetry-based telemetry provider. For details about how to set this provider as the global telemetry provider, see [Configure a `TelemetryProvider`](observability.md#observability-conf-telemetry-provider). To use this telemetry provider, you need the following resources in your project:
+ The [OpenTelemetry.Instrumentation.AWS](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWS) NuGet package.
+ A telemetry exporter such as OTLP or Console. For more information, see [Exporters](https://opentelemetry.io/docs/languages/net/exporters/) in the OpenTelemetry documentation.

The OpenTelemetry implementation included with the SDK can be configured to reduce the amount of tracing for HTTPS requests, credentials, and compression. To do so, set the `SuppressDownstreamInstrumentation` option to `true`, similar to the following:

```
Sdk.CreateTracerProviderBuilder()
    .ConfigureResource(e => e.AddService("DemoOtel"))
    .AddAWSInstrumentation(options => options.SuppressDownstreamInstrumentation = true)
    .AddConsoleExporter()
    .Build();
```

For additional information about this provider, see the blog post [Enhancing Observability in the AWS SDK for .NET with OpenTelemetry](https://aws.amazon.com/blogs/developer/enhancing-observability-in-the-aws-sdk-for-net-with-opentelemetry/).