Skip to content

Tagattribute

Stable Telemetry SourceGenerator Reviewed 2026-09-01 purview-dev/telemetry-sourcegenerator activity c-sharp distributed-tracing dotnet events high-performance-logging instrumentation logging melt metrics nuget observability open-telemetry open-telemetry-csharp otel roslyn source-generator spans telemetry tracing

The TagAttribute is used within Activity and Metric generation to specify how parameters are added as tags.

In v4, tag names follow the configured NamingConvention:

  • OpenTelemetry (default): Uses snake_case for compound words (e.g., "entity_id")
  • Legacy: Uses lowercase smashed format (e.g., "entityid")
Name Type Default Description
Name string? null Explicitly sets the name of the tag. When null, the parameter name is used (and transformed according to NamingConvention).
SkipOnNullOrEmpty bool false When true, the tag is not added if the parameter value is null or default.
using Purview.Telemetry;
[ActivitySource("OrderService")]
interface IOrderTelemetry
{
[Activity]
Activity? ProcessingOrder(
// Auto-named tag (becomes "order_id" in OpenTelemetry mode)
[Tag]int orderId,
// Explicitly named tag
[Tag(Name = "customer.name")]string customerName,
// Skip if null
[Tag(SkipOnNullOrEmpty = true)]string? notes
);
}

The tag name generation depends on the NamingConvention setting:

OpenTelemetry Convention (default):

[Tag]int orderId // Generated: "order_id"
[Tag]string userName // Generated: "user_name"
[Tag(Name = "my.custom.tag")]int value // Generated: "my.custom.tag" (explicit names not transformed)

Legacy Convention:

[Tag]int orderId // Generated: "orderid"
[Tag]string userName // Generated: "username"

To change the convention, see Generation - Naming Conventions.

  1. Use explicit names for cross-service tags - Prevents issues if parameter names change:

    [Tag(Name = "trace.id")]string traceId
  2. Use SkipOnNullOrEmpty for optional tags - Avoids cluttering telemetry with null values:

    [Tag(SkipOnNullOrEmpty = true)]string? optionalContext
  3. Follow OpenTelemetry semantic conventions - Use standard names like http.method, http.status_code, service.name:

    [Tag(Name = "http.method")]string method
    [Tag(Name = "http.status_code")]int statusCode
  4. Compound words: Let v4’s OpenTelemetry mode handle it automatically:

    // Good - auto-transforms to "customer_id"
    [Tag]int customerId
    // Also good - explicit naming
    [Tag(Name = "customer.id")]int id