Skip to content

A cross-client self-instrumentation telemetry-names contract #239

Description

@joshmouch

The problem

Each AHP client that instruments its own operation (request spans, message counters, reconnect and dropped-event metrics) has to name those spans, metrics, and attributes. There is no shared vocabulary across the Go, Rust, Swift, Kotlin, TypeScript, and .NET clients today. When one client emits ahp.client.messages.sent and another emits ahp_messages_sent, an operator running a fleet of mixed-language agents cannot write one OpenTelemetry dashboard or alert that works across all of them.

Why it belongs at the protocol layer

The self-instrumentation names are an interop surface, the same way the wire types are. They have to be byte-identical across clients or downstream OpenTelemetry tooling fragments, and that requirement is what makes the name contract a protocol concern rather than a per-client detail. The instrumentation code stays per-client and idiomatic; only the names are shared. This is separate from the existing "OpenTelemetry over AHP" channel (docs/specification/telemetry-channel.md), which carries OTel data over the protocol. This standardizes what each client emits about its own operation.

Proposed mechanism

A single source of truth, types/telemetry/registry.ts (string enums for spans, metrics, and attributes, plus a units map), consumed by the existing scripts/generate-*.ts codegen to emit a generated name holder per client. It is the same shape the protocol enums already use, with a generated-output freshness gate so the holders cannot drift.

Proof of concept

Two reference adopters, both with recorder-based emission tests that prove the names actually fire: the .NET client (request spans plus eight metrics via ActivitySource and Meter) in #206, and the Rust client (the same metrics through the metrics facade) in #237.

The decision

Whether AHP wants a spec'd cross-client self-instrumentation names contract, and if so the initial scope (which spans, metrics, and attributes) and which clients adopt first. I'll shape it to whatever scope you bless and keep #237 a draft until then.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions