diff --git a/content/en/docs/instrumentation/net/getting-started.md b/content/en/docs/instrumentation/net/getting-started.md
index 6e827524cc3a..7bb388bfef4f 100644
--- a/content/en/docs/instrumentation/net/getting-started.md
+++ b/content/en/docs/instrumentation/net/getting-started.md
@@ -1,389 +1,313 @@
---
title: Getting Started
+description: Get telemetry for your app in less than 5 minutes!
+cSpell:ignore: ASPNETCORE rolldice
weight: 10
-cSpell:ignore: KHTML loglevel nameof
---
-OpenTelemetry for .NET is unique among OpenTelemetry implementations, as it is
-integrated with the .NET `System.Diagnostics` library. At a high level, you can
-think of OpenTelemetry for .NET as a bridge between the telemetry available
-through `System.Diagnostics` and the greater OpenTelemetry ecosystem, such as
-OpenTelemetry Protocol (OTLP) and the OpenTelemetry Collector.
+This page will show you how to get started with OpenTelemetry in .NET.
-## ASP.NET Core
+You will learn how you can instrument a simple .NET application automatically,
+in such a way that [traces][], [metrics][] and [logs][] are emitted to the
+console.
-The following example demonstrates using Instrumentation Libraries and manual
-instrumentation via an ASP.NET Core app.
+## Prerequisites
-First, create your basic ASP.NET Core site:
+Ensure that you have the following installed locally:
-```shell
-dotnet new mvc
-```
+- [.NET SDK](https://dotnet.microsoft.com/download/dotnet) 6+
-Next, Add the Core OpenTelemetry packages
+## Example Application
-```shell
-dotnet add package OpenTelemetry.Exporter.Console
-dotnet add package OpenTelemetry.Extensions.Hosting
-```
+The following example uses a basic
+[Minimal API with ASP.NET Core](https://learn.microsoft.com/aspnet/core/tutorials/min-web-api)
+application. If you are not using ASP.NET Core, that's OK — you can still use
+OpenTelemetry .NET Automatic Instrumentation.
-Now let's add the instrumentation packages for ASP.NET Core. This will give us
-some automatic spans for each HTTP request to our app.
+For more elaborate examples, see
+[examples](/docs/instrumentation/net/examples/).
-```shell
-dotnet add package OpenTelemetry.Instrumentation.AspNetCore --prerelease
-```
+### Create and launch an HTTP Server
-_Note that as the Semantic Conventions for attribute names are not currently
-stable the instrumentation package is currently not in a released state. That
-doesn't mean that the functionality itself is not stable. This means that you
-need to use the `--prerelease` flag, or install a specific version of the
-package_
+To begin, set up an environment in a new directory called `dotnet-simple`.
+Within that directory, execute following command:
-### Setup
+```sh
+dotnet new web
+```
-Next, we need to add OpenTelemetry to our Service Collection in `Program.cs` so
-that its listening correctly.
+In the same directory, replace the content of `Program.cs` with the following
+code:
```csharp
-using System.Diagnostics;
-using OpenTelemetry.Resources;
-using OpenTelemetry.Trace;
+using System.Globalization;
var builder = WebApplication.CreateBuilder(args);
+var app = builder.Build();
-// .. other setup
+var logger = app.Logger;
-builder.Services.AddOpenTelemetry()
- .WithTracing(tracerProviderBuilder =>
- tracerProviderBuilder
- .AddSource(DiagnosticsConfig.ActivitySource.Name)
- .ConfigureResource(resource => resource
- .AddService(DiagnosticsConfig.ServiceName))
- .AddAspNetCoreInstrumentation()
- .AddConsoleExporter());
-
-// ... other setup
-
-public static class DiagnosticsConfig
+int RollDice()
{
- public const string ServiceName = "MyService";
- public static ActivitySource ActivitySource = new ActivitySource(ServiceName);
+ return Random.Shared.Next(1, 7);
}
-```
-
-At this stage, you should be able to run your site, and see a Console output
-similar to this:
-Note: an `Activity` in .NET is analogous to a Span in OpenTelemetry terminology
+string HandleRollDice(string? player)
+{
+ var result = RollDice();
+
+ if (string.IsNullOrEmpty(player))
+ {
+ logger.LogInformation("Anonymous player is rolling the dice: {result}", result);
+ }
+ else
+ {
+ logger.LogInformation("{player} is rolling the dice: {result}", player, result);
+ }
+
+ return result.ToString(CultureInfo.InvariantCulture);
+}
-
-View example output
+app.MapGet("/rolldice/{player?}", HandleRollDice);
-```properties
-Activity.TraceId: 54d084eba205a7a39398df4642be8f4a
-Activity.SpanId: aca5e39a86a17d59
-Activity.TraceFlags: Recorded
-Activity.ActivitySourceName: Microsoft.AspNetCore
-Activity.DisplayName: /
-Activity.Kind: Server
-Activity.StartTime: 2023-02-21T12:19:28.2499974Z
-Activity.Duration: 00:00:00.3106744
-Activity.Tags:
- net.host.name: localhost
- net.host.port: 5123
- http.method: GET
- http.scheme: http
- http.target: /
- http.url: http://localhost:5123/
- http.flavor: 1.1
- http.user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.50
- http.status_code: 200
-Resource associated with Activity:
- service.name: MyService
- service.instance.id: 2c7ca153-e460-4643-b550-7c08487a4c0c
+app.Run();
```
-
-
-### Manual Instrumentation
+In the `Properties` subdirectory, replace the content of `launchSettings.json`
+with the following:
-Next, add [tracing](/docs/concepts/signals/traces/) via the `System.Diagnostics`
-API.
-
-Paste the following code into your `HomeController`'s `Index` action:
-
-```csharp
-public IActionResult Index()
+```json
{
- // Track work inside of the request
- using var activity = DiagnosticsConfig.ActivitySource.StartActivity("SayHello");
- activity?.SetTag("foo", 1);
- activity?.SetTag("bar", "Hello, World!");
- activity?.SetTag("baz", new int[] { 1, 2, 3 });
-
- return View();
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "http://localhost:8080",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
}
```
-When you run the app and navigate to the `/` route, you'll see output about
-[spans](/docs/concepts/signals/traces/#spans) similar to the following:
+Build and run the application with the following command, then open
+ in your web browser to ensure it is working.
-
-View example output
-
-```text
-Activity.TraceId: 47d25efc8b5e9184ce57e692f5f65465
-Activity.SpanId: bb864adcf4592f54
-Activity.TraceFlags: Recorded
-Activity.ParentSpanId: acbff23f5ad721ff
-Activity.ActivitySourceName: MyService
-Activity.DisplayName: SayHello
-Activity.Kind: Internal
-Activity.StartTime: 2023-02-21T12:27:41.9596458Z
-Activity.Duration: 00:00:00.0005683
-Activity.Tags:
- foo: 1
- bar: Hello, World!
- baz: [1,2,3]
-Resource associated with Activity:
- service.name: MyService
- service.instance.id: 2b07a9ca-29c4-4e01-b0ed-929184b32192
+```sh
+dotnet build
+dotnet run
```
-
+## Instrumentation
-You'll notice the `Activity` objects from ASP.NET Core alongside the `Activity`
-we created manually in our controller action.
+Next, you'll use a [OpenTelemetry .NET Automatic Instrumentation](../automatic)
+to instrument the application at launch time. While you can [configure .NET
+Automatic Instrumentation][] in a number of ways, the steps below use Unix-shell
+or PowerShell scripts.
-### Metrics
+> **Note**: PowerShell commands require elevated (administrator) privileges.
-Next we'll add the ASP.NET Core automatically generated metrics to the app.
+1. Download installation scripts from [Releases][] of the
+ `opentelemetry-dotnet-instrumentation` repository:
-```csharp
-using OpenTelemetry.Resources;
-using OpenTelemetry.Trace;
-using OpenTelemetry.Metrics;
+ {{< tabpane text=true >}} {{% tab Unix-shell %}}
-var builder = WebApplication.CreateBuilder(args);
+ ```sh
+ curl -L -O https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/otel-dotnet-auto-install.sh
+ ```
-// .. other setup
+ {{% /tab %}} {{% tab PowerShell - Windows %}}
-builder.Services.AddOpenTelemetry()
- .WithTracing(/* .. tracing setup */ )
- .WithMetrics(metricsProviderBuilder =>
- metricsProviderBuilder
- .ConfigureResource(resource => resource
- .AddService(DiagnosticsConfig.ServiceName))
- .AddAspNetCoreInstrumentation()
- .AddConsoleExporter());
+ ```powershell
+ $module_url = "https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/OpenTelemetry.DotNet.Auto.psm1"
+ $download_path = Join-Path $env:temp "OpenTelemetry.DotNet.Auto.psm1"
+ Invoke-WebRequest -Uri $module_url -OutFile $download_path -UseBasicParsing
+ ```
-// .. other setup
-```
+ {{% /tab %}} {{< /tabpane >}}
-If you run your application now, you'll see a series of metrics output to the
-console. like this.
+2. Execute following script to download automatic instrumentation for your
+ development environment:
-
-View example output
+ {{< tabpane text=true >}} {{% tab Unix-shell %}}
-```text
-Export http.server.duration, Measures the duration of inbound HTTP requests., Unit: ms, Meter: OpenTelemetry.Instrumentation.AspNetCore/1.0.0.0
-(2023-02-21T12:38:57.0187781Z, 2023-02-21T12:44:16.9651349Z] http.flavor: 1.1 http.method: GET http.route: {controller=Home}/{action=Index}/{id?} http.scheme: http http.status_code: 200 net.host.name: localhost net.host.port: 5123 Histogram
-Value: Sum: 373.4504 Count: 1 Min: 373.4504 Max: 373.4504
-(-Infinity,0]:0
-(0,5]:0
-(5,10]:0
-(10,25]:0
-(25,50]:0
-(50,75]:0
-(75,100]:0
-(100,250]:0
-(250,500]:1
-(500,750]:0
-(750,1000]:0
-(1000,2500]:0
-(2500,5000]:0
-(5000,7500]:0
-(7500,10000]:0
-(10000,+Infinity]:0
-```
+ ```sh
+ ./otel-dotnet-auto-install.sh
+ ```
-
+ {{% /tab %}} {{% tab PowerShell - Windows %}}
-### Manual Metrics
+ ```powershell
+ Import-Module $download_path
+ Install-OpenTelemetryCore
+ ```
-Next, add some manual metrics to the app. This will initialize a
-[Meter](/docs/concepts/signals/metrics) to create a counter in code.
+ {{% /tab %}} {{< /tabpane >}}
-```csharp
-var builder = WebApplication.CreateBuilder(args);
+3. Set and export variables that specify a [console exporter][], then execute
+ script configuring other necessary environment variables using a notation
+ suitable for your shell/terminal environment — we illustrate a notation
+ for bash-like shells and PowerShell:
-// .. other setup
+ {{< tabpane text=true >}} {{% tab Unix-shell %}}
-builder.Services.AddOpenTelemetry()
- .WithTracing(/* .. tracing setup */ )
- .WithMetrics(metricsProviderBuilder =>
- metricsProviderBuilder
- .AddMeter(DiagnosticsConfig.Meter.Name)
- // .. more metrics
- );
+ ```sh
+ export OTEL_TRACES_EXPORTER=none \
+ OTEL_METRICS_EXPORTER=none \
+ OTEL_LOGS_EXPORTER=none \
+ OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED=true \
+ OTEL_DOTNET_AUTO_METRICS_CONSOLE_EXPORTER_ENABLED=true \
+ OTEL_DOTNET_AUTO_LOGS_CONSOLE_EXPORTER_ENABLED=true
+ OTEL_SERVICE_NAME=RollDiceService
+ . $HOME/.otel-dotnet-auto/instrument.sh
+ ```
-public static class DiagnosticsConfig
-{
- public const string ServiceName = "MyService";
+ {{% /tab %}} {{% tab PowerShell - Windows %}}
- // .. other config
+ ```powershell
+ $env:OTEL_TRACES_EXPORTER="none"
+ $env:OTEL_METRICS_EXPORTER="none"
+ $env:OTEL_LOGS_EXPORTER="none"
+ $env:OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED="true"
+ $env:OTEL_DOTNET_AUTO_METRICS_CONSOLE_EXPORTER_ENABLED="true"
+ $env:OTEL_DOTNET_AUTO_LOGS_CONSOLE_EXPORTER_ENABLED="true"
+ Register-OpenTelemetryForCurrentSession -OTelServiceName "RollDiceService"
+ ```
- public static Meter Meter = new(ServiceName);
- public static Counter RequestCounter =
- Meter.CreateCounter("app.request_counter");
-}
-```
-
-Now we can increment the counter in our `Index` action.
-
-```csharp
-public IActionResult Index()
-{
- // do other stuff
-
- DiagnosticsConfig.RequestCounter.Add(1,
- new("Action", nameof(Index)),
- new("Controller", nameof(HomeController)));
-
- return View();
-}
-```
-
-You'll notice here that we're also adding Tags (OpenTelemetry Attributes) to our
-request counter that distinguishes it from other requests. You should now see an
-output like this.
-
-
-View example output
-
-```text
-Export app.request_counter, Meter: MyService
-(2023-02-21T13:11:28.7265324Z, 2023-02-21T13:11:48.7074259Z] Action: Index Controller: HomeController LongSum
-Value: 1
-```
+ {{% /tab %}} {{< /tabpane >}}
-
-
-Tip: if you comment out the `.AddAspNetCoreInstrumentation()` line in
-`Program.cs` you'll be able to see the output better.
-
-## Send data to a collector
-
-The [OpenTelemetry Collector](/docs/collector/getting-started/) is a vital
-component of most production deployments. A collector is most beneficial in the
-following situations, among others:
-
-- A single telemetry sink shared by multiple services, to reduce overhead of
- switching exporters
-- Aggregate traces across multiple services, running on multiple hosts
-- A central place to process traces prior to exporting them to a backend
-
-### Configure and run a local collector
-
-First, save the following collector configuration code to a file in the `/tmp/`
-directory:
-
-```yaml
-# /tmp/otel-collector-config.yaml
-receivers:
- otlp:
- protocols:
- http:
- grpc:
-exporters:
- logging:
- loglevel: debug
-processors:
- batch:
-service:
- pipelines:
- traces:
- receivers: [otlp]
- exporters: [logging]
- processors: [batch]
- metrics:
- receivers: [otlp]
- exporters: [logging]
- processors: [batch]
-```
+4. Run your **application** once again:
-Then run the docker command to acquire and run the collector based on this
-configuration:
+ ```sh
+ dotnet run
+ ```
-```shell
-docker run -p 4317:4317 \
- -v /tmp/otel-collector-config.yaml:/etc/otel-collector-config.yaml \
- otel/opentelemetry-collector:latest \
- --config=/etc/otel-collector-config.yaml
-```
+ Note the output from the `dotnet run`.
-You will now have an collector instance running locally.
+5. From _another_ terminal, send a request using `curl`:
-### Modify the code to export spans via OTLP
+ ```sh
+ curl localhost:8080/rolldice
+ ```
-The next step is to modify the code to send spans to the collector via OTLP
-instead of the console.
-
-First, add the following package:
-
-```shell
-dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
-```
+6. After about 30 sec, stop the server process.
-Next, using the ASP.NET Core code from earlier, replace the console exporter
-with an OTLP exporter:
+At this point, you should see trace and log output from the server and client
+that looks something like this (output is line-wrapped for readability):
-```csharp
-builder.Services.AddOpenTelemetry()
- .WithTracing(tracerProviderBuilder =>
- tracerProviderBuilder
- // .. other config
- .AddOtlpExporter())
- .WithMetrics(metricsProviderBuilder =>
- metricsProviderBuilder
- // .. other config
- .AddOtlpExporter());
+
+Traces and Logs
+
+```log
+LogRecord.Timestamp: 2023-08-14T06:44:53.9279186Z
+LogRecord.TraceId: 3961d22b5f90bf7662ad4933318743fe
+LogRecord.SpanId: 93d5fcea422ff0ac
+LogRecord.TraceFlags: Recorded
+LogRecord.CategoryName: simple-dotnet
+LogRecord.LogLevel: Information
+LogRecord.StateValues (Key:Value):
+ result: 1
+ OriginalFormat (a.k.a Body): Anonymous player is rolling the dice: {result}
+
+Resource associated with LogRecord:
+service.name: simple-dotnet
+telemetry.auto.version: 0.7.0
+telemetry.sdk.name: opentelemetry
+telemetry.sdk.language: dotnet
+telemetry.sdk.version: 1.4.0.802
+
+info: simple-dotnet[0]
+ Anonymous player is rolling the dice: 1
+Activity.TraceId: 3961d22b5f90bf7662ad4933318743fe
+Activity.SpanId: 93d5fcea422ff0ac
+Activity.TraceFlags: Recorded
+Activity.ActivitySourceName: OpenTelemetry.Instrumentation.AspNetCore
+Activity.DisplayName: /rolldice
+Activity.Kind: Server
+Activity.StartTime: 2023-08-14T06:44:53.9278162Z
+Activity.Duration: 00:00:00.0049754
+Activity.Tags:
+ net.host.name: localhost
+ net.host.port: 8080
+ http.method: GET
+ http.scheme: http
+ http.target: /rolldice
+ http.url: http://localhost:8080/rolldice
+ http.flavor: 1.1
+ http.user_agent: curl/8.0.1
+ http.status_code: 200
+Resource associated with Activity:
+ service.name: simple-dotnet
+ telemetry.auto.version: 0.7.0
+ telemetry.sdk.name: opentelemetry
+ telemetry.sdk.language: dotnet
+ telemetry.sdk.version: 1.4.0.802
```
-By default, it will send spans to `localhost:4317`, which is what the collector
-is listening on if you've followed the step above.
-
-### Run the application
+
-Run the application like before:
+Also when stopping the server, you should see an output of all the metrics
+collected (sample excerpt shown):
-```shell
-dotnet run
+
+Metrics
+
+```log
+Export process.runtime.dotnet.gc.collections.count, Number of garbage collections that have occurred since process start., Meter: OpenTelemetry.Instrumentation.Runtime/1.1.0.2
+(2023-08-14T06:12:05.8500776Z, 2023-08-14T06:12:23.7750288Z] generation: gen2 LongSum
+Value: 2
+(2023-08-14T06:12:05.8500776Z, 2023-08-14T06:12:23.7750288Z] generation: gen1 LongSum
+Value: 2
+(2023-08-14T06:12:05.8500776Z, 2023-08-14T06:12:23.7750288Z] generation: gen0 LongSum
+Value: 6
+
+...
+
+Export http.client.duration, Measures the duration of outbound HTTP requests., Unit: ms, Meter: OpenTelemetry.Instrumentation.Http/1.0.0.0
+(2023-08-14T06:12:06.2661140Z, 2023-08-14T06:12:23.7750388Z] http.flavor: 1.1 http.method: POST http.scheme: https http.status_code: 200 net.peer.name: dc.services.visualstudio.com Histogram
+Value: Sum: 1330.4766000000002 Count: 5 Min: 50.0333 Max: 465.7936
+(-Infinity,0]:0
+(0,5]:0
+(5,10]:0
+(10,25]:0
+(25,50]:0
+(50,75]:2
+(75,100]:0
+(100,250]:0
+(250,500]:3
+(500,750]:0
+(750,1000]:0
+(1000,2500]:0
+(2500,5000]:0
+(5000,7500]:0
+(7500,10000]:0
+(10000,+Infinity]:0
```
-Now, telemetry will be output by the collector process.
-
-## Next steps
-
-To ensure you're getting the most data as easily as possible, install
-[instrumentation libraries](/docs/instrumentation/net/libraries) to generate
-observability data.
-
-Additionally, enriching your codebase with
-[manual instrumentation](/docs/instrumentation/net/manual) gives you customized
-observability data.
-
-You'll also want to configure an appropriate exporter to
-[export your telemetry data](/docs/instrumentation/net/exporters) to one or more
-telemetry backends.
-
-You can also check the
-[automatic instrumentation for .NET](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation),
-which is currently in beta.
+
-If you'd like to explore a more complex example, take a look at the
-[OpenTelemetry Demo](/docs/demo/), which includes the .NET based
-[Cart Service](/docs/demo/services/cart/).
+## What next?
+
+For more:
+
+- Run this example with another [exporter][] for telemetry data.
+- Try [automatic instrumentation](../automatic/) on one of your own apps.
+- Learn about [manual instrumentation][] and try out more
+ [examples](/docs/instrumentation/net/examples/).
+- Take a look at the [OpenTelemetry Demo](/docs/demo/), which includes .NET
+ based [Cart Service](/docs/demo/services/cart/).
+
+[traces]: /docs/concepts/signals/traces/
+[metrics]: /docs/concepts/signals/metrics/
+[logs]: /docs/concepts/signals/logs/
+[configure .NET Automatic Instrumentation]: ../automatic
+[console exporter]:
+ https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/main/docs/config.md#internal-logs
+[exporter]:
+ https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/main/docs/config.md#exporters
+[manual instrumentation]: ../manual
+[releases]:
+ https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases
diff --git a/static/refcache.json b/static/refcache.json
index c041a3b34c6f..39548e22238f 100644
--- a/static/refcache.json
+++ b/static/refcache.json
@@ -1271,6 +1271,10 @@
"StatusCode": 200,
"LastSeen": "2023-06-29T15:46:44.824874-04:00"
},
+ "https://dotnet.microsoft.com/download": {
+ "StatusCode": 200,
+ "LastSeen": "2023-08-14T07:27:50.575755318Z"
+ },
"https://dotnet.microsoft.com/download/dotnet": {
"StatusCode": 200,
"LastSeen": "2023-08-01T12:16:39.990619752Z"
@@ -2427,10 +2431,18 @@
"StatusCode": 200,
"LastSeen": "2023-06-30T09:25:10.121533-04:00"
},
+ "https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases": {
+ "StatusCode": 200,
+ "LastSeen": "2023-08-14T07:27:52.35566079Z"
+ },
"https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest": {
"StatusCode": 200,
"LastSeen": "2023-06-30T08:44:58.585689-04:00"
},
+ "https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/otel-dotnet-auto-install.sh": {
+ "StatusCode": 206,
+ "LastSeen": "2023-08-14T07:27:51.68749521Z"
+ },
"https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/tag/v0.1.0-beta.1": {
"StatusCode": 200,
"LastSeen": "2023-06-30T09:25:04.874497-04:00"
@@ -3567,6 +3579,10 @@
"StatusCode": 206,
"LastSeen": "2023-06-29T16:21:28.969704-04:00"
},
+ "https://learn.microsoft.com/aspnet/core/tutorials/min-web-api": {
+ "StatusCode": 200,
+ "LastSeen": "2023-08-14T07:27:51.174082501Z"
+ },
"https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id": {
"StatusCode": 200,
"LastSeen": "2023-06-30T09:16:26.155249-04:00"