Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update .NET manual instrumentation docs with example app #3834

Merged
merged 28 commits into from
May 16, 2024
Merged
Changes from 3 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f5f71b9
add example app preparation
IAMebonyhope Jan 20, 2024
f75bdbd
add manual instrumentation setup
IAMebonyhope Jan 20, 2024
7594701
fix code snippets
IAMebonyhope Jan 20, 2024
8ead5ef
add example app preparation
IAMebonyhope Jan 20, 2024
996dc8a
add manual instrumentation setup
IAMebonyhope Jan 20, 2024
02afc00
fix code snippets
IAMebonyhope Jan 20, 2024
fff5bc5
Merge branch 'main' of github.com:IAMebonyhope/opentelemetry.io
IAMebonyhope Jan 20, 2024
020f5d4
Apply suggestions from code review
IAMebonyhope Jan 24, 2024
610a060
Merge branch 'main' of github.com:IAMebonyhope/opentelemetry.io
IAMebonyhope Jan 24, 2024
a977d67
update traces section
IAMebonyhope Feb 8, 2024
6ae0416
Add traces section
IAMebonyhope Feb 9, 2024
3fdd65f
fix some comments
IAMebonyhope Feb 9, 2024
d3580d6
incorporate feedback
IAMebonyhope Feb 14, 2024
7dc7ffc
incorporate feedback
IAMebonyhope Feb 14, 2024
505bcf9
Update content/en/docs/languages/net/instrumentation.md
IAMebonyhope Mar 1, 2024
d84d5ca
Apply suggestions from code review
IAMebonyhope Mar 1, 2024
55ec3a0
incorporate feedback
IAMebonyhope Apr 10, 2024
2d36d21
Merge branch 'main' of github.com:IAMebonyhope/opentelemetry.io
IAMebonyhope Apr 10, 2024
dbbf6f7
fix alignment
IAMebonyhope Apr 10, 2024
5ea327f
add Instrumentation wrapper
IAMebonyhope Apr 11, 2024
90b7a96
Merge branch 'open-telemetry:main' into main
IAMebonyhope May 2, 2024
2cb9cd0
add reference to activitySource in Dice.cs
IAMebonyhope May 10, 2024
4ab7355
update blog contribution policy
svrnm May 10, 2024
39733f8
include comments
IAMebonyhope May 15, 2024
4d02369
Apply suggestions from code review
IAMebonyhope May 15, 2024
a4cf770
Merge branch 'open-telemetry:main' into main
svrnm May 16, 2024
102e258
Merge branch 'main' into IAMebonyhope/main
svrnm May 16, 2024
da78f9c
Prepare for merge
svrnm May 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
226 changes: 226 additions & 0 deletions content/en/docs/languages/net/instrumentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@

{{% docs/languages/manual-intro %}}

{{% alert title="Note" color="info" %}}

On this page you will learn how you can add traces, metrics and logs to your
code _manually_. But, you are not limited to only use one kind of
instrumentation: use [automatic instrumentation](/docs/languages/net/automatic/)
to get started and then enrich your code with manual instrumentation as needed.
svrnm marked this conversation as resolved.
Show resolved Hide resolved

Also, for libraries your code depends on, you don't have to write
instrumentation code yourself, since they might come with OpenTelemetry built-in
_natively_ or you can make use of
[instrumentation libraries](/docs/languages/net/libraries/).
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved

{{% /alert %}}

## A note on terminology

.NET is different from other languages/runtimes that support OpenTelemetry. The
Expand All @@ -22,6 +36,218 @@
If you prefer to use OpenTelemetry APIs instead of `System.Diagnostics` APIs,
you can refer to the [OpenTelemetry API Shim docs for tracing](../shim).

## Example app preparation {#example-app}

This page uses a modified version of the example app from
[Getting Started](/docs/languages/net/getting-started/) to help you learn
about manual instrumentation.

You don't have to use the example app: if you want to instrument your own app or
library, follow the instructions here to adapt the process to your own code.

### Dependencies {#example-app-dependencies}
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved

