@absolutejs/telemetry

中文文档
0.3.1发布于 2026/08/07Apache-2.0TypeScriptES Module近 30 天下载 4617

Tiny shared OpenTelemetry substrate for the AbsoluteJS ecosystem. Type-replicates @opentelemetry/api's Tracer/Span shape, ships noop implementations + a tracerOrNoop helper + a zero-dep OTLP-HTTP-JSON span exporter (/otlp-http subpath), and pins ABS_ATTRS

原始使用文档
文档目录12 节
  1. Install
  2. Durable trace storage
  3. Usage
  4. As a substrate-package author
  5. As a consumer wiring it all together
  6. API
  7. tracerOrNoop(provider, name, version?)
  8. withSpan(tracer, name, options, fn) / withSpanSync(...)
  9. createNoopSpan() / createNoopTracer() / createNoopTracerPro…
  10. ABS_ATTRS
  11. Type re-exports
  12. License

@absolutejs/telemetry

Tiny shared OpenTelemetry substrate for the AbsoluteJS substrate packages.

It also ships a provider-neutral agent observer at @absolutejs/telemetry/agent. Pass createAgentTelemetryObserver(tracer) directly as @absolutejs/agent-runtime's onEvent callback to correlate runs, signed discovery identities, steps, effects, budgets, and failures. Prompts and effect payloads are excluded, and actor IDs are private by default.

Docs: absolutejs.com/documentation/telemetry-package

What it is. Type-replicated OTel surface + noop implementations + the tracerOrNoop() helper + ABS_ATTRS semantic conventions. ~250 LOC, zero runtime deps.

What it solves. The deep-research audit's G2 gap: substrate packages (runtime / sync / queue / router / secrets / rate-limit / isolated-jsc) need OTel spans for the "one trace from edge → runtime → sync → queue → secret" SRE narrative. Without a shared substrate, every package writes its own peer-dep / noop-fallback boilerplate and picks its own attribute names.

How it's wired. Every substrate package factory takes an optional tracerProvider?: TracerProvider. Internally it calls:

const tracer = tracerOrNoop(options.tracerProvider, '@absolutejs/<pkg>');

and uses tracer.startActiveSpan(name, options, fn) in hot paths. When the user passes their @opentelemetry/api TracerProvider, real spans flow through. When they don't, the noop tracer executes the callback with zero allocations.

Install

bun add @absolutejs/telemetry
# Optional — only if you want real OTel spans:
bun add @opentelemetry/api @opentelemetry/sdk-node

The package has no runtime dependencies. It does not peer-dep @opentelemetry/api — its types are structurally compatible, so a real OTel TracerProvider satisfies the shape this package expects.

Durable trace storage

@absolutejs/telemetry owns the provider-neutral TraceStore contract. createTraceStoreSpanExporter() projects OpenTelemetry SDK spans into a bounded, credential-safe stored shape and writes batches through that contract. It drops secret-bearing attribute keys, strips URL query/hash values, bounds attributes/events/links, drops request/response bodies and database statements by default, supports an application-specific attribute allowlist, and preserves nanosecond timestamps as strings.

createFanoutSpanExporter() sends each batch to multiple exporters and reports partial failures without hiding a healthy destination. This supports durable first-party storage alongside an optional OTLP collector without coupling the storage contract to either provider.

Use createMemoryTraceStore() for tests. For production PostgreSQL/Neon storage, import createDrizzleTraceStore() and telemetryDrizzleSchema from @absolutejs/telemetry/drizzle. The exported table is intended for host-owned Drizzle migrations. Writes are idempotent on (trace_id, span_id); the store supports filtered trace summaries, complete trace retrieval, retention through prune(), aggregate storage statistics, bucketed error/latency time series, per-service health summaries, and a parent/child service dependency map without prescribing a hosted observability vendor. The in-memory implementation exposes the same TraceAnalyticsStore interface for local development and tests.

Usage

As a substrate-package author

import { tracerOrNoop, ABS_ATTRS, type TracerProvider } from '@absolutejs/telemetry';

export type MyPackageOptions = {
  // existing options...
  tracerProvider?: TracerProvider;
};

export const createMyPackage = (options: MyPackageOptions) => {
  const tracer = tracerOrNoop(options.tracerProvider, '@absolutejs/my-package');

  return {
    doWork: async (input: string) => {
      return tracer.startActiveSpan(
        'my-package.doWork',
        { attributes: { [ABS_ATTRS.tenant]: input } },
        async (span) => {
          try {
            const result = await actuallyDoWork(input);
            return result;
          } catch (error) {
            span.recordException(error);
            throw error;
          } finally {
            span.end();
          }
        }
      );
    },
  };
};

