maple-telemetry-conventions

star 1.4k

Maple's OpenTelemetry conventions — custom span attribute keys (`maple.*` vendor namespace, `query.context`, `db.query.*`, `result.*`, `cache.*`, `tenant.*`), Title Case status codes (`Ok`/`Error`/`Unset`), resource attribute dual-emit (`deployment.environment` + `deployment.environment.name`), span kinds, Tinybird MV pre-extracted columns, loop-prevention filters, and sampling. Use whenever writing or reviewing instrumentation code in any language (TypeScript, Rust, Python) in this repo — adding `setAttribute`/`setAttributes`/`record`/`#[instrument(fields(...))]` calls, setting span status, configuring an OTLP exporter, defining a new resource attribute, or wiring a new query through `WarehouseQueryService.sqlQuery()`.

Makisuo By Makisuo schedule Updated 6/11/2026

name: maple-telemetry-conventions description: Maple's OpenTelemetry conventions — custom span attribute keys (maple.* vendor namespace, query.context, db.query.*, result.*, cache.*, tenant.*), Title Case status codes (Ok/Error/Unset), resource attribute dual-emit (deployment.environment + deployment.environment.name), span kinds, Tinybird MV pre-extracted columns, loop-prevention filters, and sampling. Use whenever writing or reviewing instrumentation code in any language (TypeScript, Rust, Python) in this repo — adding setAttribute/setAttributes/record/#[instrument(fields(...))] calls, setting span status, configuring an OTLP exporter, defining a new resource attribute, or wiring a new query through WarehouseQueryService.sqlQuery(). version: "1.0.0"

Maple Telemetry Conventions

Reference for the language-agnostic OpenTelemetry conventions Maple uses across TypeScript (apps/api, Cloudflare workers in lib/effect-sdk/), Rust (apps/ingest), and future Python services. These conventions are load-bearing — Tinybird materialized views pre-extract certain attribute keys into columns, dashboards filter on Title Case status strings, and sampling-aware throughput math relies on the SampleRate column. Use the exact attribute spellings here in every language.

When to apply

  • Adding setAttribute / Effect.annotateCurrentSpan / Span::current().record(...) / #[instrument(fields(...))] to any code path
  • Setting span status (Ok / Error / Unset)
  • Wiring a new query through WarehouseQueryService.sqlQuery() (the context and profile options become span attributes)
  • Configuring an OTLP exporter, tracer provider, or resource builder
  • Introducing a new pre-extracted MV column or a new vendor attribute under maple.*
  • Reviewing a PR that touches apps/api/src/services/WarehouseQueryService.ts, apps/ingest/src/main.rs, apps/api/src/app.ts, lib/effect-sdk/src/cloudflare/, or packages/domain/src/tinybird/materializations.ts

Index

  • rules/span-attributes.md — Master reference of every custom attribute key Maple emits, grouped by namespace, with file:line citations.
  • rules/status-and-kind.md — Title Case status code rule (Ok/Error/Unset) and span kind conventions (Server / Client / Internal).
  • rules/resource-attributes.mdservice.* identity, deployment.environment.name resolution order, the legacy deployment.environment dual-emit, and maple_org_id.
  • rules/language-bindings.md — Parallel TypeScript / Rust / Python snippets that emit the same attribute keys.
  • rules/mv-first-class-columns.md — Which span and resource attributes Tinybird MVs pre-extract into columns (and the rule for adding new ones).
  • rules/service-map-attribution.md — Required span and resource attributes for the service map to render edges, runtime icons, and platform badges. Includes the canonical peer.service registry.
  • rules/loop-prevention.md — The three guards that prevent Maple's self-traffic from creating a feedback loop: API TracerDisabledWhen, ingest loopback guard, sampling.

Quick reference

Topic Rule
Status codes Always Title Case: "Ok", "Error", "Unset". Never OK, ERROR, SUCCESS, FAILED.
Vendor namespace Custom attributes go under maple.*. Sub-namespaces: maple.ingest.*, maple.cloudflare.*.
Standard semconv Use OTel semconv keys verbatim: service.name, http.request.method, db.system.name, error.type.
Org identity orgId (camelCase) in TypeScript spans, maple.org_id (dotted) in Rust spans. Don't unify until MVs migrate.
Deployment env Dual-emit deployment.environment + deployment.environment.name. Keep both until MV coalesce() migration lands.
Warehouse SQL spans Every span from WarehouseQueryService.executeSql carries db.system.name, peer.service, db.query.text, db.query.fingerprint, db.duration_ms, result.rowCount, orgId, query.context, query.profile. Legacy spans (pre 2026-06) use db.statement*/db.system; warehouse readers coalesce both.
Service map Outbound spans need peer.service (HTTP/RPC) or db.system.name (DB) on a Client/Producer span. Resource attrs need process.runtime.name, cloud.platform, maple.sdk.type for runtime icon + platform badge. See rules/service-map-attribution.md.
Loop prevention Never remove HttpMiddleware.TracerDisabledWhen (apps/api/src/app.ts:169-175) or the ingest loopback guard (apps/ingest/src/main.rs:499-514).

Canonical references (do not modify from this skill)

  • apps/api/src/services/WarehouseQueryService.ts:441-510executeSql span emission (the canonical example for TS).
  • apps/ingest/src/otel.rs — Resource builder + platform detection + forward-span helper for Rust. The canonical example for Rust resource and outbound-span attribution.
  • apps/ingest/src/main.rshandle_signal and handle_cloudflare_logpush (search for tracing::info_span! with otel.kind = "server") — Server-kind span macros for OTLP inbound.
  • apps/api/src/app.ts:169-175TracerDisabledWhen filter.
  • lib/effect-sdk/src/cloudflare/index.tsMapleCloudflareSDK tracer setup.
  • packages/domain/src/tinybird/materializations.ts — MV SELECT lists that pre-extract attribute keys into columns.
Install via CLI
npx skills add https://github.com/Makisuo/maple --skill maple-telemetry-conventions
Repository Details
star Stars 1,444
call_split Forks 93
navigation Branch main
article Path SKILL.md
More from Creator