@foam-ai/node 0.1.0-alpha.5 → 0.1.0-alpha.6

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
@@ -160,19 +160,43 @@ exporters. Note: Never add Foam's own processors/readers helpers.
160
160
  `additionalResourceAttributes` adds extra resource attributes (for example
161
161
  `team` or `cloud.region`) to all telemetry.
162
162
 
163
- `disableLogSending` defaults to `false`. Set `true` to stop copying logger
164
- records into Foam (see Loggers).
163
+ `disableLogSending` defaults to `false`. Set `true` to stop Foam from
164
+ adding its own sending path to supported loggers; trace correlation in
165
+ log records is unaffected (see Loggers).
165
166
 
166
167
  `networkCapture` defaults to `"basic"`. Upgrade to `"advanced"` unless you
167
168
  cannot; it gives much more powerful HTTP and Undici capture. See Network capture.
168
169
 
169
- `redact` and `beforeSend` are accepted but **not implemented yet**; passing
170
- them logs a warning and they are ignored. `redact` will add extra
171
- sensitive keys (strings or RegExps) to the built-in body redaction list.
172
- `beforeSend` will run on every captured body before it leaves the
173
- process, returning the (possibly edited) text or `null` to drop the
174
- capture. Until they ship, rely on the built-in redaction (see Network
175
- capture).
170
+ `redact` adds keys to Foam's built-in redaction. `secrets` preserves the last
171
+ four characters of longer values; `pii` fully masks values.
172
+
173
+ ```js
174
+ init({
175
+ // ...
176
+ redact: {
177
+ secrets: ["internalId", "internalReference"],
178
+ pii: ["customerEmail", "homeAddress"],
179
+ },
180
+ });
181
+ ```
182
+
183
+ `beforeSend` can edit or drop spans and logs before Foam exports them. Return
184
+ the event to send it or `null` to drop it.
185
+
186
+ ```js
187
+ init({
188
+ // ...
189
+ beforeSend: (event) => {
190
+ if (event.type === "span" && event.attributes["url.path"] === "/health") {
191
+ return null; // drop health checks
192
+ }
193
+ delete event.attributes["user.email"];
194
+ return event;
195
+ },
196
+ });
197
+ ```
198
+
199
+ Metrics are not passed through `beforeSend`. See Redaction for coverage.
176
200
 
177
201
  `ignoredOutboundHosts` skips outbound HTTP tracing for those hostnames.
178
202
  The configured `endpoint` host is always skipped so export calls do not
@@ -185,15 +209,18 @@ TODO(pcga11): Add other common Gen AI providers.
185
209
  If another SDK already registered traces, metrics, logs, or the propagator,
186
210
  `init()` leaves the signal's slot untouched and only takes what is available. When a slot is taken, use its ingest helper instead.
187
211
 
188
- ### `createFoamIngestSpanProcessor(name, environment, token)`
212
+ ### `createFoamIngestSpanProcessor(name, environment, token, options?)`
189
213
 
190
- Returns a span processor that exports traces to Foam without taking over
191
- the global TracerProvider.
192
-
193
- Use this when another OpenTelemetry SDK already owns traces and you only
194
- need Foam as an extra export destination.
214
+ The helper returns a span processor but does not attach it to the
215
+ application's provider. Include it in the `spanProcessors` option when
216
+ constructing `BasicTracerProvider`. It cannot be added after provider
217
+ construction in `@opentelemetry/sdk-trace-base` 2.10; the old
218
+ `addSpanProcessor()` API is obsolete. If another SDK creates the provider,
219
+ configure the processor through that SDK's startup options.
195
220
 