- [.NET SDK](https://dotnet.microsoft.com/download/dotnet) 6+

### Create and launch an HTTP Server

IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved
To highlight the difference between instrumenting a _library_ and a standalone
_app_, split out the dice rolling into a _library file_, which then will be
imported as a dependency by the _app file_.

Create the _library file_ named `Dice.cs` and add the following code to it:
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved

```csharp
/*Dice.cs*/
namespace otel
{
public class Dice
{
private int min;
private int max;

public Dice(int min, int max)
{
this.min = min;
this.max = max;
}

public List<int> rollTheDice(int rolls)
{
List<int> results = new List<int>();

for (int i = 0; i < rolls; i++)
{
results.Add(rollOnce());
}

return results;
}

private int rollOnce()
{
return Random.Shared.Next(min, max + 1);
}
}
}
```

Create the _app file_ `DiceController.cs` and add the following code to it:

```csharp
using Microsoft.AspNetCore.Mvc;
using System.Net;

namespace otel
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved
{
public class DiceController : ControllerBase
{
private ILogger<DiceController> logger;

public DiceController(ILogger<DiceController> logger)
{
this.logger = logger;
}

[HttpGet("/rolldice")]
public List<int> RollDice(string player, int? rolls)
{
if(!rolls.HasValue)
{
logger.LogError("Missing rolls parameter");
throw new HttpRequestException("Missing rolls parameter", null, HttpStatusCode.BadRequest);
}

var result = new Dice(1, 6).rollTheDice(rolls.Value);

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;
}
}
}
```

Replace the program.cs content with the following code:
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved

```csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

var app = builder.Build();

app.MapControllers();

app.Run();
```

IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved
To ensure that it is working, run the application with the following command and
open <http://localhost:8080/rolldice?rolls=12> in your web browser:

```sh
dotnet build
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved
dotnet run
```

You should get a list of 12 numbers in your browser window, for example:

```text
[5,6,5,3,6,1,2,5,4,4,2,4]
```

## Manual instrumentation setup

### Dependencies

Install the [OpenTelemetry API and SDK NuGet packages](https://www.nuget.org/profiles/OpenTelemetry):
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved

```sh
dotnet add package OpenTelemetry
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved
dotnet add package OpenTelemetry.Exporter.Console
dotnet add package OpenTelemetry.Extensions.Hosting
```

### Initialize the SDK

{{% alert title="Note" color="info" %}} If you’re instrumenting a library,
**skip this step**. {{% /alert %}}
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved

Before any other module in your application is loaded, you must initialize the SDK.
If you fail to initialize the SDK or initialize it too late, no-op
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved
implementations will be provided to any library that acquires a tracer or meter from the API.

To intialize the sdks, replace the program.cs content with the following code:

Check warning on line 187 in content/en/docs/languages/net/instrumentation.md

View workflow job for this annotation

GitHub Actions / SPELLING check

Unknown word (intialize)
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved

```csharp
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

var serviceName = "dice-server";
var serviceVersion = "1.0.0";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService(
serviceName: serviceName,
serviceVersion: serviceVersion))
.WithTracing(tracing => tracing
.AddSource(serviceName)
svrnm marked this conversation as resolved.
Show resolved Hide resolved
.AddConsoleExporter())
svrnm marked this conversation as resolved.
Show resolved Hide resolved
.WithMetrics(metrics => metrics
.AddMeter(serviceName)
.AddConsoleExporter());

builder.Logging.AddOpenTelemetry(options => options
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(
serviceName: serviceName,
serviceVersion: serviceVersion))
.AddConsoleExporter());

builder.Services.AddControllers();

var app = builder.Build();

app.MapControllers();

app.Run();

```

For debugging and local development purposes, the following example exports
telemetry to the console. After you have finished setting up manual
instrumentation, you need to configure an appropriate exporter to
[export the app's telemetry data](/docs/languages/net/exporters/) to one or more
telemetry backends.
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved

The example also sets up the mandatory SDK default attribute `service.name`,
which holds the logical name of the service, and the optional (but highly
encouraged!) attribute `service.version`, which holds the version of the service
API or implementation.

IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved
Alternative methods exist for setting up resource attributes. For more
information, see [Resources](/docs/languages/net/resources/).

To verify your code, build and run the app:

```sh
dotnet build
dotnet run
```

This basic setup has no effect on your app yet. You need to add code for
IAMebonyhope marked this conversation as resolved.
Show resolved Hide resolved
[traces](#traces), [metrics](#metrics), and/or [logs](#logs).

## Traces

### Initializing tracing
Expand Down
Loading