Docs
DocumentationQuery ReferenceAPI Reference
Open Console→→
DocumentationQuery ReferenceAPI Reference

Platform overview

What is Axiom?QuickstartArchitectureFeatures
Fundamentals
Datasets
Edge deployments
Limits
Performance
Optimize usage
Requirements
Semantic conventions
Glossary
Tour
SecurityRoadmap

Send data

Reference architecturesMethods

Understand data

Console
Query
Builder
Editor
Query results
Visualize
Traces
Metrics
Correlations
Save queries
Stream
Dashboard
Create
Elements
Create
Configure
Element types
Gauge
Heatmap
Log stream
Monitor list
Note
Pie chart
Scatter plot
Statistic
Table
Time series
Sections
Configure
Filter
Annotate
Monitor
Overview
View status
Configure
Examples
Monitor types
Anomaly
Match
Threshold
Alerting
Overview
Configure
Notifier types
Custom Webhook
Discord
Email
Microsoft Teams
Opsgenie
PagerDuty
Slack
Manage
Datasets
Overview
Views
Virtual fields
Access
RBAC
Tokens
CLI
Organization
Audit log
Settings
Usage and billing
Profile
Extend
Overview
AWS Lambda
AWS PrivateLink
Cloudflare Workers
Cloudflare Logpush
Convex
Grafana
Hex
Netlify
Supabase
Tailscale
Terraform
Vercel
Intelligence
Overview
Spotlight
AI agents
Overview
MCP Server
Query cost limits
Agent-created orgs
Skills
Overview
Axiom alerting
Build dashboards
Control costs
Query metrics
SRE
Translate SPL to APL
Splunk
Overview
Splunk app
Install and configure
Commands
Examples
Portal
How it works
Set up standard mode
Set up transparent mode
Observability Cloud
SPL command support
Examples
Monitor and troubleshoot

Use cases

ObservabilityProduct analytics
LLM observability
Overview
Use Axiom AI SDK
Manual instrumentation
GenAI attributes
Redaction policies

Miscellaneous

LLMs
Overview
List of docs pages
Full docs
Query reference
FAQs
Legal
Acceptable use policy
Cookies
Data processing
HIPAA
Partner agreement
Partner program guide
Privacy policy
SLA
Terms of service
Terms of use

OpenTelemetry using .NET

This guide explains how to configure a .NET app using the .NET OpenTelemetry SDK to send telemetry data to Axiom.

OpenTelemetry provides a unified approach to collecting telemetry data from your .NET apps. This guide explains how to configure OpenTelemetry in a .NET app to send telemetry data to Axiom using the OpenTelemetry SDK.

Prerequisites

  • Create an Axiom account.
  • Create a dataset in Axiom where you send your data.
  • Create an API token in Axiom with permissions to ingest data to the dataset you have created.
  • Install the .NET 6.0 SDK on your development machine.
  • Use your existing .NET app or start with the sample provided in the program.cs below.

Install dependencies

Run the following command in your terminal to install the necessary NuGet packages:

shell
dotnet add package OpenTelemetry --version 1.7.0
dotnet add package OpenTelemetry.Exporter.Console --version 1.7.0
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol --version 1.7.0
dotnet add package OpenTelemetry.Extensions.Hosting --version 1.7.0
dotnet add package OpenTelemetry.Instrumentation.AspNetCore --version 1.7.1
dotnet add package OpenTelemetry.Instrumentation.Http --version 1.6.0-rc.1

Replace the dotnet.csproj file in your project with the following:

csharp
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="OpenTelemetry" Version="1.7.0" />
    <PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.7.0" />
    <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.7.0" />
    <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.7.0" />
    <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.7.1" />
    <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.6.0-rc.1" />

  </ItemGroup>

</Project>

The dotnet.csproj file is important for defining your project’s settings, including target framework, nullable reference types, and package references. It informs the .NET SDK and build tools about the components and configurations your project requires.

Core app

program.cs is the core of the .NET app. It uses ASP.NET to create a simple web server. The server has an endpoint /rolldice that returns a random number, simulating a basic API.

csharp
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Globalization;

// Set up the web app builder
var builder = WebApplication.CreateBuilder(args);
// Configure OpenTelemetry for detailed tracing information
TracingConfiguration.ConfigureOpenTelemetry();
var app = builder.Build();

