Skip to content
Purview Dev logo

Activities

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

All activity-related attributes live in the Purview.Telemetry namespace. To signal an interface for Activity generation, decorate it with the [ActivitySource] attribute.

In v5 the ActivitySource name defaults to the assembly name with casing preserved (OpenTelemetry convention). You can override it at the interface or assembly level:

  • Interface: ActivitySourceAttribute.Name
  • Assembly: ActivitySourceGenerationAttribute.Name

Creating sources with ActivitySourceFactory (.NET 11)

Section titled “Creating sources with ActivitySourceFactory (.NET 11)”

By default each generated class owns a static readonly ActivitySource. .NET 11 adds ActivitySourceFactory, the tracing counterpart of IMeterFactory: registered by services.AddTracing() (Microsoft.Extensions.Diagnostics 11), it creates local sources that the container owns and that AddTracing rules can enable or disable. Opt in at the assembly level:

[assembly: ActivitySourceGeneration("MyApp.Orders", UseActivitySourceFactory = true)]

The generated class then takes an ActivitySourceFactory constructor parameter (after ILogger<T> and IMeterFactory, when the interface also targets logging or metrics) and creates its source with activitySourceFactory.Create(new ActivitySourceOptions(name)). Register the factory before resolving the telemetry:

builder.Services.AddTracing();
builder.Services.AddOrderTelemetry();
  • The factory owns the source; the generated class never disposes it.
  • The option is opt-in because it changes the generated constructor. Without it, nothing changes when you move to .NET 11.
  • It is gated on the compilation, not the target framework: it needs System.Diagnostics.ActivitySourceFactory, which ships in .NET 11 and in the System.Diagnostics.DiagnosticSource 11 package (net462, netstandard2.0, net10.0). When the type cannot be resolved the generator keeps the static source and reports TSG3023.
  • Listeners registered with ActivitySource.AddActivityListener (OpenTelemetry’s included) still see factory-created sources.

There are three method types:

  1. Activity methods that generate either a started or un-started Activity.
  2. Event methods that generate an ActivityEvent attached to an Activity.
  3. Context methods that add either tags or baggage to the current Activity.

Decorate the method with the [Activity] attribute to explicitly define an Activity method. Parameters can be passed directly to ActivitySource.CreateActivity or ActivitySource.StartActivity:

  • tags — the parameter type must be an ActivityTagsCollection, IEnumerable<KeyValuePair<string, object?>>, or TagList.
  • parentContext — the parameter type must be ActivityContext.
  • parentId — the parameter must be named parentId with type string.
  • links — the parameter type must be an IEnumerable<ActivityLink>.
  • startTime — the parameter must be named startTime with type DateTimeOffset.

Other parameters can be marked with [Tag] or [Baggage] to specify where they are applied. The return type must be void, Activity, or Activity?; returning the Activity returns the created or started Activity.

Decorate the method with the [Event] attribute to generate a method that creates an ActivityEvent and attaches it to the specified Activity or Activity.Current. To specify an Activity explicitly, the parameter type must be Activity or Activity?.

The tags collection can be populated with a parameter of type ActivityTagsCollection, IEnumerable<KeyValuePair<string, object?>>, or TagList. To specify the timestamp, name the parameter timestamp with type DateTimeOffset.

The return type must be void, Activity, or Activity?. When returning an Activity, either the one specified as a parameter is used, or Activity.Current.

When an Exception parameter is present, the default behaviour follows the OpenTelemetry exception rules: an event named exception is added with the following tags:

  • exception.escaped — true by default; override it by decorating a bool parameter with [Escape].
  • exception.message — the value of Exception.Message.
  • exception.stacktrace — the value of Exception.StackTrace.
  • exception.type — the Type.FullName of the exception.

This behaviour can be overridden with the EventAttribute options (see below). The standard exception event is only required when the exception is recorded with the OpenTelemetry rules: naming the event exception with [Event(Name = "exception")] attaches the tags above to that event instead of adding a separate one, and TSG3021 suggests doing so when the name differs. The diagnostic and the standard name do not apply when UseRecordExceptionRules is false, when the exception is a [Baggage] parameter, or when the parameter is excluded from the Activities target with [ExcludeTargets(Targets.Activities)].

Decorate the method with the [Context] attribute to generate a method that populates tags and/or baggage on a specified Activity or Activity.Current. Parameters are marked with [Tag] or [Baggage]. The return type must be void, Activity, or Activity?.

On a single-target Activities interface you can skip the method-level attribute:

  • If the method name ends with Event (case-sensitive), it is treated as an Event.
  • If the first parameter is an Activity, it is treated as an Event.
  • If the method name ends with Context (case-sensitive), it is treated as a Context.
  • Anything else defaults to creating an Activity.

If you decorate a parameter with [Tag] or [Baggage], that stops inference. Any undecorated parameter is treated as a tag or baggage based on the default settings:

  • ActivitySourceAttribute.DefaultToTags (interface) — true means tags, false means baggage. Default true.
  • ActivitySourceGenerationAttribute.DefaultToTags (assembly) — same. Default true.

See also Tags, Baggage, and Parameter Attributes.

Defines Activity creation on a method.

PropertyTypeDescription
Namestring?The name of the Activity. If not provided, the method name is used. Available on construction.
KindActivityKindThe kind used to create the Activity. Default Internal. Available on construction.
CreateOnlyboolWhether the created Activity is started or not. Default false. When true, you must return the Activity/Activity? from the method.

Defines the creation of the ActivitySource on an interface.

PropertyTypeDescription
Namestring?The ActivitySource name. If not provided, ActivitySourceGenerationAttribute.Name is used, then the assembly name. A warning (TSG3001) is generated when no custom name is defined anywhere. Available on construction.
DefaultToTagsboolWhether undecorated parameters are added as tags (true) or baggage (false). Special-case parameters are matched first. Default true.
BaggageAndTagPrefixstring?Prefix for tag/baggage names. Useful for grouping. Default null.
IncludeActivitySourcePrefixboolWhether the ActivitySourceGenerationAttribute.BaggageAndTagSeparator is used to generate a prefix. Default true.
LowercaseBaggageAndTagKeysboolWhether tag/baggage names are lower-cased. Default true.

Defines ActivitySource defaults at the assembly level.

PropertyTypeDescription
NamestringDefault ActivitySource name when none is defined on an interface.
DefaultToTagsboolWhether undecorated parameters are tags (true) or baggage (false). Default true.
BaggageAndTagPrefixstring?Prefix for tag/baggage names. Default null.
BaggageAndTagSeparatorstringSeparator used when generating prefixes. Default ..
LowercaseBaggageAndTagKeysboolWhether tag/baggage names are lower-cased. Default true.
GenerateDiagnosticsForMissingActivityboolWhether diagnostics (TSG3014/TSG3015) are raised when Activity parameters or return values are missing. Default true.
UseActivitySourceFactorybool.NET 11: create each generated source from the injected System.Diagnostics.ActivitySourceFactory instead of a static ActivitySource (see below). Default false.

Marks a parameter as baggage on an Activity or Event.

PropertyTypeDescription
Namestring?The baggage name. Defaults to null, meaning the parameter name is used.
SkipOnNullOrEmptyboolWhether the parameter is skipped when it is null or default. Default false.

Marks a method as adding parameters as tags or baggage to an Activity. There are no properties.

Marks a string parameter as the status description for an Activity Event — typically used with events that set an error status code.

[ActivitySource("MyApp")]
interface IMyTelemetry
{
[Event]
void OperationFailed(
Activity? activity,
[StatusDescription]string failureReason
);
}

The parameter must be of type string, and this attribute is only valid on Event methods, not Activity or Context methods.

Marks a bool parameter as the escape value on an event-based method. See the OpenTelemetry exception rules.

Defines a method that creates an ActivityEvent.

PropertyTypeDescription
Namestring?The name of the event. If not provided, the method name is used. Available on construction.
StatusCodeActivityStatusCodeSets the status code on the Activity after the event is added. Default Unset. Available on construction. When set to Error, the status description is sourced (in order of precedence) from a [StatusDescription]-marked parameter, the StatusDescription property, the first Exception parameter’s Message, or null.
StatusDescriptionstring?A static description for the StatusCode when set to Error. Overridden by a [StatusDescription]-marked parameter if present.
UseRecordExceptionRulesboolWhether the OpenTelemetry exception rules are followed when a parameter is an Exception. Default true.
RecordExceptionAsEscapedboolThe value used for exception.escaped when UseRecordExceptionRules is true and an exception is present. Overridable with [Escape]. Default true.