Or use the convenience wrapper withSpan(tracer, name, options, fn) that auto-sets status + recordException + end() for the common case.

As a consumer wiring it all together

import { NodeTracerProvider } from '@opentelemetry/sdk-node';
import { createMyPackage } from '@absolutejs/my-package';

const tracerProvider = new NodeTracerProvider({ /* exporter, sampler, etc */ });
tracerProvider.register();

const pkg = createMyPackage({ tracerProvider });
// Spans now flow through to your configured exporter.

API

tracerOrNoop(provider, name, version?)

Returns provider.getTracer(name, version) if provider is defined; otherwise a noop tracer. The canonical entry point for substrate packages.

withSpan(tracer, name, options, fn) / withSpanSync(...)

Wrap an async (or sync) callback in a span that auto-sets:

  • status: OK on success
  • status: ERROR + recordException(error) on throw
  • span.end() in either case (finally)
const result = await withSpan(
  tracer,
  'sync.runMutation',
  { attributes: { [ABS_ATTRS.mutation]: 'createIssue' } },
  async (span) => {
    span.setAttribute(ABS_ATTRS.mutationAttempt, 1);
    return await engine.runMutation('createIssue', args, ctx);
  }
);

createNoopSpan() / createNoopTracer() / createNoopTracerProvider()

Singletons. Useful in tests + as default fallbacks.

ABS_ATTRS

Standard attribute names. Use these instead of inline string literals so cross-package queries (abs.tenant = "acme") resolve in one filter:

abs.tenant                  // tenant / shard key
abs.shard.id

// sync
abs.engine.id
abs.collection
abs.mutation
abs.mutation.attempt
abs.subscription.id
abs.batch.size
abs.cluster.origin

// queue
abs.job.id
abs.job.kind
abs.job.attempt
abs.job.max_attempts
abs.worker.id

// runtime
abs.runtime.key
abs.runtime.pid
abs.runtime.port
abs.runtime.exit_reason
abs.runtime.readiness_ms

// router
abs.route.shard
abs.route.decision

// secrets
abs.secret.name
abs.secret.fingerprint

// audit
abs.audit.kind

// handoff
abs.handoff.correlation_id
abs.handoff.operation
abs.handoff.outcome
abs.handoff.service
abs.handoff.source
abs.handoff.attempt
abs.handoff.contradiction

Adding NEW attributes is a minor bump; renaming an existing one is a breaking change (anyone querying their span store has hard-coded the old name).

Type re-exports

Tracer, Span, TracerProvider, SpanContext, SpanStatus, SpanStatusCode, SpanKind, SpanOptions, Attributes, AttributeValue, AbsAttrName. Mirror @opentelemetry/api exactly; a real OTel TracerProvider satisfies these types structurally.

handoffSpanAttributes() and handoffSummarySpanAttributes() project @absolutejs/handoff evidence into these conventions without copying messages, references, external ids, raw payloads, or customer data into spans.

License

Apache 2.0. Tier B substrate-adjacent under the AbsoluteJS licensing policy.

版本与发布记录

@absolutejs/telemetry 共发布 9 个版本,首次发布于 2026/05/31;过去 12 个月发布了 9 个版本。

版本发布日期距今
0.3.1latest2026/08/073 个月前
0.3.02026/08/073 个月前
0.2.12026/07/303 个月前
0.2.02026/07/163 个月前
0.1.12026/06/045 个月前
0.1.02026/05/315 个月前

关于 @absolutejs/telemetry 的常见问题

@absolutejs/telemetry 是什么?

Tiny shared OpenTelemetry substrate for the AbsoluteJS ecosystem. Type-replicates @opentelemetry/api's Tracer/Span shape, ships noop implementations + a tracerOrNoop helper + a zero-dep OTLP-HTTP-JSON span exporter (/otlp-http subpath), and pins ABS_ATTRS

如何安装 @absolutejs/telemetry?

在项目目录运行 npm install @absolutejs/telemetry,或使用 pnpm add / yarn add / bun add。

@absolutejs/telemetry 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@absolutejs/telemetry 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@absolutejs/telemetry 可以商用吗?

@absolutejs/telemetry 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@absolutejs/telemetry 的下载量有多少?

根据 npm 官方下载统计,@absolutejs/telemetry 在 2026/10/05 – 2026/11/03 这 30 天内被下载 4,617 次,日均约 154 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@absolutejs/telemetry 还在维护吗?

最新版本 0.3.1 发布于 2026/08/07(3 个月前);至今共发布 9 个版本,其中过去 12 个月发布了 9 个;首次发布于 2026/05/31。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。