196
221
  ```js
222
+ import { trace } from "@opentelemetry/api";
223
+ import { BasicTracerProvider } from "@opentelemetry/sdk-trace-base";
197
224
  import { createFoamIngestSpanProcessor } from "@foam-ai/node";
198
225
 
199
226
  const spanProcessor = createFoamIngestSpanProcessor(
@@ -201,18 +228,24 @@ const spanProcessor = createFoamIngestSpanProcessor(
201
228
  "production",
202
229
  process.env.FOAM_OTEL_TOKEN,
203
230
  );
204
- tracerProvider.addSpanProcessor(spanProcessor);
231
+ const tracerProvider = new BasicTracerProvider({
232
+ spanProcessors: [spanProcessor],
233
+ });
234
+ trace.setGlobalTracerProvider(tracerProvider);
205
235
  ```
206
236
 
207
- ### `createFoamIngestLogRecordProcessor(name, environment, token)`
237
+ ### `createFoamIngestLogRecordProcessor(name, environment, token, options?)`
208
238
 
209
- Returns a log-record processor that exports logs to Foam without taking over
210
- the global LoggerProvider.
211
-
212
- Use this when another SDK already owns logs and you want those records in
213
- Foam.
239
+ The helper returns a log-record processor but does not attach it to the
240
+ application's provider. Include it in the `processors` option when constructing
241
+ `LoggerProvider`. It cannot be added after provider construction in
242
+ `@opentelemetry/sdk-logs` 0.221; the old `addLogRecordProcessor()` API is
243
+ obsolete. If another SDK creates the provider, configure the processor through
244
+ that SDK's startup options.
214
245
 
215
246
  ```js
247
+ import { logs } from "@opentelemetry/api-logs";
248
+ import { LoggerProvider } from "@opentelemetry/sdk-logs";
216
249
  import { createFoamIngestLogRecordProcessor } from "@foam-ai/node";
217
250
 
218
251
  const logRecordProcessor = createFoamIngestLogRecordProcessor(
@@ -220,18 +253,27 @@ const logRecordProcessor = createFoamIngestLogRecordProcessor(
220
253
  "production",
221
254
  process.env.FOAM_OTEL_TOKEN,
222
255
  );
223
- loggerProvider.addLogRecordProcessor(logRecordProcessor);
256
+ const loggerProvider = new LoggerProvider({
257
+ processors: [logRecordProcessor],
258
+ });
259
+ logs.setGlobalLoggerProvider(loggerProvider);
224
260
  ```
225
261
 
226
- ### `createFoamIngestMetricReader(name, environment, token)`
262
+ Both ingest helpers accept the same `redact` and `beforeSend` options as
263
+ `init()`.
227
264
 
228
- Returns a metric reader that exports metrics to Foam without taking over
229
- the global MeterProvider.
265
+ ### `createFoamIngestMetricReader(name, environment, token)`
230
266
 
231
- Use this when another SDK already owns metrics and you want those meters in
232
- Foam.
267
+ The helper returns a metric reader but does not attach it to the application's
268
+ provider. Include it in the `readers` option when constructing `MeterProvider`.
269
+ It cannot be added after provider construction in
270
+ `@opentelemetry/sdk-metrics` 2.10; the old `addMetricReader()` API is obsolete.
271
+ If another SDK creates the provider, configure the reader through that SDK's
272
+ startup options.
233
273
 
234
274
  ```js
275
+ import { metrics } from "@opentelemetry/api";
276
+ import { MeterProvider } from "@opentelemetry/sdk-metrics";
235
277
  import { createFoamIngestMetricReader } from "@foam-ai/node";
236
278
 
237
279
  const metricReader = createFoamIngestMetricReader(
@@ -239,9 +281,15 @@ const metricReader = createFoamIngestMetricReader(
239
281
  "production",
240
282
  process.env.FOAM_OTEL_TOKEN,
241
283
  );
242
- meterProvider.addMetricReader(metricReader);
284
+ const meterProvider = new MeterProvider({
285
+ readers: [metricReader],
286
+ });
287
+ metrics.setGlobalMeterProvider(meterProvider);
243
288
  ```
244
289
 
290
+ If a vendor SDK does not expose a processor or reader startup option, add Foam
291
+ at the collector instead.
292
+
245
293
  If the other SDK already set `service.name` or environment,