// Map the GET request for '/rolldice/{player?}' to a handler
app.MapGet("/rolldice/{player?}", (ILogger<Program> logger, string? player) =>
{
    // Start a manual tracing activity
    using var activity = TracingConfiguration.StartActivity("HandleRollDice");

    // Call the RollDice function to get a dice roll result
    var result = RollDice();

    if (activity != null)
    {
        // Add detailed information to the tracing activity for debugging and monitoring
        activity.SetTag("player.name", player ?? "anonymous"); // Tag the player’s name, default to 'anonymous' if not provided
        activity.SetTag("dice.rollResult", result); // Tag the result of the dice roll
        activity.SetTag("operation.success", true); // Flag the operation as successful
        activity.SetTag("custom.attribute", "Additional detail here"); // Add a custom attribute for potential further detail
    }

    // Log the dice roll event
    LogRollDice(logger, player, result);

    // Retur the dice roll result as a string
    return result.ToString(CultureInfo.InvariantCulture);
});

// Start the web app
app.Run();

// Log function to log the result of a dice roll
void LogRollDice(ILogger logger, string? player, int result)
{
    // Log message varies based on whether a player’s name is provided
    if (string.IsNullOrEmpty(player))
    {
        // Log for an anonymous player
        logger.LogInformation("Anonymous player is rolling the dice: {result}", result);
    }
    else
    {
        // Log for a named player
        logger.LogInformation("{player} is rolling the dice: {result}", player, result);
    }
}

// Function to roll a dice and return a random number between 1 and 6
int RollDice()
{
    // Use the shared instance of Random for thread safety
    return Random.Shared.Next(1, 7);
}

Exporter

The tracing.cs file sets up the OpenTelemetry instrumentation. It configures the OTLP (OpenTelemetry Protocol) exporters for traces and initializes the ASP.NET SDK with automatic instrumentation capabilities.

csharp
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using System;
using System.Diagnostics;
using System.Reflection;

// Class to configure OpenTelemetry tracing
public static class TracingConfiguration
{
    // Declare an ActivitySource for creating tracing activities
    private static readonly ActivitySource ActivitySource = new("MyCustomActivitySource");

    // Configure OpenTelemetry with custom settings and instrumentation
    public static void ConfigureOpenTelemetry()
    {
        // Retrieve the service name and version from the executing assembly metadata
        var serviceName = Assembly.GetExecutingAssembly().GetName().Name ?? "UnknownService";
        var serviceVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "UnknownVersion";

        // Set up the tracer provider with various configurations
        Sdk.CreateTracerProviderBuilder()
            .SetResourceBuilder(
                // Set resource attributes including service name and version
                ResourceBuilder.CreateDefault().AddService(serviceName, serviceVersion: serviceVersion)
                .AddAttributes(new[] { new KeyValuePair<string, object>("environment", "development") }) // Additional attributes
                .AddTelemetrySdk() // Add telemetry SDK information to the traces
                .AddEnvironmentVariableDetector()) // Detect resource attributes from environment variables
            .AddSource(ActivitySource.Name) // Add the ActivitySource defined above
            .AddAspNetCoreInstrumentation() // Add automatic instrumentation for ASP.NET Core
            .AddHttpClientInstrumentation() // Add automatic instrumentation for HttpClient requests
            .AddOtlpExporter(options => // Configure the OTLP exporter
            {
                options.Endpoint = new Uri("https://AXIOM_DOMAIN/v1/traces"); // Set the endpoint for the exporter
                options.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.HttpProtobuf; // Set the protocol
                options.Headers = "Authorization=Bearer API_TOKEN, X-Axiom-Dataset=DATASET_NAME"; // Update API token and dataset
            })
            .Build(); // Build the tracer provider
    }

    // Method to start a new tracing activity with an optional activity kind
    public static Activity? StartActivity(string activityName, ActivityKind kind = ActivityKind.Internal)
    {
        // Starts and returns a new activity if sampling allows it, otherwise returns null
        return ActivitySource.StartActivity(activityName, kind);
    }
}
Info

Replace the value of the serviceName variable with the name of the service you want to trace. This is used for identifying and categorizing trace data, particularly in systems with multiple services.

