feat(core-shared): Sentry-as-OTel-exporter bridge module

This commit is contained in:
2026-05-11 11:23:49 +02:00
parent 12aeb8bf37
commit 3a32838c71
2 changed files with 70 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
beforeEach(() => vi.resetModules());
describe("createSentryOtelBridge", () => {
it("returns a span processor when given a DSN", async () => {
// Mock @sentry/opentelemetry — we only verify the shape of what the bridge returns.
vi.doMock("@sentry/opentelemetry", () => ({
SentrySpanProcessor: class {
onStart() {}
onEnd() {}
forceFlush() {
return Promise.resolve();
}
shutdown() {
return Promise.resolve();
}
},
}));
const { createSentryOtelBridge } = await import("./sentry-bridge");
const bridge = createSentryOtelBridge({ dsn: "https://test@sentry.io/1" });
expect(bridge.spanProcessor).toBeDefined();
// logRecordProcessor is null in Phase 1 — @sentry/opentelemetry 10.x does not
// export SentryLogRecordProcessor. It will be wired in Phase 3 via @sentry/node.
expect(bridge.logRecordProcessor).toBeNull();
});
it("returns null processors when no DSN provided", async () => {
const { createSentryOtelBridge } = await import("./sentry-bridge");
const bridge = createSentryOtelBridge({ dsn: "" });
expect(bridge.spanProcessor).toBeNull();
expect(bridge.logRecordProcessor).toBeNull();
});
});

View File

@@ -0,0 +1,36 @@
import type { SpanProcessor } from "@opentelemetry/sdk-trace-base";
import type { LogRecordProcessor } from "@opentelemetry/sdk-logs";
export type SentryOtelBridgeOpts = {
/** Sentry DSN. When empty, no Sentry processors are returned (Noop boot). */
dsn: string;
};
export type SentryOtelBridge = {
spanProcessor: SpanProcessor | null;
/**
* Log record processor slot. Null in Phase 1 — @sentry/opentelemetry 10.x does
* not export SentryLogRecordProcessor. This slot is filled in Phase 3 when the
* OTel Logger is introduced and wired via @sentry/node's log SDK support.
*/
logRecordProcessor: LogRecordProcessor | null;
};
/**
* Creates Sentry-as-OTel-exporter processors. The OTel SDK uses these to
* forward spans (and, in Phase 3, log records) to Sentry. This is the ONLY
* file in core-shared that imports from `@sentry/opentelemetry` — all other
* Sentry coupling is excluded by the R40/R52 ESLint allowlist.
*/
export function createSentryOtelBridge(opts: SentryOtelBridgeOpts): SentryOtelBridge {
if (!opts.dsn) {
return { spanProcessor: null, logRecordProcessor: null };
}
// eslint-disable-next-line @typescript-eslint/no-require-imports
const sentryOtel = require("@sentry/opentelemetry");
return {
spanProcessor: new sentryOtel.SentrySpanProcessor() as SpanProcessor,
// logRecordProcessor wired in Phase 3 via @sentry/node logger support.
logRecordProcessor: null,
};
}