Skip to content

feat(observability): instrument SWR fetch caches so cache metrics reach ClickHouse - #411

Open
JonasJesus42 wants to merge 2 commits into
mainfrom
otel-cache-dashboard-clickhouse
Open

feat(observability): instrument SWR fetch caches so cache metrics reach ClickHouse#411
JonasJesus42 wants to merge 2 commits into
mainfrom
otel-cache-dashboard-clickhouse

Conversation

@JonasJesus42

@JonasJesus42 JonasJesus42 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Cache/upstream telemetry only reached ClickHouse for the edge and cachedLoader layers; the commerce apps' in-memory SWR fetch caches (VTEX today, and every Magento site) were dark, so we had no hit/miss ratio or upstream latency for the layer doing the real dedup/SWR work against provider APIs. This adds one shared, instrumented SWR cache — createFetchCache in @decocms/blocks/sdk/fetchCache, emitting deco.cache.requests{layer="swr",profile=<provider>} on HIT/STALE-HIT/MISS with provider-isolated Maps — and routes every commerce app through it plus the shared createInstrumentedFetch, so any current or future app is covered automatically (the vtex-swr layer is renamed to the provider-agnostic swr). VTEX's fetchCache becomes a thin binding over the shared util (no behavior change, now emits metrics); apps-magento gains setMagentoFetch/createMagentoFetch + magentoCachedFetch + an operation router; apps-salesforce gains createSalesforceFetch and defaults createHttpClient's fetcher to it so all loaders are instrumented without per-loader wiring. The contract is documented in CLAUDE.md and enforced by a guardrail test in apps-commerce that fails if a commerce app lacks an instrumented fetch. Verified: typecheck clean across the six affected packages and the full test suites pass (plus new fetchCache, magento instrumentation, and guardrail tests).

🤖 Generated with Claude Code


Summary by cubic

Instrumented the shared SWR fetch cache and provider fetches so cache hit/miss and upstream latency metrics reach ClickHouse with clean labels. SWR now emits deco.cache.requests with layer="swr" and the backend in deco.cache.provider; VTEX, Magento, and Salesforce also emit http.client.request.duration.

  • New Features

    • Added createFetchCache in @decocms/blocks/sdk/fetchCache emitting deco.cache.requests{layer="swr",provider=<backend>} on HIT/STALE-HIT/MISS.
    • Renamed cache layer label from vtex-swr to swr; SWR leaves deco.cache.profile unset and carries the backend in deco.cache.provider.
    • VTEX: routed through the shared cache; kept the same API (fetchWithCache, stats, clear).
    • Magento: added createMagentoFetch + setMagentoFetch, magentoCachedFetch, and an operation router to instrument all egress via one fetch.
    • Salesforce: added createSalesforceFetch; createHttpClient now defaults its fetcher to it so all loaders are covered.
    • Updated recordCacheMetric to accept a provider label; tests and docs reflect the new label scheme. Guardrail test ensures each commerce app ships an instrumentedFetch factory (factory existence only).
  • Migration

    • Magento: call setMagentoFetch(createMagentoFetch()) at boot; use magentoCachedFetch for cacheable GETs.
    • Salesforce: no action needed; if you pass a custom fetcher to createHttpClient, wrap it with createSalesforceFetch({ baseFetch }).
    • Dashboards: filter deco.cache.layer="swr" and slice by deco.cache.provider (was vtex-swr and deco.cache.profile).

Written for commit 8d3f4db. Summary will update on new commits.

Review in cubic

…trics reach ClickHouse

Cache/upstream telemetry only reached ClickHouse for the edge + cachedLoader
layers; the apps' in-memory SWR fetch caches (VTEX, and any Magento site) were
dark. Add one shared, instrumented SWR cache and route all commerce apps
through it so hit/miss + upstream latency flow automatically.

- @decocms/blocks: new `sdk/fetchCache` (`createFetchCache`) emitting
  `deco.cache.requests{layer="swr",profile=<provider>}` on HIT/STALE-HIT/MISS,
  provider-isolated Maps; generalize CacheLayer `vtex-swr` -> `swr`.
- apps-vtex: fetchCache is now a thin binding over the shared util (no behavior
  change, now emits metrics).
- apps-magento: `setMagentoFetch`/`createMagentoFetch` + operationRouter +
  `magentoCachedFetch` (route egress through instrumented fetch + SWR cache).
- apps-salesforce: `createSalesforceFetch`; `createHttpClient` defaults its
  fetcher to it so all loaders are instrumented automatically.
- Convention documented in CLAUDE.md + guardrail test in apps-commerce that
  fails if a commerce app lacks an instrumented fetch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JonasJesus42
JonasJesus42 requested a review from a team July 29, 2026 14:44
… honest guardrail scope

Addresses PR review: the swr cache carried the backend on `deco.cache.profile`,
which the edge layer uses for page-type — a `sum by (profile)` panel would blend
provider names with page-types. Add a separate `deco.cache.provider` label
(recordCacheMetric gains an optional `provider` arg); the swr layer now leaves
`profile` unset. Also soften the guardrail docstring + CLAUDE.md to state its
real scope (the factory exists; it does NOT verify the site wired setXFetch).

Co-Authored-By: Claude Opus 4.8 (1M context) <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.

1 participant