diff --git a/packages/core-shared/src/instrumentation/di/bind-noop-instrumentation.ts b/packages/core-shared/src/instrumentation/di/bind-noop-instrumentation.ts index 73f6695..d81258f 100644 --- a/packages/core-shared/src/instrumentation/di/bind-noop-instrumentation.ts +++ b/packages/core-shared/src/instrumentation/di/bind-noop-instrumentation.ts @@ -2,22 +2,29 @@ import type { Container } from "inversify"; import { NoopTracer } from "../noop-tracer"; import { NoopLogger } from "../noop-logger"; +import { NoopMetrics } from "../noop-metrics"; import { INSTRUMENTATION_SYMBOLS } from "../symbols"; -import type { ITracer, ILogger } from "../index"; +import type { ITracer, ILogger, IMetrics } from "../index"; export function bindNoopInstrumentation(container: Container): { tracer: ITracer; logger: ILogger; + metrics: IMetrics; } { const tracer = new NoopTracer(); const logger = new NoopLogger(); + const metrics = new NoopMetrics(); if (container.isBound(INSTRUMENTATION_SYMBOLS.TRACER)) { container.unbind(INSTRUMENTATION_SYMBOLS.TRACER); } if (container.isBound(INSTRUMENTATION_SYMBOLS.LOGGER)) { container.unbind(INSTRUMENTATION_SYMBOLS.LOGGER); } + if (container.isBound(INSTRUMENTATION_SYMBOLS.METRICS)) { + container.unbind(INSTRUMENTATION_SYMBOLS.METRICS); + } container.bind(INSTRUMENTATION_SYMBOLS.TRACER).toConstantValue(tracer); container.bind(INSTRUMENTATION_SYMBOLS.LOGGER).toConstantValue(logger); - return { tracer, logger }; + container.bind(INSTRUMENTATION_SYMBOLS.METRICS).toConstantValue(metrics); + return { tracer, logger, metrics }; } diff --git a/packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.ts b/packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.ts index 828ae4a..66c7010 100644 --- a/packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.ts +++ b/packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.ts @@ -2,9 +2,10 @@ import type { Container } from "inversify"; import { OtelTracer } from "../otel/otel-tracer"; import { OtelLogger } from "../otel/otel-logger"; +import { OtelMetrics } from "../otel/otel-metrics"; import { initOtelServerNode } from "../otel/init-server-node"; import { INSTRUMENTATION_SYMBOLS } from "../symbols"; -import type { ITracer, ILogger } from "../index"; +import type { ITracer, ILogger, IMetrics } from "../index"; export type BindOtelOpts = { dsn: string; @@ -15,7 +16,7 @@ export type BindOtelOpts = { export function bindOtelInstrumentation( container: Container, opts: BindOtelOpts, -): { tracer: ITracer; logger: ILogger } { +): { tracer: ITracer; logger: ILogger; metrics: IMetrics } { const environment = process.env["SENTRY_ENVIRONMENT"] ?? process.env["VERCEL_ENV"] ?? @@ -32,6 +33,7 @@ export function bindOtelInstrumentation( const tracer = new OtelTracer(); const logger = new OtelLogger(); + const metrics = new OtelMetrics(); if (container.isBound(INSTRUMENTATION_SYMBOLS.TRACER)) { container.unbind(INSTRUMENTATION_SYMBOLS.TRACER); @@ -39,7 +41,11 @@ export function bindOtelInstrumentation( if (container.isBound(INSTRUMENTATION_SYMBOLS.LOGGER)) { container.unbind(INSTRUMENTATION_SYMBOLS.LOGGER); } + if (container.isBound(INSTRUMENTATION_SYMBOLS.METRICS)) { + container.unbind(INSTRUMENTATION_SYMBOLS.METRICS); + } container.bind(INSTRUMENTATION_SYMBOLS.TRACER).toConstantValue(tracer); container.bind(INSTRUMENTATION_SYMBOLS.LOGGER).toConstantValue(logger); - return { tracer, logger }; + container.bind(INSTRUMENTATION_SYMBOLS.METRICS).toConstantValue(metrics); + return { tracer, logger, metrics }; } diff --git a/packages/core-shared/src/instrumentation/index.ts b/packages/core-shared/src/instrumentation/index.ts index d5dd58a..550c108 100644 --- a/packages/core-shared/src/instrumentation/index.ts +++ b/packages/core-shared/src/instrumentation/index.ts @@ -9,8 +9,10 @@ export type { Breadcrumb, CaptureContext, } from "./logger.interface"; +export type { IMetrics, MetricAttributeValue } from "./metrics.interface"; export { NoopTracer } from "./noop-tracer"; export { NoopLogger } from "./noop-logger"; +export { NoopMetrics } from "./noop-metrics"; export { withSpan } from "./with-span"; export { withCapture } from "./with-capture"; export { isReported, markReported } from "./reported-flag"; diff --git a/packages/core-shared/src/instrumentation/otel/init-server-node.ts b/packages/core-shared/src/instrumentation/otel/init-server-node.ts index a7db035..0905879 100644 --- a/packages/core-shared/src/instrumentation/otel/init-server-node.ts +++ b/packages/core-shared/src/instrumentation/otel/init-server-node.ts @@ -18,8 +18,9 @@ export type InitOtelServerNodeOpts = { * Initializes the OpenTelemetry NodeSDK for a server-side app. * - Configures Resource attributes per OTel semantic conventions. * - Registers Sentry span processor (via createSentryOtelBridge) when DSN is set. - * - Registers Sentry log record processor (Phase 3) when DSN is set. - * - metricReader filled in Phase 4. + * - Registers Sentry log record processor when DSN is set. + * - Registers an in-process MeterProvider (no exporter — Sentry metrics not yet + * wired; a future phase or vendor-specific exporter can add a MetricReader). * - PII scrub processors land in Phase 5. * * Caller is responsible for `sdk.shutdown()` on process exit. @@ -42,11 +43,17 @@ export function initOtelServerNode(opts: InitOtelServerNodeOpts): NodeSDK { // to avoid blocking the hot path). const logRecordProcessors = bridge.logRecordProcessor ? [bridge.logRecordProcessor] : []; + // In-process MeterProvider with no reader/exporter. Sentry metrics ingestion + // is experimental in @sentry/opentelemetry 10.x and not wired here; metrics + // emit through the API but are not exported anywhere. A future phase can add + // a PeriodicExportingMetricReader when a vendor exporter is available. + const metricReader = undefined; + const sdk = new NodeSDK({ resource, spanProcessors, logRecordProcessors, - // metricReader filled in Phase 4 + metricReader, }); sdk.start(); diff --git a/packages/core-shared/src/instrumentation/symbols.ts b/packages/core-shared/src/instrumentation/symbols.ts index df770f8..17f939e 100644 --- a/packages/core-shared/src/instrumentation/symbols.ts +++ b/packages/core-shared/src/instrumentation/symbols.ts @@ -1,4 +1,5 @@ export const INSTRUMENTATION_SYMBOLS = { TRACER: Symbol.for("core-shared.TRACER"), LOGGER: Symbol.for("core-shared.LOGGER"), + METRICS: Symbol.for("core-shared.METRICS"), } as const;