Replace API_TOKEN with the Axiom API token you have generated. For added security, store the API token in an environment variable.

Replace DATASET_NAME with the name of the Axiom dataset where you send your data.

Replace AXIOM_DOMAIN with the base domain of your edge deployment. For more information, see Edge deployments.

Run the instrumented app

  1. Run in local development mode using the development settings in appsettings.development.json. Ensure your Axiom API token and dataset name are correctly set in tracing.cs.

  2. Before deploying, run in production mode by switching to appsettings.json for production settings. Ensure your Axiom API token and dataset name are correctly set in tracing.cs.

  3. Run your app with dotnet run. Your app starts and you can interact with it by sending requests to the /rolldice endpoint.

For example, if you are using port 8080, your app is accessible locally at http://localhost:8080/rolldice. This URL will direct your requests to the /rolldice endpoint of your server running on your local machine.

Observe the telemetry data

As you interact with your app, traces are collected and exported to Axiom where you can monitor and analyze your app’s performance and behavior.

  1. Log into your Axiom account and click the Datasets or Stream tab.

  2. Select your dataset from the list.

  3. From the list of fields, click the trace_id, to view your spans.

Dynamic OpenTelemetry Traces dashboard

The data can then be further viewed and analyzed in the traces dashboard, providing insights into the performance and behavior of your app.

  1. Log into your Axiom account, select Dashboards, and click the traces dashboard named after your dataset.

  2. View the dashboard which displays your total traces, incoming spans, average span duration, errors, slowest operations, and top 10 span errors across services.

Send data from an existing .NET project

Manual Instrumentation

Manual instrumentation involves adding code to create, configure, and manage telemetry data, such as traces and spans, providing control over what data is collected.

  1. Initialize ActivitySource. Define an ActivitySource to create activities (spans) for tracing specific operations within your app.
csharp
private static readonly ActivitySource MyActivitySource = new ActivitySource("MyActivitySourceName");
  1. Start and stop activities. Manually start activities (spans) at the beginning of the operations you want to trace and stop them when the operations complete. You can add custom attributes to these activities for more detailed tracing.
csharp
using var activity = MyActivitySource.StartActivity("MyOperationName");
activity?.SetTag("key", "value");
// Perform the operation here
activity?.Stop();
  1. Add custom attributes. Enhance activities with custom attributes to provide additional context, making it easier to analyze telemetry data.
csharp
activity?.SetTag("UserId", userId);
activity?.SetTag("OperationDetail", "Detail about the operation");

Automatic Instrumentation

Automatic instrumentation uses the OpenTelemetry SDK and additional libraries to automatically generate telemetry data for certain operations, such as incoming HTTP requests and database queries.

  1. Configure OpenTelemetry SDK. Use the OpenTelemetry SDK to configure automatic instrumentation in your app. This typically involves setting up a TracerProvider in your program.cs or startup configuration, which automatically captures telemetry data from supported libraries.

    csharp
    Sdk.CreateTracerProviderBuilder()
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        .AddOtlpExporter(options =>
        {
            options.Endpoint = new Uri("https://AXIOM_DOMAIN/v1/traces");
            options.Headers = $"Authorization=Bearer API_TOKEN, X-Axiom-Dataset=DATASET_NAME";
        })
        .Build();
    Info

    Replace API_TOKEN with the Axiom API token you have generated. For added security, store the API token in an environment variable.

    Replace DATASET_NAME with the name of the Axiom dataset where you send your data.

    Replace AXIOM_DOMAIN with the base domain of your edge deployment. For more information, see Edge deployments.

  2. Install and configure additional OpenTelemetry instrumentation packages as needed, based on the technologies your app uses. For example, to automatically trace SQL database queries, you might add the corresponding database instrumentation package.

  3. With automatic instrumentation set up, no further code changes are required for tracing basic operations. The OpenTelemetry SDK and its instrumentation packages handle the creation and management of traces for supported operations.

Reference

List of OpenTelemetry trace fields

