D4S.AgentMetrics 1.1.0

dotnet add package D4S.AgentMetrics --version 1.1.0
                    
NuGet\Install-Package D4S.AgentMetrics -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="D4S.AgentMetrics" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="D4S.AgentMetrics" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="D4S.AgentMetrics" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add D4S.AgentMetrics --version 1.1.0
                    
#r "nuget: D4S.AgentMetrics, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package D4S.AgentMetrics@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=D4S.AgentMetrics&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=D4S.AgentMetrics&version=1.1.0
                    
Install as a Cake Tool

D4S.AgentMetrics

Internal NuGet package for Dev4Side AI agents built on .NET 10.

It handles, transparently:

  • Handshake — verifies at startup that the agent is registered and active in the D4S back-end.
  • Metric definition registration — sends all metric descriptors (default + custom) to the back-end.
  • Business metric tracking — exposes IMetricWriter.TrackAsync with a bounded in-memory queue.
  • HTTP request tracking — middleware measuring interactions, response time and error rate, scoped to the endpoints you choose.
  • AI token tracking — an OpenTelemetry listener harvests gen_ai.usage.* from any Microsoft.Extensions.AI chat pipeline (D4S.Agent works out of the box, zero code).
  • Periodic flush — drains the queue and POSTs the event batch to the back-end, with retry on transient failures.
  • Heartbeat — sends periodic liveness pings to the back-end.

Internal use only. This package is not intended for public distribution.


Prerequisites

The agent must already be registered in the D4S back-end (manually or via the marketplace onboarding process) — this package only verifies that the registration exists.

Everything is fail-soft: if the AgentMetrics configuration is missing, or the back-end is unreachable, or the handshake is rejected, metric tracking is silently disabled and the agent starts and runs normally. This makes it safe to keep the wiring always on (see Quick start), including in local dev where no back-end is configured.


Installation

dotnet add package D4S.AgentMetrics

Quick start

This is the wiring used by the MAF365Agent template — two lines of code, everything else is configuration:

// Program.cs
builder.Services.AddAgentMetrics(options =>
{
    builder.Configuration.GetSection("AgentMetrics").Bind(options);
    // Project-specific business metrics go here (see "Tracking custom metrics"):
});

// After UseRouting, before the endpoint mappings:
app.UseAgentMetricsTracking();
// appsettings.json
{
  "AgentMetrics": {
    "AgentId": "my-agent",
    "DisplayName": "My Agent",
    "TenantId": "customer-tenant",
    "BaseUrl": "https://my-agent.azurewebsites.net",
    "D4SApiUrl": "https://d4s-api.azurewebsites.net",
    "D4SApiKey": "", // secret: set per environment (user secrets / app settings), never commit
    // Only measure the business endpoints — keeps health probes, platform warmup pings and
    // scanner noise out of total_interactions / avg_response_time_ms:
    "TrackedPathPrefixes": [ "/api/messages", "/mcp" ]
  }
}

Leave the section empty (or omit D4SApiUrl/D4SApiKey) to run with metrics disabled — the wiring is a clean no-op in that case.


Configuration

Option Type Default Description
AgentId string — (required) Unique agent identifier as registered in the D4S back-end.
DisplayName string — (required) Human-readable agent name shown in the dashboard.
TenantId string — (required) Tenant that owns this agent.
BaseUrl string — (required) Public URL of the agent itself.
D4SApiUrl string — (required) Base URL of the central D4S back-end.
D4SApiKey string — (required) API key sent as X-Api-Key on every back-end call.
FlushInterval TimeSpan 00:00:10 How often the metric queue is flushed.
HeartbeatInterval TimeSpan 00:02:00 How often a heartbeat ping is sent.
TrackedPathPrefixes string[] [] (= all) Allow-list of request path prefixes measured by the middleware. Strongly recommended on internet-facing hosts.
TokenTrackingEnabled bool true Enables the OpenTelemetry token-usage listener.
TokenTelemetrySources string[] [] (= D4S.Agent sources) ActivitySource names observed for gen_ai.usage.* tags. Defaults to Dev4Side.MAF365Agent.ChatClient + Dev4Side.MAF365Agent.Guardrail.
MaxQueuedEvents int 10000 Bound of the in-memory event queue (drops newest with a warning when full).

