Skip to content
Purview Dev logo

Logging

Stable Telemetry SourceGenerator Reviewed 2026-09-16 purview-dev/telemetry-sourcegenerator Star on GitHub 36 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

There are two distinct generated types for ILogger-based generation.

To signal an interface for logging generation, decorate it with the [Logger] attribute. To signal a method, use [Log] (or one of the semantic level attributes). All logging attributes live in the Purview.Telemetry namespace.

Generation v1Generation v2
ImplementationLoggerMessage/LoggerMessage.Define high-performance loggingState-based output resembling the built-in [LoggerMessage] generator
Parameter limitMaximum 6 non-exception parameters plus one optional ExceptionNo fixed parameter limit
[ExpandEnumerable]No effectSupported
[LogProperties]No effectSupported
Required referenceMicrosoft.Extensions.LoggingMicrosoft.Extensions.Telemetry.Abstractions

The default LoggerGenerationMode.Auto selects the mode per method:

  • v1 is used when the method is within the v1 limits (≤ 6 non-exception parameters, at most one Exception, and no [ExpandEnumerable] or [LogProperties] parameters).
  • v2 is used when the method needs it (more than 6 parameters, [ExpandEnumerable], or [LogProperties]), which requires Microsoft.Extensions.Telemetry.Abstractions.

You can force a mode with the GenerationMode property:

  • [Log].GenerationMode — per method
  • [Logger].GenerationMode — per interface
  • [LoggerGeneration].GenerationMode — per assembly
// Force v2 for one method
[Logger]
interface IOrderServiceTelemetry
{
[Info(GenerationMode = LoggerGenerationMode.V2)]
void OrderPlaced(int orderId, string customerName);
}

Define the EXCLUDE_PURVIEW_TELEMETRY_LOGGING constant to ignore the logging attributes entirely:

<!-- In a .csproj or Directory.Build.props -->
<PropertyGroup>
<DefineConstants>EXCLUDE_PURVIEW_TELEMETRY_LOGGING</DefineConstants>
</PropertyGroup>

This is primarily used when the ILogger type is unavailable — without it your project will fail to compile because the generated attributes reference related types such as LogLevel.

Return IDisposable/IDisposable? from a log method to generate a scoped log entry:

[Logger]
interface IOrderServiceTelemetry
{
[Info]
IDisposable? ProcessingOrder(Guid orderId);
}

When a method returns IDisposable?, the entry is emitted when the scope is created and the duration is logged when it is disposed. A scoped method should not specify an explicit level (TSG2007 warns if it does, since the level is ignored).