@foam-ai/otel-core
v0.2.0
Published
Foam's shared server-side OpenTelemetry package for Node.js. One core, adapters as subpath exports, per-customer behavior via configuration.
Readme
@foam-ai/otel-core
Foam's shared server-side OpenTelemetry package for Node.js. One core, adapters as subpath exports, per-customer behavior via configuration — if a bug would ever need a fleet-wide fix, it lives here; if it's customer-specific, it's config in the customer's repo.
Replaces the per-customer packages @foam-ai/cliengo-kori
(/fastify + /pino) and @foam-ai/cliengo-combee
(/express + /winston + /sqs + /sns + /outbound), and the earlier
@foam-ai/node / @foam-ai/node-opentelemetry cores.
Quick start
import { init } from '@foam-ai/otel-core';
init({
serviceName: 'my-service',
// token: defaults to the FOAM_OTEL_TOKEN env var
// endpoint: defaults to OTEL_EXPORTER_OTLP_ENDPOINT env var, then foam prod
});init() only exports in production (NODE_ENV=production) or with
forceExport: true. It registers global OTel providers, so after init the
standard OTel API works and exports to foam — spans
(tracer.startActiveSpan), exceptions (span.recordException), counters,
histograms, up-down counters, and log records (logger.emit). Convenience
accessors: getTracer(), getMeter(), getLogger().
Adapters
| Subpath | What it gives you |
| --- | --- |
| @foam-ai/otel-core/express | expressMiddleware(), expressErrorHandler() |
| @foam-ai/otel-core/fastify | fastifyPlugin(), getRequestTraceContext() |
| @foam-ai/otel-core/winston | createWinstonTransport(), createWinstonFormat(), opt-in patchWinston() |
| @foam-ai/otel-core/pino | createPinoDestination(), createPinoMixin(), createPinoLoggerConfig() |
| @foam-ai/otel-core/sqs | wrapSqsConsumer(), wrapSqsBody(), extractSqsTraceparent() |
| @foam-ai/otel-core/sns | injectSnsAttributes(), opt-in patchSns() |
| @foam-ai/otel-core/outbound | opt-in patchOutboundHttp() (shadow spans for egress) |
| @foam-ai/otel-core/newrelic | NR coexistence bridge (resolveNewRelic, getNr, …) |
Host libraries (express, fastify, winston, pino, newrelic,
@aws-sdk/client-sns) are optional peer dependencies — install only what you
use. Nothing is monkey-patched unless you call a patch*() function.
Configuration
| Option | Default | Notes |
| --- | --- | --- |
| token | FOAM_OTEL_TOKEN env | required to export |
| endpoint | OTEL_EXPORTER_OTLP_ENDPOINT env, then https://otel.api.foam.ai | |
| forceExport | false | export outside production |
| newrelic | off | true to auto-detect, or pass the agent |
| redactContactInfo | false | adds email/phone/telefono/celular to redaction |
| redactKeys | [] | extra keys to redact |
| healthRoutes | [] | routes exempted from request-context capture (none by default — health checks are captured) |
| ignoredOutboundHosts | [] | extra hosts skipped for outbound shadow spans |
| captureConsole | false | mirror console.* as OTel logs |
| captureProcessErrors | true | crash capture via uncaughtExceptionMonitor (includes rejections Node escalates; NOT rejections handled by your own listener or under --unhandled-rejections=warn/none) |
Batch cadence honors OTEL_BSP_SCHEDULE_DELAY, OTEL_BLRP_SCHEDULE_DELAY,
and OTEL_METRIC_EXPORT_INTERVAL.
The wire contract (stamps, foam.rid baggage, redaction defaults,
anti-fabrication rules) is specified in contract/SPEC.md
and enforced by the conformance apps under test-apps/.
