feat(core-shared): Sentry-as-OTel-exporter bridge module
This commit is contained in:
@@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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,
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user