Skip to content

feat(observability): unify metrics with deco-cx/deco semconv contract#289

Open
nicacioliveira wants to merge 2 commits into
mainfrom
feat/otel-semconv-unify
Open

feat(observability): unify metrics with deco-cx/deco semconv contract#289
nicacioliveira wants to merge 2 commits into
mainfrom
feat/otel-semconv-unify

Conversation

@nicacioliveira

@nicacioliveira nicacioliveira commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

What

Align @decocms/start (tanstack) telemetry with the deco-cx/deco framework so both frameworks emit the same metric names, units, and attribute keys — required before mixing their data in the shared ClickStack otel_* tables.

Changes

  • Durations → seconds at the source (was ms). http.server.request.duration, http.client.request.duration, deco.loader.duration, deco.cms.resolve.duration now divide by 1000 at record time. Removed the "convert in the collector/query layer" stance — we normalize at origin (matches deco).
  • HTTP server attributes → semconv: methodhttp.request.method, route_patternhttp.route, statushttp.response.status_code. Proprietary extras namespaced: deco.http.status_class / .outcome / .region, deco.cache.decision / .layer.
  • Cache collision fixed: deco.cache.hits + deco.cache.misses → single deco.cache.lookups counter dimensioned by deco.cache.result. This both unifies with deco-cx/deco and removes a deco.cache.hits name-with-different-semantics collision (deco counted all lookups; tanstack counted only hits).
  • Loader labels namespaced under deco.* (deco.loader.name, deco.cache.result).

Compatibility

  • The caller API is unchangedRequestMetricLabels keeps its input field names (route_pattern, cache_decision, cache_layer); only the emitted attribute keys changed. No call sites needed edits.
  • Clean rename, no dual-emit (ClickStack is a fresh backend).
  • npm run typecheck clean; observability.test.ts 14/14 green.

Companion to deco-cx/deco#1211 and deco-cx/apps#1625. Part of the HyperDX → ClickStack migration; conforms to the shared OBSERVABILITY_CONVENTIONS contract.

🤖 Generated with Claude Code


Summary by cubic

Unifies @decocms/start telemetry with deco-cx/deco semantic conventions so both emit identical metric names, units, and attributes in ClickStack otel_* tables. Durations now record in seconds and HTTP labels use OTel keys; caller API stays the same.

  • Refactors

    • Record http.server, http.client, loader, and CMS resolve durations in seconds.
    • Switch to OTel HTTP keys: http.request.method, http.route, http.response.status_code; move extras under deco.* (e.g., deco.http.status_class, deco.cache.decision, deco.http.region).
    • Namespace loader/cache labels: deco.loader.name, deco.cache.result, deco.cache.layer, deco.cache.profile.
  • Bug Fixes

    • Replace deco.cache.hits/deco.cache.misses with a single deco.cache.requests counter dimensioned by deco.cache.status to remove a naming collision and match deco-cx/deco.

Written for commit be66958. Summary will update on new commits.

Review in cubic

Align @decocms/start telemetry with the deco-cx/deco framework so both land on
the same series/labels in ClickHouse (no collisions):

- Durations normalized to SECONDS at the source (was ms; the old "convert in
  the collector" note is gone — we normalize at origin). http.server /
  http.client / loader / resolve durations all divide by 1000 at record time.
- HTTP server attributes -> OTel semconv: method -> http.request.method,
  route_pattern -> http.route, status -> http.response.status_code. Proprietary
  extras moved under deco.* (deco.http.status_class / .outcome / .region,
  deco.cache.decision / .layer).
- Cache: the two counters deco.cache.hits / deco.cache.misses collapse into a
  single deco.cache.lookups counter dimensioned by deco.cache.result — matches
  deco-cx/deco and removes the deco.cache.hits name+semantics collision.
- Loader labels namespaced under deco.* (deco.loader.name, deco.cache.result).

Caller API (RequestMetricLabels field names) is unchanged — only emitted keys
change. Tests updated; typecheck + observability suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@nicacioliveira nicacioliveira requested a review from a team June 25, 2026 19:08
…status

Per the semconv-first decision: no canonical cache metric exists, so follow the
OTel semconv pattern (nfs.server.repcache.requests + .status) and the prefer-
attributes-over-metrics guidance. Replace the two hits/misses counters with a
single deco.cache.requests counter dimensioned by deco.cache.status. Same key
on span + metric. Matches deco-cx/deco.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants