---
title: .NET Observability with OpenTelemetry | Pydantic Logfire
description: >-
  Send .NET traces to Pydantic Logfire with the standard OpenTelemetry exporter
  and built-in ActivitySource, then query traces, metrics, and logs with SQL.
canonical: 'https://pydantic.dev/logfire/dotnet'
---

> Markdown version of [Trace, monitor and debug your .NET app](https://pydantic.dev/logfire/dotnet) — the canonical HTML page.
>
> Site index: [/llms.txt](https://pydantic.dev/llms.txt)

---

# Trace, monitor and debug your .NET app

Logfire for .NET

.NET Observability from the team behind Pydantic: export ActivitySource spans, keep instrumentation vendor-neutral, and query everything in plain SQL. Standard OpenTelemetry, no lock-in.

[Try Logfire for free](https://logfire.pydantic.dev/login?intent=signup) [See the .NET docs](https://pydantic.dev/docs/logfire/instrument/dotnet/)

Set up Logfire with your coding agent:

uvx logfire-cli wizard

Install and configure

```bash
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
```

Configure exporter

```bash
export OTEL_EXPORTER_OTLP_ENDPOINT='https://logfire-us.pydantic.dev'
export OTEL_EXPORTER_OTLP_HEADERS='Authorization=your-write-token'
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
```

Instrument your app

View code

```csharp
var activitySource = new ActivitySource("hello-dotnet");

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddSource("hello-dotnet")
    .ConfigureResource(r => r.AddService("hello-dotnet"))
    .AddOtlpExporter()
    .Build();

using var activity = activitySource.StartActivity("hello");
```

Full details are in the [.NET setup guide](https://pydantic.dev/docs/logfire/instrument/dotnet/).

Trusted by teams building production software and AI

**Customers:** Motorola, Sophos, Airbyte, Pictet, Vox Media, Weaviate, Amboss, Tiger Data

What you get

## One request, one trace

![A Logfire trace of an ASP.NET Core request: the endpoint, Npgsql queries and the outbound call, with an errored request below](https://pydantic.dev/assets/logfire/language-traces/dotnet-trace.png)

**What lands in Logfire:**

* the `Microsoft.AspNetCore` request span, with route and status
* every `Npgsql` query against Postgres, timed
* your own `ActivitySource` spans, nested underneath
* the outbound `System.Net.Http` call
* a 404 marked red, at the span that produced it
* GC heap size, lock contention and thread-pool queue length, as metrics beside the spans

Try it on your stack

## See your own .NET trace

Start free with 10 million spans, logs, and metrics each month. No credit card required.

[Start free](https://logfire.pydantic.dev/login?intent=signup) [Read the .NET setup guide](https://pydantic.dev/docs/logfire/instrument/dotnet/)

How it works

## Standard OpenTelemetry, hosted backend

### Use ActivitySource, not a vendor type

System.Diagnostics.ActivitySource is .NET's built-in tracing API and is what OpenTelemetry consumes directly. Instrumentation you write against it is portable by construction: nothing in your code references Logfire, so nothing has to be undone if you change backends.

### ASP.NET Core instrumentation is a package, not a rewrite

Add the OpenTelemetry ASP.NET Core instrumentation and incoming requests become spans automatically, with route, status, and timing attached. Contrib packages also cover HttpClient, Entity Framework Core, SQL Client, and gRPC. Your own ActivitySource spans nest inside the request span, so a slow endpoint and the work that made it slow appear in one trace.

### Standard OTLP, so genuinely no lock-in

Everything is configured through OTEL\_ environment variables and the standard exporter. Repoint at another OpenTelemetry backend, or at your own collector, without touching a line of application code.

### Microsoft Agent Framework and Semantic Kernel

Building agents on .NET? Microsoft Agent Framework (Microsoft.Agents.AI) and Semantic Kernel both send their agent and model telemetry to Logfire, so agent runs sit in the same traces as the requests and queries around them. Both go through the standard OpenTelemetry .NET SDK and an OTLP exporter, so there is still no vendor SDK in your project.

### The .NET signals stay together

Keep ActivitySource spans, Meter metrics, and ILogger records in one Logfire project. Shared resource attributes keep service identity consistent across them, so the service you filter in a trace search is the same one you chart or alert on.

### SQL instead of a query language you have to learn

Use PostgreSQL-compatible SQL to investigate ASP.NET routes, dependencies, tenants, or any attribute your application records. Save the result as a dashboard or alert when it becomes an operational question you ask repeatedly.

Query

## Query your .NET telemetry with SQL

If you can ask it, SQL can find out

* Query your traces, metrics and logs with real SQL
* No proprietary query language to learn
* AI models are great at writing SQL
* From a one-off investigation to an alert, dashboard, or SLO

```sql
select
  attributes->>'http.route' as route,
  count(*) as requests,
  avg(duration) as avg_seconds
from records
where duration > 1
group by route
order by avg_seconds desc;
```

Proof

## In production

> You can tell that Pydantic Logfire was built by people who use it.

Dennis Griffin, VP of Engineering, Sophos [Read the case study](https://pydantic.dev/case-studies/sophos)

Decision guide

## Is Logfire right for you?

### Choose Logfire if

* You already use ActivitySource and want a hosted backend for it
* You want no vendor-specific types in your .NET codebase
* You want to query traces, metrics, and logs with PostgreSQL-compatible SQL
* You do not want to run Jaeger, Prometheus, and storage yourself
* You want the option to repoint at another backend without a rewrite

### Choose a vendor APM if

* You want a vendor-maintained .NET SDK with vendor-specific APIs
* You are already deeply integrated with a specific APM vendor's ecosystem
* You need a vendor-only integration or compliance capability Logfire does not offer

FAQ

## Common questions

### Is there a Logfire SDK for .NET?

No, and .NET needs one less than most languages. Tracing primitives live in the base class library as System.Diagnostics.ActivitySource, which is the OpenTelemetry API in practice. You add the standard OpenTelemetry OTLP exporter and point it at Logfire. First-party Logfire SDKs exist for Python, TypeScript, and Rust.

### Why is nothing arriving in Logfire?

Two usual causes. First, protocol: set OTEL\_EXPORTER\_OTLP\_PROTOCOL to http/protobuf, because the OpenTelemetry .NET default can be gRPC, which Logfire does not expect. Second, source names: the string passed to AddSource must match the name given to the ActivitySource you create, or every span is silently dropped with no error.

### Does this work with ASP.NET Core?

Yes. Add the OpenTelemetry ASP.NET Core instrumentation package and incoming HTTP requests become spans automatically, without changing your controllers. Your own ActivitySource spans then nest inside those request spans.

### Do I need to change how I write code?

No. You use ActivitySource and Activity from System.Diagnostics, which are standard .NET types rather than anything vendor-specific. The instrumentation you write is portable to any OpenTelemetry-compatible backend.

### Am I locked in to Logfire?

No. Configuration is standard OTEL\_ environment variables and the standard exporter, and your code references only base class library types. Repoint the endpoint at another OpenTelemetry-compatible backend, or at your own collector, at any time.

## Start seeing your .NET app

Get started with 10 million free spans, logs, and metrics per month. No credit card required.

* [Start free](https://logfire.pydantic.dev/login?intent=signup)
* [Book a demo](https://pydantic.dev/contact)
* [View pricing plans](https://pydantic.dev/pricing)
