Rig.TUnit.Observability.Metrics
0.1.0-beta.2
dotnet add package Rig.TUnit.Observability.Metrics --version 0.1.0-beta.2
NuGet\Install-Package Rig.TUnit.Observability.Metrics -Version 0.1.0-beta.2
<PackageReference Include="Rig.TUnit.Observability.Metrics" Version="0.1.0-beta.2" />
<PackageVersion Include="Rig.TUnit.Observability.Metrics" Version="0.1.0-beta.2" />
<PackageReference Include="Rig.TUnit.Observability.Metrics" />
paket add Rig.TUnit.Observability.Metrics --version 0.1.0-beta.2
#r "nuget: Rig.TUnit.Observability.Metrics, 0.1.0-beta.2"
#:package Rig.TUnit.Observability.Metrics@0.1.0-beta.2
#addin nuget:?package=Rig.TUnit.Observability.Metrics&version=0.1.0-beta.2&prerelease
#tool nuget:?package=Rig.TUnit.Observability.Metrics&version=0.1.0-beta.2&prerelease
Rig.TUnit.Observability.Metrics
In-process
MeterListener-based metrics capture withMetricAssertandTagCardinalityGuard.
What this package is
A metrics testing fixture for System.Diagnostics.Metrics.
MetricsFixture creates a MeterListener wired to a named Meter —
your production code emits via the real Meter.CreateCounter<T> / etc.,
and the fixture records every sample for assertion. TagCardinalityGuard
is the novel piece: it asserts that a given tag's distinct-value count
stays within a budget, because unbounded cardinality is the #1 cause
of TSDB bill shock.
When to use it
- Asserting counter / histogram / gauge increments match design expectations.
- Regression-guarding against cardinality explosions.
- Verifying tag-name consistency across instrumentation sites.
- Not for: E2E tests hitting a real Prometheus / OTLP collector — those need a separate integration flow.
Prerequisites
- .NET 10 SDK
System.Diagnostics.DiagnosticSource(in-box)
Quick start
using System.Diagnostics.Metrics;
using Rig.TUnit.Observability.Metrics.Fixtures;
using Rig.TUnit.Observability.Metrics.Options;
await using var fx = new MetricsFixture(new MetricsFixtureOptions
{
MeterName = "orders.service",
});
await fx.InitializeAsync();
using var meter = new Meter("orders.service");
var counter = meter.CreateCounter<long>("orders.placed");
counter.Add(1);
Options
| Property | Type | Default | Description |
|---|---|---|---|
MeterName |
string |
"Rig.TUnit.Metrics" |
Meter.Name to listen on |
MaxTagCardinality |
int |
100 |
Cardinality budget enforced by TagCardinalityGuard |
IncludeHistograms |
bool |
true |
Capture histogram samples |
Fixture + helper APIs
Rig.TUnit.Observability.Metrics.Fixtures.MetricsFixtureRig.TUnit.Observability.Metrics.Options.MetricsFixtureOptionsRig.TUnit.Observability.Metrics.Builder.MetricsRigBuilderRig.TUnit.Observability.Metrics.Assertions.MetricAssertRig.TUnit.Observability.Metrics.Helpers.TagCardinalityGuard
Per-test isolation
Each fixture owns its MeterListener; listeners are per-fixture so
parallel tests don't cross-contaminate samples. MeterName includes
IsolationKey when using the default wiring.
Parallelism + performance
- Fixture construction: ~1 ms.
- Per-sample capture: ~500 ns.
- Safe under full parallelism.
Troubleshooting
MetricAssert.Counter(…).Sum()returns 0 —MeterListenerstarted AFTER theMeterwas created; ensure the fixture initialises before the code under test instantiates its meter.- Histograms return empty distribution — set
IncludeHistograms=true(default true) and confirm the histogram is actually recorded, not just created.
See docs/troubleshooting.md#metrics.
Provider quirks + edge cases
TagCardinalityGuard.EnsureWithinBudgetis a pure predicate — call it in test teardown or at assertion time, not in production code.- Multiple meters can share a name; the fixture listens on ALL of
them matching the
MeterName.
Benchmarks
See MetricsBenchmarks.cs;
baseline in benchmarks/baseline-005.json.
Related docs
- Architecture diagram
- Glossary
- Family base:
Rig.TUnit.Observability
License
MIT. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Bogus (>= 35.6.1)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.0)
- Rig.TUnit.Observability (>= 0.1.0-beta.2)
- TUnit.Core (>= 1.34.5)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Rig.TUnit.Observability.Metrics:
| Package | Downloads |
|---|---|
|
Rig.TUnit.All
Meta-package containing every Rig.TUnit.* package. DISCOURAGED — prefer per-feature or per-stack meta-packages (Rig.TUnit, Rig.TUnit.Microservices). |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-beta.2 | 44 | 4/27/2026 |
| 0.0.0-alpha.0.14 | 50 | 4/26/2026 |