Field CategoryField NameDescription
General Trace Information
_rowIdUnique identifier for each row in the trace data.
_sysTimeSystem timestamp when the trace data was recorded.
_timeTimestamp when the actual event being traced occurred.
trace_idUnique identifier for the entire trace.
span_idUnique identifier for the span within the trace.
parent_span_idUnique identifier for the parent span within the trace.
HTTP Attributes
attributes.http.request.methodHTTP method used for the request.
attributes.http.response.status_codeHTTP status code returned in response.
attributes.http.routeRoute accessed during the HTTP request.
attributes.url.pathPath component of the URL accessed.
attributes.url.schemeScheme component of the URL accessed.
attributes.server.addressAddress of the server handling the request.
attributes.server.portPort number on the server handling the request.
Network Attributes
attributes.network.protocol.versionVersion of the network protocol used.
User Agent
attributes.user_agent.originalOriginal user agent string, providing client software and OS.
Custom Attributes
attributes.custom["custom.attribute"]Custom attribute provided in the trace.
attributes.custom["dice.rollResult"]Result of a dice roll operation.
attributes.custom["operation.success"]Indicates if the operation was successful.
attributes.custom["player.name"]Name of the player in the operation.
Operational Details
durationTime taken for the operation.
kindType of span (for example, server, client, internal).
nameName of the span.
Resource Attributes
resource.custom.environmentEnvironment where the trace was captured, for example, development.
Telemetry SDK Attributes
telemetry.sdk.languageLanguage of the telemetry SDK, for example, dotnet.
telemetry.sdk.nameName of the telemetry SDK, for example, opentelemetry.
telemetry.sdk.versionVersion of the telemetry SDK, for example, 1.7.0.
Service Attributes
service.instance.idUnique identifier for the instance of the service.
service.nameName of the service generating the trace, for example, dotnet.
service.versionVersion of the service generating the trace, for example, 1.0.0.0.
Scope Attributes
scope.nameName of the scope for the operation, for example, OpenTelemetry.Instrumentation.AspNetCore.
scope.versionVersion of the scope, for example, 1.0.0.0.

List of imported libraries

OpenTelemetry

<PackageReference Include="OpenTelemetry" Version="1.7.0" />

This is the core SDK for OpenTelemetry in .NET. It provides the foundational tools needed to collect and manage telemetry data within your .NET apps. It’s the base upon which all other OpenTelemetry instrumentation and exporter packages build.

OpenTelemetry.Exporter.Console

<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.7.0" />

This package allows apps to export telemetry data to the console. It’s primarily useful for development and testing purposes, offering a simple way to view the telemetry data your app generates in real time.

OpenTelemetry.Exporter.OpenTelemetryProtocol

<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.7.0" />

This package enables your app to export telemetry data using the OpenTelemetry Protocol (OTLP) over gRPC or HTTP. It’s vital for sending data to observability platforms that support OTLP, ensuring your telemetry data can be easily analyzed and monitored across different systems.

OpenTelemetry.Extensions.Hosting

<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.7.0" />

Designed for .NET apps, this package integrates OpenTelemetry with the .NET Generic Host. It simplifies the process of configuring and managing the lifecycle of OpenTelemetry resources such as TracerProvider, making it easier to collect telemetry data in apps that use the hosting model.

OpenTelemetry.Instrumentation.AspNetCore

<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.7.1" />

This package is designed for instrumenting ASP.NET Core apps. It automatically collects telemetry data about incoming requests and responses. This is important for monitoring the performance and reliability of web apps and APIs built with ASP.NET Core.

OpenTelemetry.Instrumentation.Http

<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.6.0-rc.1" />

This package provides automatic instrumentation for HTTP clients in .NET apps. It captures telemetry data about outbound HTTP requests, including details such as request and response headers, duration, success status, and more. It’s key for understanding external dependencies and interactions in your app.

Was this page helpful?
Suggest edits on GitHub
On this page
Install dependenciesCore appExporterRun the instrumented appObserve the telemetry dataDynamic OpenTelemetry Traces dashboardSend data from an existing .NET projectManual InstrumentationAutomatic InstrumentationReferenceList of OpenTelemetry trace fieldsList of imported librariesOpenTelemetryOpenTelemetry.Exporter.ConsoleOpenTelemetry.Exporter.OpenTelemetryProtocolOpenTelemetry.Extensions.HostingOpenTelemetry.Instrumentation.AspNetCoreOpenTelemetry.Instrumentation.Http