Tutorial: Use GitLab Observability with a .NET application
FLAG: The availability of this feature is controlled by a feature flag. For more information, see the history of the Distributed tracing feature.
In this tutorial, you'll learn how to create, configure, instrument, and monitor a .NET Core application using GitLab Observability features.
Before you begin
To follow along this tutorial, you must have:
- A GitLab Ultimate subscription for GitLab.com or GitLab self-managed
- A local installation of .NET
- Basic knowledge of Git, .NET, and the core concepts of OpenTelemetry
Create a GitLab project
First, create a GitLab project and a corresponding access token.
- On the left sidebar, at the top, select Create new ({plus}) and New project/repository.
- Select Create blank project.
- Enter the project details.
- In the Project name field, enter
dotnet-O11y-tutorial
.
- In the Project name field, enter
- Select Create project.
- In the
dotnet-O11y-tutorial
project, on the left sidebar, select Settings > Access tokens. - Create an access token with the
api
scope and Developer role. Store the token value somewhere safe. You'll need it later.
Create a .NET application
Next, we'll create a .NET web application that we can instrument. For this tutorial, let's create a toy application that returns animal emojis.
-
Clone the
dotnet-O11y-tutorial
project andcd
to thedotnet-O11y-tutorial
directory. -
Create a web application by running:
dotnet new web
-
Create an animal controller file by running the following:
touch AnimalController.cs
-
Replace the contents of
AnimalController.cs
with the following:using Microsoft.AspNetCore.Mvc; public class AnimalsController : ControllerBase { private Dictionary<string, string> animals = new Dictionary<string, string> { { "dog", "🐶" }, { "cat", "🐱" }, { "fish", "🐟" } }; private ILogger<AnimalsController> logger; public AnimalsController(ILogger<AnimalsController> logger) { this.logger = logger; } [HttpGet("/animals/{animal}")] public IActionResult GetAnimal([FromRoute] string animal) { if (animals.TryGetValue(animal, out string? emoji)) { logger.LogInformation("Animal emoji found for: {animal}", animal); return Ok(emoji); } else { logger.LogInformation("Could not find animal emoji for: {animal}", animal); return NotFound("Animal not found"); } } }
-
In the
Properties
subdirectory, replace the contents oflaunchSettings.json
with the following:{ "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { "http": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "applicationUrl": "http://localhost:8080", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
-
Replace the contents of
Program.cs
with the following:var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run();
-
Build and run the application:
dotnet build dotnet run
-
Visit
http://localhost:8080/animals/dog
, and you should see the emoji🐶 .
Instrument the application
-
Install the required OpenTelemetry packages:
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol dotnet add package OpenTelemetry.Extensions.Hosting dotnet add package OpenTelemetry.Exporter.Console dotnet add package OpenTelemetry.Instrumentation.AspNetCore --prerelease dotnet add package OpenTelemetry.Instrumentation.Http --prerelease
-
Replace the contents of
Program.cs
with the following:using OpenTelemetry.Exporter; using OpenTelemetry.Logs; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; var builder = WebApplication.CreateBuilder(args); const string serviceName = "dotnet-O11y-tutorial"; string otelHeaders = Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_HEADERS") ?? "empty"; string otelBaseUrl = Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "empty"; builder.Services.AddOpenTelemetry() .ConfigureResource(resource => resource.AddService(serviceName)) .WithTracing(tracing => tracing .AddSource(serviceName) .AddHttpClientInstrumentation() .AddAspNetCoreInstrumentation() .AddOtlpExporter(options => { options.Endpoint = new Uri(otelBaseUrl + "/traces"); options.Headers = otelHeaders; options.Protocol = OtlpExportProtocol.HttpProtobuf; })) .WithMetrics(metrics => metrics .AddMeter(serviceName) .AddHttpClientInstrumentation() .AddAspNetCoreInstrumentation() .AddOtlpExporter(options => { options.Endpoint = new Uri(otelBaseUrl + "/metrics"); options.Headers = otelHeaders; options.Protocol = OtlpExportProtocol.HttpProtobuf; })) .WithLogging(logging => logging .AddConsoleExporter() .AddOtlpExporter(options => { options.Endpoint = new Uri(otelBaseUrl + "/logs"); options.Headers = otelHeaders; options.Protocol = OtlpExportProtocol.HttpProtobuf; })); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run();
-
Find your project ID:
- On the
dotnet-O11y-tutorial
project overview page, in the upper-right corner, select Actions ({ellipsis_v}). - Select Copy project ID. Save the copied ID for later.
- On the
-
Configure your application with instrumentation. If you're using self-managed GitLab, replace
gitlab.com
with your self-managed instance hostname. -
Run your application.
env OTEL_EXPORTER_OTLP_ENDPOINT="https://gitlab.com/api/v4/projects/{{PROJECT_ID}}/observability" \ OTEL_EXPORTER_OTLP_HEADERS="PRIVATE-TOKEN={{ACCESS_TOKEN}}" \ OTEL_LOG_LEVEL="debug" \ dotnet run
-
Visit
http://localhost:8080/animals/dog
to generate some events.
View the information in GitLab
To view the exported information from your test project:
- On the left sidebar, select Search or go to and find your project.
- Select Monitor, then either Logs, Metrics, or Traces.