246
294
  Foam's values overwrite them on that copy only. The original spans, logs,
247
295
  and metrics are left unchanged. For the Foam SDK, ensure all of the signals (spans, logs and metrics)
@@ -275,7 +323,7 @@ OpenTelemetry allows only one global propagator per signal. Foam registers W3C T
275
323
  Context and W3C Baggage (`traceparent`, `tracestate`, `baggage`), not B3,
276
324
  Jaeger, or AWS X-Ray. Auto-instrumented HTTP uses whichever propagator
277
325
  won. If another SDK already registered a propagator, Foam keeps it and
278
- `getState().signals.baggage` is `false`. A non-W3C propagator will not
326
+ `getState().signals.baggage` is `"none"`. A non-W3C propagator will not
279
327
  send `traceparent`, so a Foam peer starts a new trace. Foam does not add
280
328
  W3C headers on top.
281
329
 
@@ -304,7 +352,8 @@ await kafka.send({ value: payload, headers });
304
352
  Reads W3C trace and baggage headers and returns a parent OpenTelemetry
305
353
  context.
306
354
 
307
- Use this when you receive a message on a custom transport so the tracing carries over. Missing to extact resets the context on these headers effectively losing the context previously injected.
355
+ Use this when receiving a message on a custom transport. Without extraction,
356
+ the handler loses the propagated parent context.
308
357
 
309
358
  ```js
310
359
  import { context } from "@opentelemetry/api";
@@ -313,18 +362,14 @@ const parent = extractTraceContext(message.headers);
313
362
  await context.with(parent, () => handle(message));
314
363
  ```
315
364
 
316
- ### `setBaggage(key, value)`
365
+ ### `setBaggage(key, value, callback)`
317
366
 
318
- Stores a small string on the current request context.
319
-
320
- Use this for request-scoped identity (tenant, user id) that should follow
321
- the request across `await`s without being passed through every function.
322
-
323
- Values do not leak to other concurrent requests. Caveat: auto-instrumented HTTP
324
- does not send these keys until you call `injectTraceContext`.
367
+ Runs a callback with a request-scoped string such as a tenant or user ID.
368
+ The value follows work started by the callback across `await`s without leaking
369
+ to later handlers. Call `injectTraceContext` to send it on custom transports.
325
370
 
326
371
  ```js
327
- setBaggage("tenant.id", "acme");
372
+ await setBaggage("tenant.id", "acme", () => handleRequest());
328
373
  ```
329
374
 
330
375
  ### `getBaggage(key)`
@@ -524,42 +569,51 @@ export wherever `getState().signals.traces` points.
524
569
  - `"advanced"` adds those headers plus full Node `http`/`https` and
525
570
  Fetch/Undici request and response bodies as raw wire bytes, up to 1 MiB. Always set to `"advanced"` when security and compliance allows.
526
571
 
572
+ ## Redaction
527
573
 
528
- Headers are captured from an allowlist only, so sensitive headers such as
529
- `authorization` and `cookie` never leave the process. Captured JSON and
530
- form-urlencoded bodies are redacted before emission: values of sensitive
531
- keys (`password`, `token`, `api_key`, `client_secret`, `ssn`, and similar,
532
- matched case-insensitively across `-`, `_`, and `.` separators) are
533
- replaced with `[REDACTED]` on both the span body content and the emitted
534
- body chunks. When redaction changes a compressed body, the chunks carry
535
- the redacted text instead of the raw wire bytes. Other text and binary
536
- media types are captured unmodified.
537
-
538
- ## Loggers
539
-
540
- Foam follows the compatibility ranges of its OpenTelemetry logger
541
- instrumentations:
542
-
543
- - Bunyan `>=1 <2`
544
- - Pino `>=5.14 <11`
545
- - Winston `>=1 <4`
546
-
547
- Initialize Foam before you import or construct the logger. Registration alone does not mean a logger
548
- was loaded, patched, or produced records.
549
-
550
- With `disableLogSending: false` (the default), Foam SDK sends:
574
+ Foam always masks common credentials in captured request and response data,
575
+ URLs, and exported span and log fields. Add application-specific keys with the
576
+ `redact` option shown under `init(options)`.
551
577
 
