feat(core-shared): OTel NodeSDK init helper with Sentry exporter wiring

This commit is contained in:
2026-05-11 11:24:55 +02:00
parent 3a32838c71
commit e85b8b12cf
2 changed files with 69 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
import { describe, it, expect } from "vitest";
import { initOtelServerNode } from "./init-server-node";
describe("initOtelServerNode", () => {
it("returns an SDK handle with shutdown()", () => {
const sdk = initOtelServerNode({
dsn: "",
serviceName: "test-service",
environment: "test",
});
expect(sdk).toBeDefined();
expect(typeof sdk.shutdown).toBe("function");
});
it("accepts a DSN and wires the Sentry bridge", () => {
const sdk = initOtelServerNode({
dsn: "https://test@sentry.io/1",
serviceName: "test-service",
environment: "test",
});
expect(sdk).toBeDefined();
});
});

View File

@@ -0,0 +1,46 @@
import { NodeSDK } from "@opentelemetry/sdk-node";
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { buildResource } from "./resource";
import { createSentryOtelBridge } from "./sentry-bridge";
export type InitOtelServerNodeOpts = {
/** Sentry DSN. When empty, OTel SDK boots without the Sentry exporter. */
dsn: string;
serviceName: string;
serviceVersion?: string;
environment: string;
namespace?: string;
};
/**
* 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.
* - logRecordProcessors filled in Phase 3; metricReader filled in Phase 4.
* - PII scrub processors land in Phase 5.
*
* Caller is responsible for `sdk.shutdown()` on process exit.
*/
export function initOtelServerNode(opts: InitOtelServerNodeOpts): NodeSDK {
const resource = buildResource({
serviceName: opts.serviceName,
serviceVersion: opts.serviceVersion,
environment: opts.environment,
namespace: opts.namespace,
});
const bridge = createSentryOtelBridge({ dsn: opts.dsn });
const spanProcessors = bridge.spanProcessor
? [new BatchSpanProcessor(bridge.spanProcessor as never)]
: [];
const sdk = new NodeSDK({
resource,
spanProcessors,
// logRecordProcessors filled in Phase 3
// metricReader filled in Phase 4
});
sdk.start();
return sdk;
}