Skip to content
Purview Dev logo

Diagnostics

Stable Telemetry SourceGenerator Reviewed 2026-10-28 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

The package ships a single Roslyn analyzer, TelemetryDiagnosticAnalyzer, which validates telemetry interfaces and raises diagnostics with the TSG prefix. All diagnostics are grouped by category.

  • General — TSG1xxx
  • Logging — TSG2xxx
  • Activities — TSG3xxx
  • Metrics — TSG4xxx
IDSeverityDescription
TSG1000ErrorFatal execution error occurred (Failed to execute the generation stage: {0}). Raised by the generator itself when an unexpected exception escapes the pipeline.
TSG1001ErrorInferring generation targets is not supported when using multi-target generation. A method on a multi-target interface has no explicit generation attribute.
TSG1002ErrorMultiple attributes from the same target family are not supported. Only one Activity, Logging, or Metrics attribute is allowed per method.
TSG1003ErrorDuplicate method names are not supported. Two or more methods on the interface share the same name.
TSG1004ErrorGeneric interfaces are not supported.
TSG1005ErrorGeneric methods are not supported.
TSG1006WarningExcludeTargets references a target not present on this method.
TSG1007WarningExcludeTargets results in an empty or invalid parameter set for a target.
TSG1008WarningActivity parameter has no Activity target. A parameter of type Activity is present on a method with no [Activity]/[Event]/[Context] attribute.
TSG1010ErrorMethod target not registered on interface. A method carries an attribute for a target family that is not registered on the interface.
TSG1011ErrorUnsupported target framework. The compilation targets neither .NET 8+ nor .NET Framework 4.8+ (for example netstandard2.0), so no telemetry is generated for it. There is no opt-out. Target net8.0 or later, or net48 or later; a multi-targeted library references the package only from its supported targets (a Condition on the PackageReference), with the telemetry interfaces under the same condition. See Platform Support.
IDSeverityDescription
TSG2000ErrorToo many exception parameters. A non-scoped log method has more than one Exception-typed parameter.
TSG2001ErrorMore than 6 parameters. A log method in v1 generation mode has more than 6 non-exception parameters.
TSG2002InfoInferring error log level. In v1 generation, a single Exception parameter is present with no explicit level, so Error is inferred.
TSG2003WarningCould not find a reference to Microsoft.Extensions.Logging.ILogger, skipping log generation.
TSG2004ErrorCannot mix ordinal and named property placeholders in a message template.
TSG2005ErrorOrdinal values exceed parameter count. The maximum ordinal placeholder value exceeds the number of provided parameters.
TSG2006ErrorUsing [LogProperties] and [ExpandEnumerable] on the same parameter is not supported.
TSG2007WarningA scoped log shouldn’t have a LogLevel; it will be ignored.
TSG2008WarningUnbounded enumeration possible. [ExpandEnumerable] has a MaximumValueCount greater than the recommended default of 5.
TSG2021ErrorLog method must return void or IDisposable. (Returning Activity is allowed when the method is also an Activity method.)
IDSeverityDescription
TSG3000WarningBaggage parameter types only accept strings (ToString() will be called).
TSG3001WarningNo activity source specified. Generation defaults to purview when no name is available anywhere.
TSG3002ErrorInvalid return type. An Activity/Event method returns something other than void or System.Diagnostics.Activity.
TSG3003ErrorDuplicate reserved parameters defined. More than one parameter maps to the same reserved destination.
TSG3004ErrorActivity parameter is not valid. An Activity-destination parameter appears on an Activity method (only valid on [Event] methods).
TSG3005ErrorTimestamp parameter is not valid. A timestamp parameter appears on a method that is not an [Event] method.
TSG3006ErrorStart time parameter is not valid on Create activity or Event method.
TSG3007ErrorParent context or Parent Id parameter is not valid on event.
TSG3008ErrorActivity links parameters are not valid on events or context methods.
TSG3009ErrorActivity tags parameter is not valid on context methods.
TSG3010ErrorEscaped parameters must be a boolean.
TSG3011ErrorEscaped parameters are only valid on Events, not Activity or Context methods.
TSG3012InfoThere are no Activity methods defined, assumed use of Activity.Current.
TSG3013WarningShould return the created Activity. An Activity method does not return the created Activity.
TSG3014WarningShould accept an Activity to apply the Event/Tags/Baggage to. An Event/Context method has no Activity parameter. Opt-in via ActivitySourceGeneration.GenerateDiagnosticsForMissingActivity (default true).
TSG3015InfoActivity should be the first parameter. Opt-in via GenerateDiagnosticsForMissingActivity.
TSG3016ErrorStatus description parameter should be a string.
TSG3017ErrorStatus Description parameters are only valid on Events, not Activity or Context methods.
TSG3021InfoException event does not use OpenTelemetry standard name. An [Event] method records an exception under the OpenTelemetry exception rules but the event name is not the standard "exception" (suggest [Event(Name = "exception")]). Not raised when UseRecordExceptionRules is disabled, for [Baggage] exceptions, or when the exception parameter is excluded from the Activities target.
TSG3022WarningActivity return type should be nullable. An Activity method returns non-nullable Activity; use Activity? because the Activity can be null when no listeners are active.
TSG3023WarningActivitySourceFactory is not available. UseActivitySourceFactory is set but System.Diagnostics.ActivitySourceFactory (.NET 11, or System.Diagnostics.DiagnosticSource 11+) cannot be resolved; a static ActivitySource is generated instead.
IDSeverityDescription
TSG4000ErrorNo instrument defined. A method on a Metrics interface has no instrument attribute and is not excluded.
TSG4001ErrorMust return void or bool. A metrics-owned method returns something other than void or bool.
TSG4002ErrorAuto increment counter and measurement defined. An auto-increment instrument also has a measurement parameter.
TSG4003ErrorMultiple measurement values defined.
TSG4004ErrorNo measurement value defined. A non-auto-increment instrument method has no measurement parameter.
TSG4005ErrorObservable instrument requires Func<T>.
TSG4006ErrorInvalid measurement type. Not one of byte, short, int, long, double, float, decimal, Measurement<T>, or IEnumerable<Measurement<T>>.
TSG4007ErrorObservable metrics cannot return bool.
TSG4008ErrorAutoCounter must return void.
TSG4009WarningInstrument name matches the instrument type name. Use a name that describes what is measured.

