# Diagnostics & OpenTelemetry

Every executed SQL statement automatically emits an OpenTelemetry activity (span) with database semantic-convention tags and records a duration histogram and command/error counters. Subscribe with a single AddSource/AddMeter.

## Overview

As of 0.2.0 the library instruments every SQL statement it executes: queries, inserts, updates, deletes, joins, set operations, stored procedures, migrations and DDL. For each command it emits:

- an OpenTelemetry **activity** (span) with database [semantic-convention](https://opentelemetry.io/docs/specs/semconv/database/) tags,
- a **duration histogram** plus command and error **counters**,
- one structured **log** message (see [Logging](/database/0.3.2/observability/logging)).

Tracing and metrics need no configuration beyond subscribing. The library exposes a single source/meter name.

## Enable tracing & metrics

Both the `ActivitySource` and `Meter` are named **`Socigy.OpenSource.DB`**. Register them with OpenTelemetry:

```csharp
builder.Services.AddOpenTelemetry()
    .WithTracing(t => t
        .AddSource("Socigy.OpenSource.DB")
        .AddOtlpExporter())
    .WithMetrics(m => m
        .AddMeter("Socigy.OpenSource.DB")
        .AddOtlpExporter());
```

The constants are also available in code as `SocigyDbInstrumentation.ActivitySourceName` and `SocigyDbInstrumentation.MeterName`.

## Span shape

Each command produces a client span named `"<OPERATION> (postgresql)"` (e.g. `SELECT (postgresql)`) with tags:

| Tag | Value |
|-----|-------|
| `db.system` | `postgresql` |
| `db.operation.name` | `SELECT` / `INSERT` / `UPDATE` / `DELETE` / `PROC` / `MIGRATE` / `DDL` / `SEQUENCE` |
| `db.query.text` | the executed SQL (unless command-text capture is disabled) |
| `db.query.parameters` | parameter names + types (values only when explicitly enabled; see [Logging](/database/0.3.2/observability/logging)) |
| `db.response.affected_rows` | rows affected (writes) |
| `db.response.returned_rows` | rows read (streamed reads) |

For reads the span stays open for the whole enumeration, so its duration reflects time-to-drain and `db.response.returned_rows` is accurate.

When you use [ExecuteTransactionAsync](/database/0.3.2/core-concepts/database-context), a parent `TRANSACTION (postgresql)` span wraps the commands, giving you a clean BEGIN…COMMIT trace.

## Metrics

| Instrument | Type | Unit | Meaning |
|-----------|------|------|---------|
| `db.client.operation.duration` | histogram | `s` | Duration of each command. |
| `socigy.db.commands` | counter | `{command}` | Commands executed. |
| `socigy.db.command.errors` | counter | `{error}` | Commands that threw. |

Each measurement is tagged with `db.operation.name`.

## Errors

When a command throws, its span status is set to `Error`, an exception event is recorded, and `socigy.db.command.errors` is incremented before the exception propagates.

> **NOTE** These types come from `System.Diagnostics.DiagnosticSource`, which is part of the .NET shared framework on net6.0+. The package declares it (and `Microsoft.Extensions.Logging.Abstractions`) as dependencies so non-web consumers also resolve them.