552
- - Bunyan 1 records through an added OTel stream
553
- - Pino 7–10 records through an added main-thread `multistream`
554
- - Winston 3 records through the bundled `OpenTelemetryTransportV3`
578
+ Redaction applies to Foam's exports, including ingest helpers. It does not
579
+ modify telemetry sent through other exporters.
555
580
 
556
- Pino 5–6 and Winston 1–2 still get correlation. But they have no sending
557
- path (`pino.multistream` starts at 7; Winston transports start at 3), so Foam never receives a copy. Call `log()` to send a record yourself.
581
+ ## Loggers
558
582
 
559
- Set `disableLogSending: true` when the app already exports logger records
560
- itself (a Bunyan OTel stream, `pino-opentelemetry-transport`, a Winston
561
- OTel transport, or another pipeline). That turns off sending for Bunyan
562
- 1, Pino 7–10, and Winston 3.
583
+ Initialize Foam before you import or construct the logger.
584
+
585
+ What Foam does depends on the logger version:
586
+
587
+ - Bunyan 1, Pino 7–10, and Winston 3: Foam adds trace IDs to every
588
+ record and automatically sends a copy to Foam.
589
+ - Pino 5.14–6 and Winston 1–2: Foam adds trace IDs, but these versions
590
+ have no way to attach a sender, so no copy reaches Foam. Upgrade the
591
+ logger, or call `log()` yourself.
592
+ - Everything else: Foam does nothing. Use `console.*` (captured
593
+ below), call `log()`, or upgrade the logger.
594
+
595
+ ### If the app already ships logs somewhere
596
+
597
+ - To a non-OTel destination (files, another vendor's transport): no
598
+ conflict. Keep the defaults; Foam sends its own copy alongside.
599
+ - Through its own OTel stream/transport (a Bunyan OTel stream,
600
+ Winston `OpenTelemetryTransportV3`): those already deliver to Foam
601
+ via the global LoggerProvider. Set `disableLogSending: true` so
602
+ records don't arrive twice.
603
+ - Through another OTel SDK's LoggerProvider: set
604
+ `disableLogSending: true` and attach
605
+ `createFoamIngestLogRecordProcessor` to that provider (see Public
606
+ API) so Foam gets a copy.
607
+ - Through `pino-opentelemetry-transport`: it runs in a worker
608
+ thread and never touches the in-process LoggerProvider, so nothing
609
+ conflicts. Keep `disableLogSending: false`, or Foam gets no Pino
610
+ records at all.
611
+ - Through a collector or agent reading stdout/files: no app changes;
612
+ add a Foam OTLP exporter to the collector config.
613
+
614
+ `log()` sends a single record straight to Foam in any setup. It is a
615
+ manual per-record call, not a mirror of the logger. Use it for
616
+ targeted, high-value records.
563
617
 
564
618
  `ConsoleInstrumentation` turns calls to `console.*` into OTel log records.
565
619
  It does not capture arbitrary stdout/stderr writes.
@@ -584,3 +638,12 @@ The official OpenTelemetry JavaScript SDK has no in-process Profiles provider, p
584
638
  - [Profiling SIG language SDK support tracker](https://github.com/open-telemetry/sig-profiling/issues/106)
585
639
  - [OpenTelemetry Profiles public alpha announcement](https://opentelemetry.io/blog/2026/profiles-alpha/)
586
640
  - [OpenTelemetry eBPF profiler](https://github.com/open-telemetry/opentelemetry-ebpf-profiler)
641
+
642
+ ## TODO(pcga11): Anthropic instrumentation
643
+
644
+ There is no released official OpenTelemetry JavaScript instrumentation for the Anthropic SDK yet, but one is actively in progress in js-contrib, based on the OpenInference donation from Arize. Once `@opentelemetry/instrumentation-anthropic` is released (and picked up by `auto-instrumentations-node`), bundle it here like the OpenAI and aws-sdk ones. Until then, Anthropic coverage is handled case by case with the FDE (see FDE.md). Track upstream progress:
645
+
646
+ - [feat(instrumentation-anthropic): add basic messages instrumentation](https://github.com/open-telemetry/opentelemetry-js-contrib/pull/3664)
647
+ - [refactor(instrumentation-anthropic): use genai-util library](https://github.com/open-telemetry/opentelemetry-js-contrib/pull/3698)
648
+ - [Tracking: Migrate OpenInference JS instrumentations into opentelemetry-js-contrib](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/3668)
649
+ - [feat: Add @opentelemetry/genai-util package for GenAI instrumentations](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/3681)
@@ -0,0 +1,16 @@
1
+ interface BeforeSendSpanEvent {
2
+ readonly type: "span";
3
+ name: string;
4
+ attributes: Record<string, unknown>;
5
+ }
6
+ interface BeforeSendLogEvent {
7
+ readonly type: "log";
8
+ body?: unknown;
9
+ severityText?: string;
10
+ attributes: Record<string, unknown>;
11
+ }
12
+ export type BeforeSendEvent = BeforeSendSpanEvent | BeforeSendLogEvent;
13
+ export type BeforeSendHook = (event: BeforeSendEvent) => BeforeSendEvent | null;
14
+ export declare function resolveBeforeSend(hook: unknown): BeforeSendHook | undefined;
15
+ export declare function invokeBeforeSend(hook: BeforeSendHook, event: BeforeSendEvent): BeforeSendEvent | null | undefined;
16
+ export {};
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveBeforeSend = resolveBeforeSend;
4
+ exports.invokeBeforeSend = invokeBeforeSend;
5
+ function resolveBeforeSend(hook) {
6
+ if (hook === undefined || hook === null)
7
+ return undefined;
8
+ if (typeof hook !== "function") {
9
+ throw new TypeError("[foam] beforeSend must be a function");
10
+ }
11
+ return hook;
12
+ }
13
+ function isRecord(value) {
14
+ return value !== null && typeof value === "object" && !Array.isArray(value);
15
+ }
16
+ function isEvent(value, expectedType) {
17
+ if (!isRecord(value) || value.type !== expectedType || !isRecord(value.attributes)) {
18
+ return false;
19
+ }
20
+ if (expectedType === "span")
21
+ return typeof value.name === "string";
22
+ return value.severityText === undefined || typeof value.severityText === "string";
23
+ }
24
+ function invokeBeforeSend(hook, event) {
25
+ let copy;
26
+ try {
27
+ copy = structuredClone(event);
28
+ }
29
+ catch {
30
+ return undefined;
31
+ }
32
+ try {
33
+ const result = hook(copy);
34
+ if (result === null)
35
+ return null;
36
+ return isEvent(result, event.type) ? result : undefined;
37
+ }
38
+ catch {
39
+ return undefined;
40
+ }
41
+ }
@@ -1,9 +1,10 @@
1
1
  import { SeverityNumber } from "@opentelemetry/api-logs";
2
2
  export declare const FOAM_ENDPOINT = "https://otel.api.foam.ai";
3
3
  export declare const FOAM_INGEST_HOST: string;
4
+ export declare const ATTR_FOAM_INGEST_HOST = "foam.ingest.host";
4
5
  export declare const FOAM_IDENTIFIER_NAME = "[foam-otel]";
5
6
  export declare const FOAM_DISTRO_NAME = "@foam-ai/node";
6
- export declare const FOAM_DISTRO_VERSION = "0.1.0-alpha.7";
7
+ export declare const FOAM_DISTRO_VERSION = "0.1.0-alpha.5";
7
8
  export declare const FOAM_OTLP_TRACES_PATH = "/v1/traces";
8
9
  export declare const FOAM_OTLP_LOGS_PATH = "/v1/logs";
9
10
  export declare const FOAM_OTLP_METRICS_PATH = "/v1/metrics";
@@ -37,7 +38,7 @@ export declare const ATTR_FOAM_HTTP_REQUEST_BODY_TRUNCATED = "foam.http.request.
37
38
  export declare const ATTR_FOAM_HTTP_RESPONSE_BODY_TRUNCATED = "foam.http.response.body.truncated";
38
39
  export declare const SAFE_NETWORK_HEADERS: readonly ["content-type", "content-length", "content-encoding"];
39
40
  export declare const REDACTED_VALUE = "[REDACTED]";
40
- export declare const SENSITIVE_BODY_KEY_PATTERNS: readonly ["password", "passwd", "passphrase", "secret", "token", "apikey", "authorization", "credential", "privatekey", "sessionid", "creditcard", "cardnumber", "accountnumber", "routingnumber"];
41
- export declare const SENSITIVE_BODY_KEYS_EXACT: readonly ["auth", "pwd", "pin", "otp", "cvv", "cvc", "ssn", "key", "cookie", "setcookie", "session"];
41
+ export declare const FULL_MASK = "********";
42
+ export declare const TAIL_MASK_THRESHOLD = 12;
42
43
  export declare const DIAG_LOG_LEVEL = "OTEL_LOG_LEVEL";
43
44
  export declare const SEVERITY_TEXT: Partial<Record<SeverityNumber, string>>;
package/dist/constants.js CHANGED
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SEVERITY_TEXT = exports.DIAG_LOG_LEVEL = exports.SENSITIVE_BODY_KEYS_EXACT = exports.SENSITIVE_BODY_KEY_PATTERNS = exports.REDACTED_VALUE = exports.SAFE_NETWORK_HEADERS = exports.ATTR_FOAM_HTTP_RESPONSE_BODY_TRUNCATED = exports.ATTR_FOAM_HTTP_REQUEST_BODY_TRUNCATED = exports.ATTR_FOAM_HTTP_RESPONSE_BODY_COMPLETE = exports.ATTR_FOAM_HTTP_REQUEST_BODY_COMPLETE = exports.ATTR_FOAM_HTTP_RESPONSE_BODY_CAPTURE_ID = exports.ATTR_FOAM_HTTP_REQUEST_BODY_CAPTURE_ID = exports.ATTR_FOAM_HTTP_BODY_CHUNK_CONTENT = exports.ATTR_FOAM_HTTP_BODY_CHUNK_BYTES = exports.ATTR_FOAM_HTTP_BODY_CHUNK_INDEX = exports.ATTR_FOAM_HTTP_BODY_CHUNK_COUNT = exports.ATTR_FOAM_HTTP_BODY_CAPTURED_BYTES = exports.ATTR_FOAM_HTTP_BODY_OUTCOME = exports.ATTR_FOAM_HTTP_BODY_TRUNCATED = exports.ATTR_FOAM_HTTP_BODY_COMPLETE = exports.ATTR_FOAM_HTTP_BODY_DIRECTION = exports.ATTR_FOAM_HTTP_BODY_SIDE = exports.ATTR_FOAM_HTTP_BODY_ID = exports.ATTR_HTTP_RESPONSE_BODY_CONTENT = exports.ATTR_HTTP_REQUEST_BODY_CONTENT = exports.ATTR_HTTP_RESPONSE_BODY_SIZE = exports.ATTR_HTTP_REQUEST_BODY_SIZE = exports.MAX_ACTIVE_CAPTURES = exports.NETWORK_CAPTURE_DEADLINE_MS = exports.NETWORK_CAPTURE_EVENT_BODY = exports.NETWORK_CAPTURE_EVENT = exports.NETWORK_BODY_MAX_DECODE_BYTES = exports.NETWORK_BODY_MAX_CAPTURE_BYTES = exports.NETWORK_BODY_CHUNK_BYTES = exports.FOAM_OTLP_METRICS_PATH = exports.FOAM_OTLP_LOGS_PATH = exports.FOAM_OTLP_TRACES_PATH = exports.FOAM_DISTRO_VERSION = exports.FOAM_DISTRO_NAME = exports.FOAM_IDENTIFIER_NAME = exports.FOAM_INGEST_HOST = exports.FOAM_ENDPOINT = void 0;
3
+ exports.SEVERITY_TEXT = exports.DIAG_LOG_LEVEL = exports.TAIL_MASK_THRESHOLD = exports.FULL_MASK = exports.REDACTED_VALUE = exports.SAFE_NETWORK_HEADERS = exports.ATTR_FOAM_HTTP_RESPONSE_BODY_TRUNCATED = exports.ATTR_FOAM_HTTP_REQUEST_BODY_TRUNCATED = exports.ATTR_FOAM_HTTP_RESPONSE_BODY_COMPLETE = exports.ATTR_FOAM_HTTP_REQUEST_BODY_COMPLETE = exports.ATTR_FOAM_HTTP_RESPONSE_BODY_CAPTURE_ID = exports.ATTR_FOAM_HTTP_REQUEST_BODY_CAPTURE_ID = exports.ATTR_FOAM_HTTP_BODY_CHUNK_CONTENT = exports.ATTR_FOAM_HTTP_BODY_CHUNK_BYTES = exports.ATTR_FOAM_HTTP_BODY_CHUNK_INDEX = exports.ATTR_FOAM_HTTP_BODY_CHUNK_COUNT = exports.ATTR_FOAM_HTTP_BODY_CAPTURED_BYTES = exports.ATTR_FOAM_HTTP_BODY_OUTCOME = exports.ATTR_FOAM_HTTP_BODY_TRUNCATED = exports.ATTR_FOAM_HTTP_BODY_COMPLETE = exports.ATTR_FOAM_HTTP_BODY_DIRECTION = exports.ATTR_FOAM_HTTP_BODY_SIDE = exports.ATTR_FOAM_HTTP_BODY_ID = exports.ATTR_HTTP_RESPONSE_BODY_CONTENT = exports.ATTR_HTTP_REQUEST_BODY_CONTENT = exports.ATTR_HTTP_RESPONSE_BODY_SIZE = exports.ATTR_HTTP_REQUEST_BODY_SIZE = exports.MAX_ACTIVE_CAPTURES = exports.NETWORK_CAPTURE_DEADLINE_MS = exports.NETWORK_CAPTURE_EVENT_BODY = exports.NETWORK_CAPTURE_EVENT = exports.NETWORK_BODY_MAX_DECODE_BYTES = exports.NETWORK_BODY_MAX_CAPTURE_BYTES = exports.NETWORK_BODY_CHUNK_BYTES = exports.FOAM_OTLP_METRICS_PATH = exports.FOAM_OTLP_LOGS_PATH = exports.FOAM_OTLP_TRACES_PATH = exports.FOAM_DISTRO_VERSION = exports.FOAM_DISTRO_NAME = exports.FOAM_IDENTIFIER_NAME = exports.ATTR_FOAM_INGEST_HOST = exports.FOAM_INGEST_HOST = exports.FOAM_ENDPOINT = void 0;
4
4
  const api_logs_1 = require("@opentelemetry/api-logs");
5
5
  exports.FOAM_ENDPOINT = "https://otel.api.foam.ai";
6
6
  exports.FOAM_INGEST_HOST = new URL(exports.FOAM_ENDPOINT).hostname;
7
+ exports.ATTR_FOAM_INGEST_HOST = "foam.ingest.host";
7
8
  exports.FOAM_IDENTIFIER_NAME = "[foam-otel]";
8
9
  exports.FOAM_DISTRO_NAME = "@foam-ai/node";
9
- exports.FOAM_DISTRO_VERSION = "0.1.0-alpha.7";
10
+ exports.FOAM_DISTRO_VERSION = "0.1.0-alpha.5";
10
11
  exports.FOAM_OTLP_TRACES_PATH = "/v1/traces";
11
12
  exports.FOAM_OTLP_LOGS_PATH = "/v1/logs";
12
13
  exports.FOAM_OTLP_METRICS_PATH = "/v1/metrics";
@@ -53,39 +54,8 @@ exports.SAFE_NETWORK_HEADERS = [
53
54
  "content-encoding",
54
55
  ];
55
56
  exports.REDACTED_VALUE = "[REDACTED]";
56
- // pcga11: Matched against body keys after lowercasing and stripping the
57
- // -_. separators, so "api-key", "apiKey", and "API_KEY" all normalize to
58
- // "apikey". Patterns match anywhere in the key ("user_password" is caught);
59
- // exact keys are too short or too common to substring-match safely.
60
- exports.SENSITIVE_BODY_KEY_PATTERNS = [
61
- "password",
62
- "passwd",
63
- "passphrase",
64
- "secret",
65
- "token",
66
- "apikey",
67
- "authorization",
68
- "credential",
69
- "privatekey",
70
- "sessionid",
71
- "creditcard",
72
- "cardnumber",
73
- "accountnumber",
74
- "routingnumber",
75
- ];
76
- exports.SENSITIVE_BODY_KEYS_EXACT = [
77
- "auth",
78
- "pwd",
79
- "pin",
80
- "otp",
81
- "cvv",
82
- "cvc",
83
- "ssn",
84
- "key",
85
- "cookie",
86
- "setcookie",
87
- "session",
88
- ];
57
+ exports.FULL_MASK = "********";
58
+ exports.TAIL_MASK_THRESHOLD = 12;
89
59
  exports.DIAG_LOG_LEVEL = "OTEL_LOG_LEVEL";
90
60
  exports.SEVERITY_TEXT = {
91
61
  [api_logs_1.SeverityNumber.TRACE]: "TRACE",
@@ -1,20 +1,28 @@
1
1
  import type { Attributes } from "@opentelemetry/api";
2
- import type { ExportResult } from "@opentelemetry/core";
2
+ import { type ExportResult } from "@opentelemetry/core";
3
3
  import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
4
4
  import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
5
5
  import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
6
6
  import type { ReadableLogRecord } from "@opentelemetry/sdk-logs";
7
7
  import type { ResourceMetrics } from "@opentelemetry/sdk-metrics";
8
8
  import type { ReadableSpan } from "@opentelemetry/sdk-trace-base";
9
+ import { type BeforeSendHook } from "./before-send.js";
10
+ import { type RedactionConfig } from "./redaction.js";
9
11
  type Stamp = Attributes | undefined;
12
+ export interface FoamExporterOptions {
13
+ readonly redaction?: RedactionConfig;
14
+ readonly beforeSend?: BeforeSendHook;
15
+ }
10
16
  export declare class FoamTraceExporter extends OTLPTraceExporter {
11
17
  private readonly stamp?;
12
- constructor(token: string, stamp?: Stamp);
18
+ private readonly options;
19
+ constructor(token: string, stamp?: Stamp, options?: FoamExporterOptions);
13
20
  export(spans: ReadableSpan[], callback: (result: ExportResult) => void): void;
14
21
  }
15
22
  export declare class FoamLogExporter extends OTLPLogExporter {
16
23
  private readonly stamp?;
17
- constructor(token: string, stamp?: Stamp);
24
+ private readonly options;
25
+ constructor(token: string, stamp?: Stamp, options?: FoamExporterOptions);
18
26
  export(records: ReadableLogRecord[], callback: (result: ExportResult) => void): void;
19
27
  }
20
28
  export declare class FoamMetricExporter extends OTLPMetricExporter {