Skip to content

host.name .local suffix is not normalized on the Prometheus metrics path #149

Description

@ryanrozich

Context

Raised by a Codex review on catalyst-otel#148 (P2), where the proposed fix was reverted as inert rather than shipped.

transform/metrics_normalize copies resource.attributes["host.name"] into a host_name log attribute, but it contains only log_statements — it runs on the logs pipeline. Native claude_code_* metrics reach Prometheus through a different path (resource_to_telemetry_conversion on the prometheus exporter), which promotes the raw resource attribute untouched.

Consequence: if any emitter ever supplies host.name=foo.local, Prometheus gets host_name="foo.local" while the logs path gets the .local stripped — one machine split across two series, which is the exact failure CTL-812 fixed for the hostname label.

Why this is filed rather than fixed

Nothing has been observed emitting a .local host.name to this stack. Every current emitter sets a canonical short name (laptop, mini, mini-2) explicitly. Adding a second speculative OTTL statement to a 73k-line config to guard an unobserved case is how that file got hard to reason about; a measured occurrence should drive the fix.

A .local value was observed once — in a deliberate synthetic tunnel probe (host.name=container-probe.local), which confirms the promotion path is unguarded but is not evidence of a real emitter.

Acceptance criteria

Given an emitter sends host.name=<name>.local on native claude_code_* metrics
When those metrics reach Prometheus
Then the host_name label reads <name>, matching the logs path

Given the fix is in place
When an emitter sends an already-canonical host.name (e.g. laptop)
Then the label is unchanged (the statement is a no-op)

Notes

Likely shape: a metric_statements block in a metrics-pipeline transform applying the same replace_pattern(..., "\\.local$", "") that transform/logs uses for hostname. Verify with otelcol-contrib validate plus a negative control (a deliberately broken statement must fail), since this repo has no CI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions