AutoInstrument 1.0.0
See the version list below for details.
dotnet add package AutoInstrument --version 1.0.0
NuGet\Install-Package AutoInstrument -Version 1.0.0
<PackageReference Include="AutoInstrument" Version="1.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="AutoInstrument" Version="1.0.0" />
<PackageReference Include="AutoInstrument"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add AutoInstrument --version 1.0.0
#r "nuget: AutoInstrument, 1.0.0"
#:package AutoInstrument@1.0.0
#addin nuget:?package=AutoInstrument&version=1.0.0
#tool nuget:?package=AutoInstrument&version=1.0.0
AutoInstrument
[Instrument] for .NET - add an attribute, get OpenTelemetry spans with tagged parameters at every call-site. Inspired by Rust's #[instrument].
[Instrument]
public async Task<string> ShaveYak(int yakId, string style)
{
await Task.Delay(50);
return $"Yak #{yakId} shaved with {style}";
}
Under the hood, the source generator emits C# interceptors that wrap each call-site with an Activity, tag parameters, and record exceptions. Your method is never modified.
Setup
Add the package and enable interceptors:
<PropertyGroup>
<InterceptorsNamespaces>$(InterceptorsNamespaces);AutoInstrument.Generated</InterceptorsNamespaces>
</PropertyGroup>
using AutoInstrument;
[Instrument]
public async Task<Order> ProcessOrder(int orderId, string customer) { ... }
[Instrument(Skip = new[] { "creditCard" })]
public async Task ChargeCustomer(int orderId, string creditCard) { ... }
[Instrument(Name = "orders.compute_total", RecordReturnValue = true)]
public decimal ComputeTotal(List<LineItem> items) => items.Sum(i => i.Price * i.Quantity);
Options
| Property | Default | Description |
|---|---|---|
Name |
Class.Method |
Span name |
Skip |
— | Parameters/properties to exclude from tags |
Fields |
— | Whitelist - only these become tags |
ActivitySourceName |
Assembly name | Custom ActivitySource name |
RecordReturnValue |
false |
Tag the return value |
RecordException |
true |
Record exceptions on the span |
Kind |
0 (Internal) |
ActivityKind (0=Internal, 1=Server, 2=Client, 3=Producer, 4=Consumer) |
RecordSuccess |
false |
Set status Ok on success |
IgnoreCancellation |
true |
Don't record OperationCanceledException as errors |
Condition |
— | Boolean member name - skip instrumentation when false |
LinkTo |
— | Parameter name (must be ActivityContext) to attach as ActivityLink |
Skip and Fields support dot-notation for complex type properties: Skip = new[] { "order.CreditCard" }.
Parameter attributes
[NoInstrument] on a parameter skips it from tagging. Pass property names to skip specific properties of a complex type:
public void Login(string user, [NoInstrument] string password) { ... }
public void Process([NoInstrument("CreditCard", "SSN")] Order order) { ... }
Member tags
[Tag] on a field or property includes it as a span tag on all [Instrument] methods in the class:
public class OrderService
{
[Tag] public string Region { get; set; }
[Tag(Name = "env")] public string Environment { get; set; }
[Instrument]
public void Process(int orderId) { ... }
// Tags: process.orderid, region, env
}
Complex types
Classes and structs are expanded one level deep into their public properties:
[Instrument]
public void Process(Order order, int priority) { ... }
// Tags: process.order.id, process.order.customer, process.order.creditcard, process.priority
Configuration
The ActivitySource name defaults to the assembly name. Override at three levels (highest priority wins):
- Per-method:
[Instrument(ActivitySourceName = "X")] - MSBuild:
<AutoInstrumentSourceName>X</AutoInstrumentSourceName> - Assembly attribute:
[assembly: AutoInstrumentSource("X")]
Tag naming defaults to methodname.param. Set it to Flat for just param:
[assembly: AutoInstrumentConfig(TagNaming = TagNamingConvention.Flat)]
Or via MSBuild: <AutoInstrumentTagNaming>Flat</AutoInstrumentTagNaming>
Diagnostics
| ID | Description |
|---|---|
| AUTOINST001 | Skip references unknown parameter |
| AUTOINST002 | Fields references unknown parameter |
| AUTOINST003 | Dot-notation references unknown property |
| AUTOINST004 | Condition is not a boolean member |
| AUTOINST005 | LinkTo is not an ActivityContext parameter |
| AUTOINST006 | [NoInstrument] references unknown property |
Limitations
- Interceptors only work within the same compilation — cross-project calls aren't intercepted.
- Recursive calls create nested spans.
- Complex types expand one level deep only.
Requirements
.NET 10
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.