TSG1001 — inference disabled on multi-target interfaces

Section titled “TSG1001 — inference disabled on multi-target interfaces”

A method on a multi-target interface ([ActivitySource] + [Logger] + [Meter]) has no explicit attribute. Add the attributes for each target the method should emit, or mark it [Exclude].

[ActivitySource("MyApp")]
[Logger]
[Meter]
interface IMyTelemetry
{
[Info] // ✅ explicit target
void ProcessItem(int id);
}

Two or more methods share the same name, which is used to generate members on the implementation class. Rename the methods.

[ExpandEnumerable] is configured with a MaximumValueCount greater than 5. Reduce it to the recommended default (5) unless you have tested the performance impact.

An Activity method does not return the created Activity, or an Event/Context method has no Activity parameter. Return the Activity/Activity? and pass it to Event/Context methods. These best-practice diagnostics are controlled by ActivitySourceGeneration.GenerateDiagnosticsForMissingActivity.

Rename the event with [Event(Name = "exception")] so the OpenTelemetry exception tags (exception.type, exception.message, exception.stacktrace, exception.escaped) are attached to that event instead of a separate event named exception.

[Event(Name = "exception")] // ✅ the event carries the exception tags
void FailedToRetrieve(Activity? activity, Exception exception);

A Name set on a logging attribute does not name the event — it renames the log entry:

[Event] // ❌ event name is the method name
[Error(Name = "exception")] // the log entry is named 'exception'
void FailedToRetrieve(Activity? activity, Exception exception);

The diagnostic is not raised when the exception is not recorded using the OpenTelemetry exception rules: [Event(UseRecordExceptionRules = false)], a [Baggage] exception parameter, or an exception parameter excluded from the Activities target ([ExcludeTargets(Targets.Activities)]).

Return Activity? so callers can handle the null case when no listeners are active.

TSG3023 — ActivitySourceFactory is not available

Section titled “TSG3023 — ActivitySourceFactory is not available”

[assembly: ActivitySourceGeneration(..., UseActivitySourceFactory = true)] asks for sources created by System.Diagnostics.ActivitySourceFactory, but the compilation cannot resolve that type, so a static ActivitySource is generated instead. Target net11.0, or reference System.Diagnostics.DiagnosticSource 11 or later; or remove the option. See Creating sources with ActivitySourceFactory.

TSG4002 — auto-increment counter with a measurement

Section titled “TSG4002 — auto-increment counter with a measurement”

[AutoCounter] (or [Counter(AutoIncrement = true)]) must not declare a measurement parameter — the measurement is fixed to 1.