# Instrumenting Example Applications with the OpenTelemetry .NET Automatic Instrumentation

The following examples show how different instrumentation scenarios are covered by
the OpenTelemetry .NET Automatic Instrumentation.

## Overview

The example script instruments two .NET processes. These processes are identified
as [OpenTelemetry services](https://github.com/open-telemetry/opentelemetry-specification/blob/d6bcc0cb072d8d6f6ced856f1f23c451648a3caa/specification/resource/semantic_conventions/README.md#service)
with the following names:

 1. **`aspnet-server`**: ASP.NET Core application that makes requests to MongoDB
 and Redis databases.
 2. **`{exampleApp}`**: .NET application that makes a few HTTP requests
 to the `aspnet-server` and some public websites. The exact name is equal
 to `exampleApp` value.

The script creates Docker containers for MongoDB, Redis, Jaeger, Prometheus,
and the [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/).
You can see the traces generated by the example in the Jaeger container,
while the metrics are available on the Prometheus container.
The number and organization of traces generated depends on the `exampleApp`
used in the specific run. The script waits for your input before stopping the containers.

## How to run the examples

To run the example applications:

 1. Create a local build of the project following the [developing instructions](../docs/developing.md).
 2. Run the `./run-example.sh` script at the root of the repository.

You can customize the script using the following environment variables:

| Environment variable            | Description                                                                         | Default                                                                       |
|---------------------------------|-------------------------------------------------------------------------------------|-------------------------------------------------------------------------------|
| **aspNetAppTargetFramework**    | Target framework for the `aspnet-server` service                                    | `netcoreapp3.1`                                                               |
| **configuration**               | Build configuration for example apps, either `Release` or `Debug`                   | `Release`                                                                     |
| **enableProfiling**             | Value of `COR_ENABLE_PROFILING` and `CORECLR_ENABLE_PROFILING` for the example apps | `1`                                                                           |
| **exampleApp**                  | Application selected for the `http-client` service                                  | `ConsoleApp`                                                                  |
| **exampleAppInjectSDK**         | Whether automatic instrumentation injects the SDK on the `http-client` service      | `true`                                                                        |
| **exampleAppTargetFramework**   | Target framework for the `http-client` service                                      | `netcoreapp3.1`                                                               |
| **tracesExporter**              | Value for [`OTEL_TRACES_EXPORTER`](../docs/config.md#exporters) env. variable       | `otlp`                                                                        |
| **metricsExporter**             | Value for [`OTEL_METRICS_EXPORTER`](../docs/config.md#exporters) env. variable      | `otlp`                                                                        |
| **keepContainers**              | Whether the docker containers are preserved after the script execution              | `false`                                                                       |
| **skipAppBuild**                | Whether the script skips building the example apps                                  | `false`                                                                       |
| **vendorPluginTargetFramework** | Target framework for the `aspnet-server` service                                    | `net462` if `aspNetAppTargetFramework` is `net462`, `netcoreapp3.1` otherwise |

Usage example:

```bash
exampleAppTargetFramework="net6.0" ./run-example.sh
```

## Project examples

### AspNetCoreMvc

An ASP.NET Core MVC application used to simulate a server application capable
of making calls to MongoDB, Redis and generate metrics. In addition to these calls,
it also supports various other endpoints.
Check the [Controllers](./AspNetCoreMvc/Controllers/) for some
of the endpoints you can use.

Usage example:

```bash
aspNetAppTargetFramework="net6.0" ./run-example.sh
```

### BindingRedirect

Example client app that uses .NET Framework binding redirects to handle assembly
version conflict between automatic instrumentation and third-party libraries
that cannot be updated to the same version required by OpenTelemetry.
See the `OldReference` project for more information.

The project representing the third-party library has a legacy Activity named `InstrumentedHttpCall.GetAsync`
set [`OTEL_DOTNET_AUTO_LEGACY_SOURCES`](../docs/config.md#customization)
to capture it.

The following usage example is for Windows, as binding redirection only applies
to .NET Framework:

```bash
OTEL_DOTNET_AUTO_LEGACY_SOURCES="InstrumentedHttpCall.GetAsync" exampleApp=BindingRedirect exampleAppTargetFramework=net462 ./run-example.sh
```

### ConsoleApp

The default example app used by `./run-example.sh`. [OpenTracing](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Shims.OpenTracing#readme).

Usage example:

```bash
exampleAppTargetFramework="net6.0" ./run-example.sh
```

### ConsoleApp.SelfBootstrap

A client app that bootstraps the OpenTelemetry SDK. It uses an
[ActivitySource](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry/README.md#activity-source)
to implement manual instrumentation. The bootstrap code takes care of adding
the ActivitySource name for the automatic instrumentation and the manual instrumentation.

The bootstrap code enables the [Zipkin exporter](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Zipkin/README.md)
provided by the SDK. The OpenTelemetry collector container is also configured
to accept Zipkin spans.

Use the environment variable `exampleAppInjectSDK` in the script to control
the value of [`OTEL_DOTNET_AUTO_LOAD_TRACER_AT_STARTUP`](../docs/config.md#customization).
For example:

```bash
exampleAppInjectSDK=false exampleApp=ConsoleApp.SelfBootstrap ./run-example.sh
```

### CoreAppOldReference

Example client application that uses NuGet package version resolution at build
time to handle assembly version conflict between automatic instrumentation
and third-party libraries that can't be updated to the same version required
by OpenTelemetry. See the `OldReference` project for more information.

The project representing the third-party library has a legacy Activity named `InstrumentedHttpCall.GetAsync`
set [`OTEL_DOTNET_AUTO_LEGACY_SOURCES`](../docs/config.md#customization)
to capture it.

Usage example:

```bash
OTEL_DOTNET_AUTO_LEGACY_SOURCES="InstrumentedHttpCall.GetAsync" exampleApp=CoreAppOldReference ./run-example.sh
```

### ManualInstrumentations

Example console application to illustrate how to make [manual instrumentation](..\docs\manual-instrumentation.md).

Usage example:

```bash
OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES="Examples.ManualInstrumentations.*" exampleApp=ManualInstrumentations ./run-example.sh
```

### OldReference

Represents a third-party project that can't be updated to use the same version
of the assemblies required by OpenTelemetry .NET SDK used by the automatic instrumentation.

### OpenTracing.Library

A library that wraps an OpenTracing span around a `Func<Task>` delegate.

### Vendor.Distro

Implements an [instrumentation plugin](../docs/config.md#additional-settings).
The example script adds this plugin to the instrumentation configuration
when launching the server application of the demo.
