@davidilie/telemetry-next 0.3.0 → 0.5.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.
package/README.md CHANGED
@@ -80,6 +80,25 @@ sampler strings. Either sampler is wrapped in a mutable provider-wide gate, so
80
80
  new automatic and client-created spans, including children of sampled parents.
81
81
  Already queued/exported work is not recalled.
82
82
 
83
+ Resource detectors default to an empty list, so `OTEL_RESOURCE_ATTRIBUTES` and
84
+ `OTEL_SERVICE_NAME` cannot override the configured identity or add unfiltered
85
+ attributes. Explicit `otel.resourceDetectors` opt into upstream detection;
86
+ review their output because it bypasses core redaction. Standard Vercel
87
+ deployment metadata from `@vercel/otel` remains available.
88
+
89
+ The default trace exporter sends OTLP/HTTP protobuf directly to Alloy. It
90
+ redacts completed span names, attributes, events, links, and status messages,
91
+ including automatic fetch spans and exceptions. URL paths are removed from
92
+ span names. A custom `otel.traceExporter` receives the same redacted copies.
93
+ Core attribute bounds apply; canonical service identity remains on the OTel
94
+ resource. Resource and instrumentation-scope metadata are trusted configuration.
95
+
96
+ Explicit `otel.spanProcessors` replace this default, so their exporters must
97
+ apply their own privacy policy (or use Node's `RedactingSpanExporter`). The
98
+ default does not use Vercel's hosted exporter or `VERCEL_OTEL_ENDPOINTS`.
99
+ Choose custom processors deliberately if a Vercel tracing integration is
100
+ required. Use a custom exporter for a protocol other than HTTP protobuf.
101
+
83
102
  Provider registration owns trace sampling and the Node adapter applies
84
103
  `sampleRate` once to logs; core does not make a second decision for those
85
104
  signals. OTel histogram measurements remain aggregated instead of randomly
@@ -172,4 +191,4 @@ only when queued telemetry must leave before returning or exiting. It drains
172
191
  core sends and invokes public `forceFlush()` on registered trace, log, and
173
192
  metric providers when supported. It does not shut down the framework provider.
174
193
 
175
- See the [web adapter](https://www.npmjs.com/package/@davidilie/telemetry-web), [Node adapter](https://www.npmjs.com/package/@davidilie/telemetry-node), [project onboarding](https://github.com/DavidIlie/davidapps-telemetry/blob/main/docs/adding-a-project.md), and [troubleshooting](https://github.com/DavidIlie/davidapps-telemetry/blob/main/docs/troubleshooting.md).
194
+ See the [web adapter](https://www.npmjs.com/package/@davidilie/telemetry-web), [Node adapter](https://www.npmjs.com/package/@davidilie/telemetry-node), [project onboarding](https://github.com/davidapps-org/davidapps-telemetry/blob/main/docs/adding-a-project.md), and [troubleshooting](https://github.com/davidapps-org/davidapps-telemetry/blob/main/docs/troubleshooting.md).
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_request_error = require("./request-error-DR7VrDk_.cjs");
2
+ const require_request_error = require("./request-error-CEM6CkHw.cjs");
3
3
  exports.createNextRequestErrorHandler = require_request_error.createNextRequestErrorHandler;
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { t as createNextRequestErrorHandler } from "./request-error-BWohGji2.mjs";
1
+ import { t as createNextRequestErrorHandler } from "./request-error-DbUeEPob.mjs";
2
2
  export { createNextRequestErrorHandler };
package/dist/node.cjs CHANGED
@@ -1,9 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_request_error = require("./request-error-DR7VrDk_.cjs");
2
+ const require_request_error = require("./request-error-CEM6CkHw.cjs");
3
3
  let _davidilie_telemetry_core = require("@davidilie/telemetry-core");
4
4
  let _vercel_otel = require("@vercel/otel");
5
5
  let _davidilie_telemetry_node = require("@davidilie/telemetry-node");
6
6
  let _opentelemetry_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
7
+ let _opentelemetry_exporter_trace_otlp_proto = require("@opentelemetry/exporter-trace-otlp-proto");
7
8
  //#region src/node.ts
8
9
  const REGISTRATION = Symbol.for("@davidilie/telemetry-next/registration");
9
10
  function traceSampler(config) {
@@ -24,8 +25,13 @@ function registerNextTelemetry(config) {
24
25
  enabled: config.enabled ?? true,
25
26
  consent: config.consent ?? "granted"
26
27
  });
28
+ const { spanProcessors, traceExporter, ...otel } = config.otel ?? {};
29
+ const exporter = traceExporter && traceExporter !== "auto" ? traceExporter : void 0;
27
30
  (0, _vercel_otel.registerOTel)({
28
- ...config.otel,
31
+ ...otel,
32
+ spanProcessors: spanProcessors ?? [new _opentelemetry_sdk_trace_base.BatchSpanProcessor(new _davidilie_telemetry_node.RedactingSpanExporter(exporter ?? new _opentelemetry_exporter_trace_otlp_proto.OTLPTraceExporter()))],
33
+ ...spanProcessors && exporter ? { traceExporter: new _davidilie_telemetry_node.RedactingSpanExporter(exporter) } : {},
34
+ resourceDetectors: config.otel?.resourceDetectors ?? [],
29
35
  traceSampler: sampler,
30
36
  serviceName: resource.serviceName,
31
37
  attributes: (0, _davidilie_telemetry_node.telemetryResourceAttributes)(resource)
package/dist/node.mjs CHANGED
@@ -1,8 +1,9 @@
1
- import { t as createNextRequestErrorHandler } from "./request-error-BWohGji2.mjs";
1
+ import { t as createNextRequestErrorHandler } from "./request-error-DbUeEPob.mjs";
2
2
  import { sanitizeResource } from "@davidilie/telemetry-core";
3
3
  import { registerOTel } from "@vercel/otel";
4
- import { DynamicTelemetrySampler, NodeTelemetryClient, telemetryResourceAttributes } from "@davidilie/telemetry-node";
5
- import { ParentBasedSampler, TraceIdRatioBasedSampler } from "@opentelemetry/sdk-trace-base";
4
+ import { DynamicTelemetrySampler, NodeTelemetryClient, RedactingSpanExporter, telemetryResourceAttributes } from "@davidilie/telemetry-node";
5
+ import { BatchSpanProcessor, ParentBasedSampler, TraceIdRatioBasedSampler } from "@opentelemetry/sdk-trace-base";
6
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
6
7
  //#region src/node.ts
7
8
  const REGISTRATION = Symbol.for("@davidilie/telemetry-next/registration");
8
9
  function traceSampler(config) {
@@ -23,8 +24,13 @@ function registerNextTelemetry(config) {
23
24
  enabled: config.enabled ?? true,
24
25
  consent: config.consent ?? "granted"
25
26
  });
27
+ const { spanProcessors, traceExporter, ...otel } = config.otel ?? {};
28
+ const exporter = traceExporter && traceExporter !== "auto" ? traceExporter : void 0;
26
29
  registerOTel({
27
- ...config.otel,
30
+ ...otel,
31
+ spanProcessors: spanProcessors ?? [new BatchSpanProcessor(new RedactingSpanExporter(exporter ?? new OTLPTraceExporter()))],
32
+ ...spanProcessors && exporter ? { traceExporter: new RedactingSpanExporter(exporter) } : {},
33
+ resourceDetectors: config.otel?.resourceDetectors ?? [],
28
34
  traceSampler: sampler,
29
35
  serviceName: resource.serviceName,
30
36
  attributes: telemetryResourceAttributes(resource)
@@ -9,6 +9,22 @@ function errorDigest(error) {
9
9
  if (typeof error === "object" && error !== null && "digest" in error && typeof error.digest === "string") return error.digest;
10
10
  }
11
11
  function createNextRequestErrorHandler(config) {
12
+ let pendingFlush;
13
+ let needsFlush = false;
14
+ function flushCaptured() {
15
+ needsFlush = true;
16
+ pendingFlush ??= Promise.resolve().then(async () => {
17
+ try {
18
+ do {
19
+ needsFlush = false;
20
+ await config.telemetry.flush?.();
21
+ } while (needsFlush);
22
+ } finally {
23
+ pendingFlush = void 0;
24
+ }
25
+ });
26
+ return pendingFlush;
27
+ }
12
28
  return async (error, request, context) => {
13
29
  if (config.beforeCapture) try {
14
30
  if (!await config.beforeCapture(error, request, context)) return;
@@ -35,7 +51,7 @@ function createNextRequestErrorHandler(config) {
35
51
  return;
36
52
  }
37
53
  try {
38
- await config.telemetry.flush?.();
54
+ await flushCaptured();
39
55
  } catch (flushError) {
40
56
  await reportFailure(config, flushError, "flush");
41
57
  }
@@ -9,6 +9,22 @@ function errorDigest(error) {
9
9
  if (typeof error === "object" && error !== null && "digest" in error && typeof error.digest === "string") return error.digest;
10
10
  }
11
11
  function createNextRequestErrorHandler(config) {
12
+ let pendingFlush;
13
+ let needsFlush = false;
14
+ function flushCaptured() {
15
+ needsFlush = true;
16
+ pendingFlush ??= Promise.resolve().then(async () => {
17
+ try {
18
+ do {
19
+ needsFlush = false;
20
+ await config.telemetry.flush?.();
21
+ } while (needsFlush);
22
+ } finally {
23
+ pendingFlush = void 0;
24
+ }
25
+ });
26
+ return pendingFlush;
27
+ }
12
28
  return async (error, request, context) => {
13
29
  if (config.beforeCapture) try {
14
30
  if (!await config.beforeCapture(error, request, context)) return;
@@ -35,7 +51,7 @@ function createNextRequestErrorHandler(config) {
35
51
  return;
36
52
  }
37
53
  try {
38
- await config.telemetry.flush?.();
54
+ await flushCaptured();
39
55
  } catch (flushError) {
40
56
  await reportFailure(config, flushError, "flush");
41
57
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davidilie/telemetry-next",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Runtime-safe Next.js telemetry backed by @vercel/otel.",
5
5
  "keywords": [
6
6
  "analytics",
@@ -14,12 +14,12 @@
14
14
  "license": "Apache-2.0",
15
15
  "repository": {
16
16
  "type": "git",
17
- "url": "git+https://github.com/DavidIlie/davidapps-telemetry.git",
17
+ "url": "git+https://github.com/davidapps-org/davidapps-telemetry.git",
18
18
  "directory": "packages/next"
19
19
  },
20
- "homepage": "https://github.com/DavidIlie/davidapps-telemetry#readme",
20
+ "homepage": "https://github.com/davidapps-org/davidapps-telemetry#readme",
21
21
  "bugs": {
22
- "url": "https://github.com/DavidIlie/davidapps-telemetry/issues"
22
+ "url": "https://github.com/davidapps-org/davidapps-telemetry/issues"
23
23
  },
24
24
  "engines": {
25
25
  "node": ">=20.9.0"
@@ -66,8 +66,9 @@
66
66
  "clean": "rm -rf dist coverage"
67
67
  },
68
68
  "dependencies": {
69
- "@davidilie/telemetry-core": "0.3.0",
70
- "@davidilie/telemetry-node": "0.3.0",
69
+ "@davidilie/telemetry-core": "0.5.0",
70
+ "@davidilie/telemetry-node": "0.5.0",
71
+ "@opentelemetry/exporter-trace-otlp-proto": "0.221.0",
71
72
  "@opentelemetry/sdk-trace-base": "2.10.0",
72
73
  "@vercel/otel": "2.1.3"
73
74
  },
@@ -88,6 +89,6 @@
88
89
  "publishConfig": {
89
90
  "access": "public",
90
91
  "registry": "https://registry.npmjs.org/",
91
- "provenance": true
92
+ "provenance": false
92
93
  }
93
94
  }