@nwire/telemetry-otel 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ /**
2
+ * `otelTelemetryReporter(opts)` — a `TelemetryReporter` that drives the same
3
+ * OTel span routing as `attachOtelExporter`, but installs via the standard
4
+ * `installTelemetryReporter` API instead of subscribing directly to a runtime.
5
+ *
6
+ * import { trace } from "@opentelemetry/api";
7
+ * import { otelTelemetryReporter } from "@nwire/telemetry-otel";
8
+ * import { installTelemetryReporter } from "@nwire/app";
9
+ *
10
+ * const detach = installTelemetryReporter(app.runtime, otelTelemetryReporter({
11
+ * tracer: trace.getTracer("my-service"),
12
+ * }));
13
+ *
14
+ * // Run both the local file reporter and OTLP in parallel:
15
+ * const detachFile = installTelemetryReporter(app.runtime, fileTelemetryReporter(...));
16
+ * const detachOtel = installTelemetryReporter(app.runtime, otelTelemetryReporter({ tracer }));
17
+ *
18
+ * Internally the reporter creates a minimal mock runtime whose `onTelemetry`
19
+ * subscriber is driven by `report()`. `close()` calls the `attachOtelExporter`
20
+ * detach (which closes open spans and clears internal maps). This design keeps
21
+ * the span-routing logic in one place — `attachOtelExporter` stays the single
22
+ * source of truth.
23
+ */
24
+ import type { TelemetryReporter } from "@nwire/app";
25
+ import { type AttachOtelExporterOptions } from "./exporter.js";
26
+ import type { OtelTracer } from "./otel-types.js";
27
+ export interface OtelTelemetryReporterOptions extends AttachOtelExporterOptions {
28
+ readonly tracer: OtelTracer;
29
+ }
30
+ /**
31
+ * Returns a {@link TelemetryReporter} that translates each `report()` call
32
+ * into OTel spans via `attachOtelExporter`'s routing logic.
33
+ *
34
+ * Call `installTelemetryReporter(runtime, otelTelemetryReporter({ tracer }))`
35
+ * to wire it up. A single runtime can hold this reporter alongside others
36
+ * (e.g. the local JSONL file reporter) — they receive the same records
37
+ * independently.
38
+ */
39
+ export declare function otelTelemetryReporter(opts: OtelTelemetryReporterOptions): TelemetryReporter;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * `otelTelemetryReporter(opts)` — a `TelemetryReporter` that drives the same
3
+ * OTel span routing as `attachOtelExporter`, but installs via the standard
4
+ * `installTelemetryReporter` API instead of subscribing directly to a runtime.
5
+ *
6
+ * import { trace } from "@opentelemetry/api";
7
+ * import { otelTelemetryReporter } from "@nwire/telemetry-otel";
8
+ * import { installTelemetryReporter } from "@nwire/app";
9
+ *
10
+ * const detach = installTelemetryReporter(app.runtime, otelTelemetryReporter({
11
+ * tracer: trace.getTracer("my-service"),
12
+ * }));
13
+ *
14
+ * // Run both the local file reporter and OTLP in parallel:
15
+ * const detachFile = installTelemetryReporter(app.runtime, fileTelemetryReporter(...));
16
+ * const detachOtel = installTelemetryReporter(app.runtime, otelTelemetryReporter({ tracer }));
17
+ *
18
+ * Internally the reporter creates a minimal mock runtime whose `onTelemetry`
19
+ * subscriber is driven by `report()`. `close()` calls the `attachOtelExporter`
20
+ * detach (which closes open spans and clears internal maps). This design keeps
21
+ * the span-routing logic in one place — `attachOtelExporter` stays the single
22
+ * source of truth.
23
+ */
24
+ import { attachOtelExporter } from "./exporter.js";
25
+ /**
26
+ * Returns a {@link TelemetryReporter} that translates each `report()` call
27
+ * into OTel spans via `attachOtelExporter`'s routing logic.
28
+ *
29
+ * Call `installTelemetryReporter(runtime, otelTelemetryReporter({ tracer }))`
30
+ * to wire it up. A single runtime can hold this reporter alongside others
31
+ * (e.g. the local JSONL file reporter) — they receive the same records
32
+ * independently.
33
+ */
34
+ export function otelTelemetryReporter(opts) {
35
+ // We construct a lightweight synthetic runtime whose only job is to let
36
+ // attachOtelExporter subscribe. The single subscriber is stored, then driven
37
+ // directly from report(). This avoids duplicating the routing switch.
38
+ let listener = null;
39
+ const syntheticRuntime = {
40
+ onTelemetry(cb) {
41
+ // attachOtelExporter calls this exactly once.
42
+ listener = cb;
43
+ return () => {
44
+ listener = null;
45
+ };
46
+ },
47
+ };
48
+ // attachOtelExporter subscribes via onTelemetry and returns a detach.
49
+ // We cast: attachOtelExporter expects Runtime, our synthetic runtime satisfies
50
+ // the one property it uses (onTelemetry).
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ const detach = attachOtelExporter(syntheticRuntime, opts);
53
+ return {
54
+ name: "otel",
55
+ report(record) {
56
+ if (listener) {
57
+ listener(record);
58
+ }
59
+ },
60
+ close() {
61
+ detach();
62
+ return Promise.resolve();
63
+ },
64
+ };
65
+ }
@@ -14,4 +14,5 @@
14
14
  * Datadog, Honeycomb, Tempo, Jaeger).
15
15
  */
16
16
  export { attachOtelExporter, type AttachOtelExporterOptions } from "./exporter.js";
17
+ export { otelTelemetryReporter, type OtelTelemetryReporterOptions } from "./otel-reporter.js";
17
18
  export type { OtelTracer, OtelSpan, SpanContext, SpanKind, SpanStatusCode } from "./otel-types.js";
@@ -14,3 +14,4 @@
14
14
  * Datadog, Honeycomb, Tempo, Jaeger).
15
15
  */
16
16
  export { attachOtelExporter } from "./exporter.js";
17
+ export { otelTelemetryReporter } from "./otel-reporter.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nwire/telemetry-otel",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "private": false,
5
5
  "description": "OpenTelemetry bridge for the Nwire canonical telemetry stream. Translates every Telemetry record into OTLP spans + events. Plug in any OTEL exporter (Datadog, Honeycomb, Tempo, Vector → GreptimeDB).",
6
6
  "license": "MIT",
@@ -21,14 +21,14 @@
21
21
  "access": "public"
22
22
  },
23
23
  "dependencies": {
24
- "@nwire/app": "0.12.1",
25
- "@nwire/forge": "0.12.1"
24
+ "@nwire/app": "0.13.0",
25
+ "@nwire/forge": "0.13.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "typescript": "^5.6.0",
29
29
  "vitest": "^4.0.18",
30
30
  "zod": "^4.0.0",
31
- "@nwire/messages": "0.12.1"
31
+ "@nwire/messages": "0.13.0"
32
32
  },
33
33
  "scripts": {
34
34
  "build": "tsc && node ../../scripts/fix-dist-extensions.mjs dist",