Files
2026-05-27 23:47:53 +01:00

3.6 KiB

otel

(no submodules)

Purpose

otel.ts wires the @suaveplan/drive-cache meter and tracer used by every middleware intercept in @suaveplan/drive-plugin-cache. It exposes lazily-built getInstruments(), a setDriveCacheMeterProvider override (so tests can inject a stub provider), resetInstruments() for inter-test isolation, and five recordX helpers that pair a counter increment with a single short-lived span carrying the canonical drive.cache.* attributes.

The instruments are cached after the first call and rebuilt only when the provider override changes or resetInstruments() is called. This avoids re-creating instrument handles on the hot read path while still letting tests drive their own provider.

Features

  • drive_cache.hits_total{namespace} / misses_total{namespace} / populations_total{namespace} / invalidations_total{namespace} counters.
  • drive_cache.errors_total{namespace, op} counter — op ∈ {"get", "set", "delete"}.
  • drive_cache.entry_bytes{namespace} histogram observed on every population.
  • One-span-per-event spans with drive.cache.namespace, drive.cache.path, and drive.cache.outcome ∈ {"hit", "miss", "populated", "invalidated", "error"} attributes.
  • setDriveCacheMeterProvider(provider) resets the cached instruments so tests can swap providers between cases.

Usage: Basic

import { recordHit, recordMiss, recordPopulate } from "@suaveplan/drive-plugin-cache/otel";

recordMiss("drive", "clip.mov");
recordPopulate("drive", "clip.mov", 4096);
recordHit("drive", "clip.mov");

Usage: Advanced

import {
  setDriveCacheMeterProvider,
  resetInstruments,
  recordError,
} from "@suaveplan/drive-plugin-cache/otel";
import { MeterProvider } from "@opentelemetry/sdk-metrics";

const provider = new MeterProvider();
setDriveCacheMeterProvider(provider);
recordError("drive", "set", "clip.mov");
// run assertions on provider's metric readers
setDriveCacheMeterProvider(undefined);
resetInstruments();

API Reference

Export Shape Description
getInstruments(force?) () => DriveCacheInstruments Lazy accessor; pass true to force-rebuild.
resetInstruments() () => void Clear the cached bag (test-only).
setDriveCacheMeterProvider(provider) (p?: MeterProvider) => void Swap the meter provider; auto-resets the cache.
recordHit(namespace, path) (string, string) => void Increment hits + emit outcome="hit" span.
recordMiss(namespace, path) (string, string) => void Increment misses + emit outcome="miss" span.
recordPopulate(namespace, path, byteLength) (string, string, number) => void Increment populations + observe entry size + emit outcome="populated" span.
recordInvalidate(namespace, path) (string, string) => void Increment invalidations + emit outcome="invalidated" span.
recordError(namespace, op, path) (string, "get" | "set" | "delete", string) => void Increment errors + emit outcome="error" span with op attribute.

Implementation Notes

Spans are created via tracer.startSpan(...).end() rather than tracer.startActiveSpan(...). The middleware does its own work inside the calling async flow; the only purpose of these spans is to carry the outcome attribute for trace-backed analysis. Long-lived active spans would force every middleware intercept to thread an OpenTelemetry.Context, which is overkill for a cache event. Counter attribute bags are constructed inline as plain objects — V8 inlines this allocation on the hot path so the impact is undetectable.