When a required option is missing, tracking is disabled for the session (logged at startup) and every metric operation becomes a no-op.


Default profile metrics

These seven metrics are always included automatically — no extra code required. UseProfile(AgentProfile.Default) is optional but recommended for clarity.

Key Label Aggregation Tracked by
total_interactions Interazioni totali Count Middleware (automatic)
avg_response_time_ms Tempo medio risposta (ms) Average Middleware (automatic)
error_rate Tasso di errore Percentage Middleware (automatic, HTTP 5xx)
prompt_tokens_total Token prompt totali Sum OTel token listener (automatic)
completion_tokens_total Token completion totali Sum OTel token listener (automatic)
total_tokens_total Token totali Sum OTel token listener (automatic)
avg_tokens_per_interaction Token medi per interazione Average OTel token listener (automatic, per LLM call)

avg_confidence_score was removed from the default profile in 1.1.0: it had no automatic producer and rendered as a permanently empty tile. Register it as a custom scalar in agents that actually compute a confidence score.


AI token tracking

Token metrics are collected automatically by listening to the OpenTelemetry GenAI spans emitted by Microsoft.Extensions.AI pipelines wrapped with UseOpenTelemetry(...):

  • D4S.Agent / MAF365Agent hosts: zero configuration — the D4S.Agent chat and guardrail clients are already instrumented with the source names the listener observes by default.
  • Other MEAI hosts: set TokenTelemetrySources to your instrumented source names (e.g. Experimental.Microsoft.Extensions.AI for the MEAI default). Do not include agent-level sources that re-emit aggregated usage, or tokens are double-counted.
  • The listener reads both the current semantic conventions (gen_ai.usage.input_tokens / gen_ai.usage.output_tokens) and the legacy names (prompt_tokens / completion_tokens).
  • avg_tokens_per_interaction is averaged per LLM call (a single agent turn with tool calls spans several LLM calls).

For hosts that use the Azure AI Foundry ChatCompletionsClient directly (no MEAI pipeline), the legacy explicit wrapper is still available:

builder.Services.AddTrackedChatClient(
    new ChatCompletionsClient(endpoint, new AzureKeyCredential(apiKey)),
    model: "gpt-4o");

Tracking custom metrics

Register the project's business metrics at startup, then record events wherever they happen:

// Registration (inside AddAgentMetrics):
options.AddRanking("top_exams", "Esami più richiesti", dimensionName: "exam_name", topN: 20);
options.AddScalar("teams_messages", "Domande da Teams");                     // Count
options.AddScalar("avg_confidence_score", "Confidence medio", AggregationType.Average);

// Then inject IMetricWriter wherever you need it:
public class MyService(IMetricWriter metrics)
{
    public async Task HandleAsync(string examName, double confidence)
    {
        await metrics.TrackAsync("teams_messages");                          // pure count
        await metrics.TrackAsync("top_exams", dimension: examName);          // ranking increment
        await metrics.TrackAsync("avg_confidence_score", value: (decimal)confidence);
    }
}

Rules:

  • Metric definitions are sent to the back-end at handshake: keys must be registered at startup and stay stable across releases. Events for unregistered keys are dropped with a one-time warning.
  • Ranking metrics are count-based; the dimension string is the ranked value. Never use free user text or user identifiers as a dimension — only catalog-controlled values.

Delivery guarantees

Events are queued in memory and flushed every FlushInterval:

  • Transient back-end failures (network errors, HTTP 5xx) → the batch is re-enqueued and retried on the next cycle.
  • Permanent rejections (HTTP 4xx) → the batch is dropped with a warning.
  • The queue is bounded by MaxQueuedEvents; when full, the newest events are dropped with a warning. On process shutdown, unflushed events are lost — metrics are KPI-grade, not an audit log.

Internal use notice

This package is developed and maintained by Dev4Side for internal use only. It is not published on NuGet.org and is not intended for external consumption.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.1.0 48 7/20/2026
1.0.0 73 6/8/2026