KeelMatrix.MetricBudget
0.1.0
Prefix Reserved
dotnet add package KeelMatrix.MetricBudget --version 0.1.0
NuGet\Install-Package KeelMatrix.MetricBudget -Version 0.1.0
<PackageReference Include="KeelMatrix.MetricBudget" Version="0.1.0" />
<PackageVersion Include="KeelMatrix.MetricBudget" Version="0.1.0" />
<PackageReference Include="KeelMatrix.MetricBudget" />
paket add KeelMatrix.MetricBudget --version 0.1.0
#r "nuget: KeelMatrix.MetricBudget, 0.1.0"
#:package KeelMatrix.MetricBudget@0.1.0
#addin nuget:?package=KeelMatrix.MetricBudget&version=0.1.0
#tool nuget:?package=KeelMatrix.MetricBudget&version=0.1.0
KeelMatrix.MetricBudget
Catch high-cardinality .NET metrics in tests and CI. KeelMatrix.MetricBudget observes the metric series and tag
values emitted by the workload you run and checks them against explicit budgets, without a collector, exporter, or
observability backend.
Install
dotnet add package KeelMatrix.MetricBudget --version 0.1.0
The package has no OpenTelemetry dependency. It works with libraries that emit System.Diagnostics.Metrics
instruments, including ASP.NET Core, System.Net.Http, EF Core, and custom meters.
Quick start
using System.Diagnostics.Metrics;
using KeelMatrix.MetricBudget;
using KeelMatrix.MetricBudget.Assertions;
[Fact]
public async Task ClientRequestsStayWithinObservedCardinality()
{
using MetricBudgetSession session = MetricBudgetSession.Start(
new MetricBudgetOptions()
.ForInstrument("My.Service", "http.client.request.duration", budget =>
{
budget.MaxObservedSeries = 20;
budget.Tag("server.address").MaxDistinctValues = 4;
}));
await MyApplication.HandleAsync(new Request("/orders/42"));
MetricBudgetReport report = session.Complete();
report.AssertWithinBudget();
}
Start the session before the workload, complete it after the workload, and assert the returned report. A passing run means the exercised workload stayed within the configured budgets. A failing run names the instrument, counts, limits, and tag keys, but never prints tag or metric values.
Important limitations
- Observed, not production, cardinality. The report covers only the paths and inputs exercised by this run. It cannot prove the maximum cardinality production can produce or estimate backend cost. See observed-vs-production-cardinality.md.
- Deterministic multiset identity. Tag order does not change a series, but duplicate keys are retained. The CLR
type of a tag value is part of identity. Instrument identity also includes unit, description, measurement type,
meter tags, and instrument tags;
Meter.Scopeis excluded. Retained results expose a privacy-safeIdentityDiscriminatorfor the complete identity without exposing static metadata values. If a focused assertion is ambiguous, pass one of the listed discriminator values to the overload that acceptsidentityDiscriminator. See series-identity.md. - Static metadata bounds. Published unit, description, measurement type, meter tags, and instrument tags use
dedicated bounded options (
MaxStaticMetadataTagCount,MaxStaticMetadataTagKeyLength,MaxStaticMetadataTagValueLength, andMaxStaticMetadataTextLength). Rejected dimensions appear inSafety.StaticMetadataFailures; delivered-tag bounds never reject static metadata. - Completeness is explicit. Filling a safety bound is not itself incomplete; incompleteness begins when an
additional observation or state entry is rejected.
InvalidConfigurationand a provenViolationhave higher outcome precedence thanObservationIncomplete, so inspectreport.Safety, the per-result completeness flags, andreport.AccountingIsConsistentfor every result. Focused budget and observation assertions fail closed for a target whose accounting is incomplete, including per-tag value tracking. See safety-bounds.md. - Privacy boundary. Reports exclude tag values, metric values, and workload samples, but retain application- supplied meter names, meter versions, instrument names, and tag keys. Review those identifiers before sharing output outside its intended audience. See privacy-and-telemetry.md.
- Observable instruments. Observable callbacks run only when this session requests collection. Call
session.RecordObservableInstruments()at each intended observation point, even if another metrics listener is active. - Session containment. Start and complete one session around the workload it verifies. Instrument publication is process-global, while delivery is scoped to instruments selected and enabled by this session.
Supported targets
The package ships net8.0 and netstandard2.0 assets. The repository verifies the latter through a .NET Framework
net472 host using System.Diagnostics.DiagnosticSource 8.0.1. Core verification is offline; the package's optional
anonymous telemetry and opt-out rules are documented in
privacy-and-telemetry.md.
Documentation
- examples.md - canonical custom-meter and ASP.NET Core/OpenTelemetry-flavored consumer examples.
- safety-bounds.md - bounded memory, lifecycle state, and outcome precedence.
- troubleshooting.md - recurring outcomes and diagnostic guidance.
- privacy-and-telemetry.md - report data boundary and telemetry behavior.
- DEV.md - repository validation commands.
Source and the full documentation set are available at https://github.com/KeelMatrix/MetricBudget.
| 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 is compatible. 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. |
-
.NETStandard 2.0
- KeelMatrix.Telemetry (= 0.1.1)
- System.Diagnostics.DiagnosticSource (>= 8.0.1)
-
net8.0
- KeelMatrix.Telemetry (= 0.1.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 80 | 10/3/2026 |