From 53bfe727b43cac47f80cbff9fdf7ccea039ea1f0 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Mon, 11 May 2026 11:42:07 +0200 Subject: [PATCH] =?UTF-8?q?refactor(core-shared):=20rename=20bindSentryIns?= =?UTF-8?q?trumentation=20=E2=86=92=20bindOtelInstrumentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git mv bind-sentry-instrumentation → bind-otel-instrumentation; function renamed; new impl calls initOtelServerNode and binds OtelTracer (SentryLogger kept for Phase 3). Barrel re-exports both new name and deprecated alias bindSentryInstrumentation for one release. ESLint allowlist updated to the new filename. init-server-node opts gains release? field. Co-Authored-By: Claude Sonnet 4.6 --- packages/core-eslint/base.js | 4 +- .../di/bind-otel-instrumentation.test.ts | 55 +++++++++++++++++++ .../di/bind-otel-instrumentation.ts | 45 +++++++++++++++ .../di/bind-sentry-instrumentation.test.ts | 53 ------------------ .../di/bind-sentry-instrumentation.ts | 29 ---------- .../core-shared/src/instrumentation/index.ts | 11 +++- .../instrumentation/otel/init-server-node.ts | 1 + 7 files changed, 111 insertions(+), 87 deletions(-) create mode 100644 packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.test.ts create mode 100644 packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.ts delete mode 100644 packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.test.ts delete mode 100644 packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.ts diff --git a/packages/core-eslint/base.js b/packages/core-eslint/base.js index c0cb28f..34cf5ab 100644 --- a/packages/core-eslint/base.js +++ b/packages/core-eslint/base.js @@ -92,8 +92,8 @@ export default [ "**/instrumentation/sentry/**", "**/instrumentation/otel/sentry-bridge.{ts,js}", "**/instrumentation/otel/sentry-bridge.test.{ts,js}", - "**/instrumentation/di/bind-sentry-instrumentation.{ts,js}", - "**/instrumentation/di/bind-sentry-instrumentation.test.{ts,js}", + "**/instrumentation/di/bind-otel-instrumentation.{ts,js}", + "**/instrumentation/di/bind-otel-instrumentation.test.{ts,js}", "**/setup/no-sentry.{ts,js}", "**/setup/no-sentry.test.{ts,js}", "**/instrumentation.{ts,js,mjs}", diff --git a/packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.test.ts b/packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.test.ts new file mode 100644 index 0000000..e25407e --- /dev/null +++ b/packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.test.ts @@ -0,0 +1,55 @@ +// packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.test.ts +import "reflect-metadata"; +import { describe, it, expect, vi, beforeEach } from "vitest"; + +vi.mock("@sentry/nextjs", () => ({ + init: vi.fn(), + captureException: vi.fn(), + captureMessage: vi.fn(), + addBreadcrumb: vi.fn(), + setUser: vi.fn(), +})); + +vi.mock("@/instrumentation/otel/init-server-node", () => ({ + initOtelServerNode: vi.fn(), +})); + +import { Container } from "inversify"; +import { bindOtelInstrumentation } from "@/instrumentation/di/bind-otel-instrumentation"; +import { initOtelServerNode } from "@/instrumentation/otel/init-server-node"; +import { INSTRUMENTATION_SYMBOLS } from "@/instrumentation/symbols"; +import { OtelTracer } from "@/instrumentation/otel/otel-tracer"; +import { SentryLogger } from "@/instrumentation/sentry/sentry-logger"; + +describe("bindOtelInstrumentation", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("calls initOtelServerNode with the provided DSN and app as serviceName", () => { + const c = new Container(); + bindOtelInstrumentation(c, { dsn: "https://x@y/1", app: "web-next" }); + expect(initOtelServerNode).toHaveBeenCalledTimes(1); + expect((initOtelServerNode as ReturnType).mock.calls[0]![0]).toMatchObject({ + dsn: "https://x@y/1", + serviceName: "web-next", + }); + }); + + it("binds OtelTracer + SentryLogger to the container", () => { + const c = new Container(); + bindOtelInstrumentation(c, { dsn: "https://x@y/1", app: "web-next" }); + expect(c.get(INSTRUMENTATION_SYMBOLS.TRACER)).toBeInstanceOf(OtelTracer); + expect(c.get(INSTRUMENTATION_SYMBOLS.LOGGER)).toBeInstanceOf(SentryLogger); + }); + + it("returns the tracer + logger instances", () => { + const c = new Container(); + const { tracer, logger } = bindOtelInstrumentation(c, { + dsn: "https://x@y/1", + app: "web-next", + }); + expect(tracer).toBeInstanceOf(OtelTracer); + expect(logger).toBeInstanceOf(SentryLogger); + }); +}); diff --git a/packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.ts b/packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.ts new file mode 100644 index 0000000..b2049a4 --- /dev/null +++ b/packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.ts @@ -0,0 +1,45 @@ +// packages/core-shared/src/instrumentation/di/bind-otel-instrumentation.ts +import type { Container } from "inversify"; +import { OtelTracer } from "../otel/otel-tracer"; +import { SentryLogger } from "../sentry/sentry-logger"; +import { initOtelServerNode } from "../otel/init-server-node"; +import { INSTRUMENTATION_SYMBOLS } from "../symbols"; +import type { ITracer, ILogger } from "../index"; + +export type BindOtelOpts = { + dsn: string; + app: "web-next" | "cms" | "web-tanstack"; + release?: string; +}; + +export function bindOtelInstrumentation( + container: Container, + opts: BindOtelOpts, +): { tracer: ITracer; logger: ILogger } { + const environment = + process.env["SENTRY_ENVIRONMENT"] ?? + process.env["VERCEL_ENV"] ?? + process.env["NODE_ENV"] ?? + "development"; + const release = opts.release ?? process.env["VERCEL_GIT_COMMIT_SHA"] ?? "unknown"; + + initOtelServerNode({ + dsn: opts.dsn, + serviceName: opts.app, + environment, + release, + }); + + const tracer = new OtelTracer(); + const logger = new SentryLogger(); // Phase 3 replaces with OtelLogger + + if (container.isBound(INSTRUMENTATION_SYMBOLS.TRACER)) { + container.unbind(INSTRUMENTATION_SYMBOLS.TRACER); + } + if (container.isBound(INSTRUMENTATION_SYMBOLS.LOGGER)) { + container.unbind(INSTRUMENTATION_SYMBOLS.LOGGER); + } + container.bind(INSTRUMENTATION_SYMBOLS.TRACER).toConstantValue(tracer); + container.bind(INSTRUMENTATION_SYMBOLS.LOGGER).toConstantValue(logger); + return { tracer, logger }; +} diff --git a/packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.test.ts b/packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.test.ts deleted file mode 100644 index e381799..0000000 --- a/packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.test.ts +++ /dev/null @@ -1,53 +0,0 @@ -// packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.test.ts -import "reflect-metadata"; -import { describe, it, expect, vi, beforeEach } from "vitest"; - -vi.mock("@sentry/nextjs", () => ({ - init: vi.fn(), - startSpan: vi.fn((_opts: unknown, fn: (span: unknown) => unknown) => - fn({ setAttribute: vi.fn(), setStatus: vi.fn() }), - ), - captureException: vi.fn(), - captureMessage: vi.fn(), - addBreadcrumb: vi.fn(), - setUser: vi.fn(), - replayIntegration: vi.fn(() => ({ name: "Replay" })), -})); - -import * as Sentry from "@sentry/nextjs"; -import { Container } from "inversify"; -import { bindSentryInstrumentation } from "@/instrumentation/di/bind-sentry-instrumentation"; -import { INSTRUMENTATION_SYMBOLS } from "@/instrumentation/symbols"; -import { SentryTracer } from "@/instrumentation/sentry/sentry-tracer"; -import { SentryLogger } from "@/instrumentation/sentry/sentry-logger"; - -describe("bindSentryInstrumentation", () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - - it("calls Sentry.init via initSentryServer", () => { - const c = new Container(); - bindSentryInstrumentation(c, { dsn: "https://x@y/1", app: "web-next" }); - expect(Sentry.init).toHaveBeenCalledTimes(1); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - expect((Sentry.init as any).mock.calls[0][0].dsn).toBe("https://x@y/1"); - }); - - it("binds SentryTracer + SentryLogger to the container", () => { - const c = new Container(); - bindSentryInstrumentation(c, { dsn: "https://x@y/1", app: "web-next" }); - expect(c.get(INSTRUMENTATION_SYMBOLS.TRACER)).toBeInstanceOf(SentryTracer); - expect(c.get(INSTRUMENTATION_SYMBOLS.LOGGER)).toBeInstanceOf(SentryLogger); - }); - - it("returns the tracer + logger instances", () => { - const c = new Container(); - const { tracer, logger } = bindSentryInstrumentation(c, { - dsn: "https://x@y/1", - app: "web-next", - }); - expect(tracer).toBeInstanceOf(SentryTracer); - expect(logger).toBeInstanceOf(SentryLogger); - }); -}); diff --git a/packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.ts b/packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.ts deleted file mode 100644 index e52f5b7..0000000 --- a/packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.ts +++ /dev/null @@ -1,29 +0,0 @@ -// packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.ts -import type { Container } from "inversify"; -import { SentryTracer } from "../sentry/sentry-tracer"; -import { SentryLogger } from "../sentry/sentry-logger"; -import { initSentryServer, type InitServerOpts } from "../sentry/init-server"; -import { INSTRUMENTATION_SYMBOLS } from "../symbols"; -import type { ITracer, ILogger } from "../index"; - -export type BindSentryOpts = InitServerOpts; - -export function bindSentryInstrumentation( - container: Container, - opts: BindSentryOpts, -): { tracer: ITracer; logger: ILogger } { - initSentryServer(opts); - - const tracer = new SentryTracer(); - const logger = new SentryLogger(); - - if (container.isBound(INSTRUMENTATION_SYMBOLS.TRACER)) { - container.unbind(INSTRUMENTATION_SYMBOLS.TRACER); - } - if (container.isBound(INSTRUMENTATION_SYMBOLS.LOGGER)) { - container.unbind(INSTRUMENTATION_SYMBOLS.LOGGER); - } - container.bind(INSTRUMENTATION_SYMBOLS.TRACER).toConstantValue(tracer); - container.bind(INSTRUMENTATION_SYMBOLS.LOGGER).toConstantValue(logger); - return { tracer, logger }; -} diff --git a/packages/core-shared/src/instrumentation/index.ts b/packages/core-shared/src/instrumentation/index.ts index dbe7b13..d5dd58a 100644 --- a/packages/core-shared/src/instrumentation/index.ts +++ b/packages/core-shared/src/instrumentation/index.ts @@ -17,8 +17,13 @@ export { isReported, markReported } from "./reported-flag"; export { INSTRUMENTATION_SYMBOLS } from "./symbols"; export { bindNoopInstrumentation } from "./di/bind-noop-instrumentation"; export { - bindSentryInstrumentation, - type BindSentryOpts, -} from "./di/bind-sentry-instrumentation"; + bindOtelInstrumentation, + type BindOtelOpts, +} from "./di/bind-otel-instrumentation"; + +// Deprecated alias for one release cycle — callers should migrate to bindOtelInstrumentation. +export { bindOtelInstrumentation as bindSentryInstrumentation } from "./di/bind-otel-instrumentation"; +export type { BindOtelOpts as BindSentryOpts } from "./di/bind-otel-instrumentation"; + export { initSentryServerNode } from "./sentry/init-server-node"; export { initSentryClientReact } from "./sentry/init-client-react"; 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 e3adc36..92140ac 100644 --- a/packages/core-shared/src/instrumentation/otel/init-server-node.ts +++ b/packages/core-shared/src/instrumentation/otel/init-server-node.ts @@ -10,6 +10,7 @@ export type InitOtelServerNodeOpts = { serviceName: string; serviceVersion?: string; environment: string; + release?: string; namespace?: string; };