@burdenoff/be-sdk 2026.624.1 → 2026.701.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,11 @@
1
- export { AUDIT_FIELDS, GraphEventsPublisher, GraphExportService, GraphModule, SOFT_DELETE_FIELDS, STANDARD_FIELDS, TENANT_FIELDS, createGraphEventsHelper, createGraphExportService, createPrismaGraphIntegration, createRelationshipFromEntity, defineEntity, defineGraphConfig, defineModuleGraph, defineRelationship, getGraphEventsPublisher, getGraphStats, initializeGraph, isGraphInitialized } from '../chunk-DZK5UGDA.js';
1
+ export { AUDIT_FIELDS, GraphEventsPublisher, GraphExportService, GraphModule, SOFT_DELETE_FIELDS, STANDARD_FIELDS, TENANT_FIELDS, createGraphEventsHelper, createGraphExportService, createPrismaGraphIntegration, createRelationshipFromEntity, defineEntity, defineGraphConfig, defineModuleGraph, defineRelationship, getGraphEventsPublisher, getGraphStats, initializeGraph, isGraphInitialized } from '../chunk-Z2423JIB.js';
2
2
  export { GraphRegistry, addGraphExtension, createEntityEvent, createRelationshipEvent, extractEntityTitle, extractMinimalFields, getCollectionForEntity, parseRelationship, shouldSyncEntity, shouldSyncRelationship } from '../chunk-5CESUKWC.js';
3
- import '../chunk-EZ4PKRUK.js';
4
- import '../chunk-YFOHAHZE.js';
5
3
  import '../chunk-H3AXO5SY.js';
6
4
  import '../chunk-OHEPNJ2X.js';
7
5
  import '../chunk-MQCVQCFA.js';
8
6
  import '../chunk-MHNA7IS7.js';
7
+ import '../chunk-EZ4PKRUK.js';
8
+ import '../chunk-YFOHAHZE.js';
9
9
  import '../chunk-CBZNP6RF.js';
10
10
  import '../chunk-XE4OXN2W.js';
11
11
  //# sourceMappingURL=index.js.map
package/dist/index.js CHANGED
@@ -14,15 +14,18 @@ import { TenantNotificationsModule, NotificationsModule } from './chunk-IUL5TEKE
14
14
  export { tenant_notifications_exports as Notifications, NotificationsModule } from './chunk-IUL5TEKE.js';
15
15
  export { observability_exports as Observability } from './chunk-5LXDPGDH.js';
16
16
  export { platform_exports as Platform } from './chunk-UCLDHOZC.js';
17
- import { DatabaseModule } from './chunk-4OQRBSHM.js';
18
- export { DatabaseModule } from './chunk-4OQRBSHM.js';
19
17
  export { export_exports as Export } from './chunk-UJI2S556.js';
20
18
  export { feature_flags_exports as FeatureFlags } from './chunk-YEA4BZOL.js';
19
+ import { GraphModule } from './chunk-Z2423JIB.js';
20
+ export { graph_exports as Graph, GraphModule } from './chunk-Z2423JIB.js';
21
+ import './chunk-5CESUKWC.js';
22
+ import { EventsModule } from './chunk-H3AXO5SY.js';
23
+ export { event_queue_exports as EventQueue, EventsModule } from './chunk-H3AXO5SY.js';
24
+ import './chunk-OHEPNJ2X.js';
25
+ import { QueueType, EventQueueFactory } from './chunk-MQCVQCFA.js';
21
26
  export { graphql_exports as GraphQL } from './chunk-X4NELQLV.js';
22
27
  import './chunk-QLVKMWFA.js';
23
- import { GraphModule } from './chunk-DZK5UGDA.js';
24
- export { graph_exports as Graph, GraphModule } from './chunk-DZK5UGDA.js';
25
- import './chunk-5CESUKWC.js';
28
+ import './chunk-MHNA7IS7.js';
26
29
  export { i18n_exports as I18n, createTranslator, getLanguage, getLocale, hasI18n, t } from './chunk-ULFFX3YE.js';
27
30
  export { init_exports as Init } from './chunk-F5BPKP75.js';
28
31
  import { GatewayClient, GatewayError, GatewayErrorType } from './chunk-OWUVYM2S.js';
@@ -32,23 +35,20 @@ export { layer_exports as Layer } from './chunk-UIMPJNWC.js';
32
35
  import './chunk-VFCMR5GX.js';
33
36
  import { ContextManager } from './chunk-DXX6C6X6.js';
34
37
  export { ContextManager } from './chunk-DXX6C6X6.js';
35
- export { cache_exports as Cache } from './chunk-UYE4IEPT.js';
36
- export { captcha_exports as Captcha, isCaptchaEnabled, verifyCaptcha, verifyCaptchaIfEnabled } from './chunk-YMZEUTD2.js';
37
- export { createInternalClient, createInternalClientForTenant, createInternalClientForWorkspaces } from './chunk-VI4VSNTI.js';
38
38
  import { AuthModule } from './chunk-SS4XWRYR.js';
39
39
  export { AuthModule } from './chunk-SS4XWRYR.js';
40
40
  export { utils_exports as Utils } from './chunk-B7I4TABG.js';
41
+ export { cache_exports as Cache } from './chunk-UYE4IEPT.js';
42
+ export { captcha_exports as Captcha, isCaptchaEnabled, verifyCaptcha, verifyCaptchaIfEnabled } from './chunk-YMZEUTD2.js';
43
+ export { createInternalClient, createInternalClientForTenant, createInternalClientForWorkspaces } from './chunk-VI4VSNTI.js';
44
+ export { crypto_exports as Crypto } from './chunk-SBS4S2PJ.js';
45
+ import { DatabaseModule } from './chunk-4OQRBSHM.js';
46
+ export { DatabaseModule } from './chunk-4OQRBSHM.js';
41
47
  import { APIError, NetworkError, TimeoutError, ValidationError } from './chunk-EZ4PKRUK.js';
42
48
  export { DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_GATEWAY_RETRY_CONFIG, DEFAULT_GATEWAY_ROUTING, DEFAULT_LAYER_RESOURCES, DEFAULT_LAYER_STREAMS } from './chunk-YFOHAHZE.js';
43
- export { dataloader_exports as DataLoader } from './chunk-NUB5GQTU.js';
44
- import { EventsModule } from './chunk-H3AXO5SY.js';
45
- export { event_queue_exports as EventQueue, EventsModule } from './chunk-H3AXO5SY.js';
46
- import './chunk-OHEPNJ2X.js';
47
- import { QueueType, EventQueueFactory } from './chunk-MQCVQCFA.js';
48
- import './chunk-MHNA7IS7.js';
49
49
  import { logger } from './chunk-CBZNP6RF.js';
50
50
  export { logger_exports as Logger } from './chunk-CBZNP6RF.js';
51
- export { crypto_exports as Crypto } from './chunk-SBS4S2PJ.js';
51
+ export { dataloader_exports as DataLoader } from './chunk-NUB5GQTU.js';
52
52
  import { __name } from './chunk-XE4OXN2W.js';
53
53
  import { GraphQLClient } from 'graphql-request';
54
54
 
@@ -0,0 +1,5 @@
1
+ export { createPinoLogger } from './chunk-NRSIT4VI.js';
2
+ import './chunk-CBZNP6RF.js';
3
+ import './chunk-XE4OXN2W.js';
4
+ //# sourceMappingURL=pino-logger-TSRWXWIU.js.map
5
+ //# sourceMappingURL=pino-logger-TSRWXWIU.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"pino-logger-NVZXQPWO.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"pino-logger-TSRWXWIU.js"}
@@ -12,20 +12,26 @@ var asyncDisposeMetricReader = /* @__PURE__ */ __name(async (metricReaderCandida
12
12
  }
13
13
  }, "asyncDisposeMetricReader");
14
14
  async function createOtelSdk(cfg) {
15
+ console.log("[sdk] importing @opentelemetry/sdk-node...");
15
16
  const sdkNodeMod = "@opentelemetry/sdk-node";
16
17
  const sdkMod = await import(sdkNodeMod);
18
+ console.log("[sdk] importing @opentelemetry/resources...");
17
19
  const resourcesMod = "@opentelemetry/resources";
18
20
  const resources = await import(resourcesMod);
21
+ console.log("[sdk] importing @opentelemetry/semantic-conventions...");
19
22
  const semMod = "@opentelemetry/semantic-conventions";
20
23
  const sem = await import(semMod);
24
+ console.log("[sdk] importing @opentelemetry/exporter-trace-otlp-http...");
21
25
  const traceExpMod = "@opentelemetry/exporter-trace-otlp-http";
22
26
  const traceExp = await import(traceExpMod);
27
+ console.log("[sdk] importing @opentelemetry/exporter-metrics-otlp-http...");
23
28
  let metricsExp;
24
29
  try {
25
30
  const metricsExpMod = "@opentelemetry/exporter-metrics-otlp-http";
26
31
  metricsExp = await import(metricsExpMod);
27
32
  } catch {
28
33
  metricsExp = void 0;
34
+ console.log("[sdk] metrics exporter not available (non-fatal)");
29
35
  }
30
36
  let metricReader;
31
37
  let metricsEnabled = false;
@@ -55,6 +61,7 @@ async function createOtelSdk(cfg) {
55
61
  metricReader = void 0;
56
62
  }
57
63
  }
64
+ console.log("[sdk] importing @opentelemetry/sdk-trace-base for sampler...");
58
65
  let sampler;
59
66
  try {
60
67
  const traceBaseMod = "@opentelemetry/sdk-trace-base";
@@ -64,7 +71,9 @@ async function createOtelSdk(cfg) {
64
71
  });
65
72
  } catch {
66
73
  sampler = void 0;
74
+ console.log("[sdk] sampler not available (non-fatal)");
67
75
  }
76
+ console.log("[sdk] importing @opentelemetry/auto-instrumentations-node...");
68
77
  let autoInstrumentations;
69
78
  try {
70
79
  const autoMod = "@opentelemetry/auto-instrumentations-node";
@@ -74,8 +83,10 @@ async function createOtelSdk(cfg) {
74
83
  enabled: false
75
84
  }
76
85
  });
86
+ console.log("[sdk] auto-instrumentations loaded");
77
87
  } catch {
78
88
  autoInstrumentations = void 0;
89
+ console.log("[sdk] auto-instrumentations not available (non-fatal)");
79
90
  }
80
91
  const serviceNamespaceByBoundary = {
81
92
  wspace: "workspaces",
@@ -101,6 +112,7 @@ async function createOtelSdk(cfg) {
101
112
  const traceExporter = new traceExp.OTLPTraceExporter({
102
113
  url: `${cfg.otlpEndpoint.replace(/\/$/, "")}/v1/traces`
103
114
  });
115
+ console.log("[sdk] constructing NodeSDK...");
104
116
  const nodeSdk = new sdkMod.NodeSDK({
105
117
  resource,
106
118
  traceExporter,
@@ -114,15 +126,20 @@ async function createOtelSdk(cfg) {
114
126
  instrumentations: autoInstrumentations
115
127
  } : {}
116
128
  });
129
+ console.log("[sdk] NodeSDK constructed, calling start()...");
117
130
  const startResult = nodeSdk.start();
118
131
  if (isThenable(startResult)) {
119
132
  await startResult;
120
133
  }
134
+ console.log("[sdk] NodeSDK started");
121
135
  try {
122
136
  const otelApiMod = "@opentelemetry/api";
123
137
  globalThis.__otelApi = await import(otelApiMod);
138
+ console.log("[sdk] @opentelemetry/api stashed for pino mixin");
124
139
  } catch {
140
+ console.log("[sdk] @opentelemetry/api stash failed (non-fatal)");
125
141
  }
142
+ console.log("[sdk] OTel SDK initialization complete");
126
143
  return {
127
144
  shutdown: /* @__PURE__ */ __name(async () => nodeSdk.shutdown(), "shutdown"),
128
145
  metricsEnabled,
@@ -132,5 +149,5 @@ async function createOtelSdk(cfg) {
132
149
  __name(createOtelSdk, "createOtelSdk");
133
150
 
134
151
  export { createOtelSdk };
135
- //# sourceMappingURL=sdk-UWFH5PY7.js.map
136
- //# sourceMappingURL=sdk-UWFH5PY7.js.map
152
+ //# sourceMappingURL=sdk-YS2M6RF5.js.map
153
+ //# sourceMappingURL=sdk-YS2M6RF5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/telemetry/sdk.ts"],"names":["isThenable","value","then","asyncDisposeMetricReader","metricReaderCandidate","shutdown","result","call","createOtelSdk","cfg","console","log","sdkNodeMod","sdkMod","resourcesMod","resources","semMod","sem","traceExpMod","traceExp","metricsExp","metricsExpMod","undefined","metricReader","metricsEnabled","metricsDropReason","OTLPMetricExporter","metricsSdkMod","metricsSdk","candidate","PeriodicExportingMetricReader","exporter","url","otlpEndpoint","replace","setProducer","setMetricProducer","sampler","traceBaseMod","traceBase","ParentBasedSampler","root","TraceIdRatioBasedSampler","Math","min","max","sampleRatio","autoInstrumentations","autoMod","auto","getNodeAutoInstrumentations","enabled","serviceNamespaceByBoundary","wspace","global","gateway","resourceAttributes","serviceName","serviceVersion","boundary","env","module","serviceInstanceId","process","clusterName","resource","resourceFromAttributes","traceExporter","OTLPTraceExporter","nodeSdk","NodeSDK","instrumentations","startResult","start","otelApiMod","globalThis","__otelApi"],"mappings":"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","file":"sdk-YS2M6RF5.js","sourcesContent":["/**\n * Thin wrapper that initializes `@opentelemetry/sdk-node` with the\n * OTLPTrace + OTLPMetric exporters and standard auto-instrumentations.\n *\n * All imports are dynamic so services that haven't installed sdk-node\n * still compile and run. The function resolves `undefined` when the SDK\n * isn't available, letting `bootstrapTelemetry` fall back gracefully.\n */\nimport type { Boundary, Env } from './index.js';\n\nexport interface OtelSdkConfig {\n serviceName: string;\n serviceVersion: string;\n boundary: Boundary;\n module?: string;\n env: Env;\n otlpEndpoint: string;\n sampleRatio: number;\n}\n\nexport interface OtelSdkHandle {\n shutdown: () => Promise<void>;\n metricsEnabled: boolean;\n metricsDropReason?: string;\n}\n\ntype Thenable = {\n then: (onfulfilled?: (value: void) => void, onrejected?: (reason: unknown) => void) => unknown;\n};\n\nconst isThenable = (value: unknown): value is Thenable => {\n return typeof value === 'object' && value !== null && typeof (value as { then?: unknown }).then === 'function';\n};\n\nconst asyncDisposeMetricReader = async (metricReaderCandidate: unknown): Promise<void> => {\n const shutdown = (metricReaderCandidate as { shutdown?: () => void | Promise<void> }).shutdown;\n if (typeof shutdown === 'function') {\n const result = shutdown.call(metricReaderCandidate) as unknown;\n if (isThenable(result)) await result;\n }\n};\n\nexport async function createOtelSdk(cfg: OtelSdkConfig): Promise<OtelSdkHandle> {\n // Use local string variables so TypeScript skips static module resolution for\n // optional peer dependencies that may not be installed.\n console.log('[sdk] importing @opentelemetry/sdk-node...');\n const sdkNodeMod = '@opentelemetry/sdk-node';\n const sdkMod = (await import(sdkNodeMod)) as unknown as {\n NodeSDK: new (init: Record<string, unknown>) => {\n start: () => void;\n shutdown: () => Promise<void>;\n };\n };\n\n console.log('[sdk] importing @opentelemetry/resources...');\n const resourcesMod = '@opentelemetry/resources';\n const resources = (await import(resourcesMod)) as unknown as {\n resourceFromAttributes: (attrs: Record<string, string | number>) => unknown;\n };\n\n console.log('[sdk] importing @opentelemetry/semantic-conventions...');\n const semMod = '@opentelemetry/semantic-conventions';\n const sem = (await import(semMod)) as unknown as Record<string, string>;\n\n console.log('[sdk] importing @opentelemetry/exporter-trace-otlp-http...');\n const traceExpMod = '@opentelemetry/exporter-trace-otlp-http';\n const traceExp = (await import(traceExpMod)) as unknown as {\n OTLPTraceExporter: new (init: Record<string, string>) => unknown;\n };\n\n console.log('[sdk] importing @opentelemetry/exporter-metrics-otlp-http...');\n let metricsExp: { OTLPMetricExporter?: new (init: Record<string, string>) => unknown } | undefined;\n try {\n const metricsExpMod = '@opentelemetry/exporter-metrics-otlp-http';\n metricsExp = await import(metricsExpMod);\n } catch {\n metricsExp = undefined;\n console.log('[sdk] metrics exporter not available (non-fatal)');\n }\n\n let metricReader: unknown;\n let metricsEnabled = false;\n let metricsDropReason: string | undefined;\n if (metricsExp?.OTLPMetricExporter) {\n try {\n const metricsSdkMod = '@opentelemetry/sdk-metrics';\n const metricsSdk = (await import(metricsSdkMod)) as unknown as {\n PeriodicExportingMetricReader: new (init: Record<string, unknown>) => unknown;\n };\n const candidate = new metricsSdk.PeriodicExportingMetricReader({\n exporter: new metricsExp.OTLPMetricExporter({\n url: `${cfg.otlpEndpoint.replace(/\\/$/, '')}/v1/metrics`,\n }),\n });\n // Pre-flight API compatibility check. Some OTel package version\n // combinations construct `PeriodicExportingMetricReader` successfully\n // but lack `setMetricProducer` on the prototype chain (mixed\n // sdk-metrics versions, or runtime-specific class-inheritance\n // quirks — Bun has surfaced this in the past). Without the check,\n // `NodeSDK.start()` may register the global tracer provider BEFORE\n // it tries to call `setMetricProducer` and throws — leaving the\n // global tracer pointing at a half-initialized provider whose\n // span pipeline never drains. Skipping the metric reader when the\n // API isn't there avoids that whole failure mode in one pass.\n const setProducer = (candidate as { setMetricProducer?: unknown }).setMetricProducer;\n if (typeof setProducer === 'function') {\n metricReader = candidate;\n metricsEnabled = true;\n } else {\n metricsDropReason =\n 'setMetricProducer is not a function on PeriodicExportingMetricReader; skipping metrics path';\n await asyncDisposeMetricReader(candidate);\n metricReader = undefined;\n }\n } catch {\n if (metricsDropReason === undefined) {\n metricsDropReason = 'metric reader construction or compatibility check failed';\n }\n metricReader = undefined;\n }\n }\n\n console.log('[sdk] importing @opentelemetry/sdk-trace-base for sampler...');\n let sampler: unknown;\n try {\n const traceBaseMod = '@opentelemetry/sdk-trace-base';\n const traceBase = (await import(traceBaseMod)) as unknown as {\n ParentBasedSampler: new (init: Record<string, unknown>) => unknown;\n TraceIdRatioBasedSampler: new (ratio: number) => unknown;\n };\n sampler = new traceBase.ParentBasedSampler({\n root: new traceBase.TraceIdRatioBasedSampler(Math.min(1, Math.max(0, cfg.sampleRatio))),\n });\n } catch {\n sampler = undefined;\n console.log('[sdk] sampler not available (non-fatal)');\n }\n\n // Some services have auto-instrumentations installed; optional.\n console.log('[sdk] importing @opentelemetry/auto-instrumentations-node...');\n let autoInstrumentations: unknown[] | undefined;\n try {\n const autoMod = '@opentelemetry/auto-instrumentations-node';\n const auto = (await import(autoMod)) as unknown as {\n getNodeAutoInstrumentations: (cfg?: Record<string, unknown>) => unknown[];\n };\n autoInstrumentations = auto.getNodeAutoInstrumentations({\n '@opentelemetry/instrumentation-fs': { enabled: false },\n });\n console.log('[sdk] auto-instrumentations loaded');\n } catch {\n autoInstrumentations = undefined;\n console.log('[sdk] auto-instrumentations not available (non-fatal)');\n }\n\n const serviceNamespaceByBoundary: Record<Boundary, string> = {\n wspace: 'workspaces',\n global: 'tenant',\n gateway: 'gateways',\n };\n const resourceAttributes: Record<string, string> = {\n [sem['SEMRESATTRS_SERVICE_NAME'] ?? 'service.name']: cfg.serviceName,\n [sem['SEMRESATTRS_SERVICE_VERSION'] ?? 'service.version']: cfg.serviceVersion,\n [sem['SEMRESATTRS_SERVICE_NAMESPACE'] ?? 'service.namespace']: serviceNamespaceByBoundary[cfg.boundary],\n [sem['SEMRESATTRS_DEPLOYMENT_ENVIRONMENT'] ?? 'deployment.environment']: cfg.env,\n 'burdenoff.boundary': cfg.boundary,\n };\n if (cfg.module) resourceAttributes['burdenoff.module'] = cfg.module;\n const serviceInstanceId = process.env['POD_NAME'] ?? process.env['HOSTNAME'];\n if (serviceInstanceId) resourceAttributes['service.instance.id'] = serviceInstanceId;\n const clusterName = process.env['CLUSTER_NAME'];\n if (clusterName) {\n resourceAttributes['cluster'] = clusterName;\n resourceAttributes['k8s.cluster.name'] = clusterName;\n }\n\n const resource = resources.resourceFromAttributes(resourceAttributes);\n\n const traceExporter = new traceExp.OTLPTraceExporter({\n url: `${cfg.otlpEndpoint.replace(/\\/$/, '')}/v1/traces`,\n });\n\n // Single NodeSDK, single start. The pre-flight `setMetricProducer`\n // check above means we never pass an incompatible metric reader into\n // NodeSDK construction — so we no longer need the prior catch+rebuild\n // fallback dance, which had its own side-effect: the failed first\n // NodeSDK could leave the global tracer provider partially registered,\n // and the second NodeSDK's `setGlobalTracerProvider` becomes a no-op\n // — meaning spans flow into the FIRST (broken) provider and never\n // reach the exporter. Eliminating the fallback eliminates that hazard.\n console.log('[sdk] constructing NodeSDK...');\n const nodeSdk = new sdkMod.NodeSDK({\n resource,\n traceExporter,\n ...(metricReader ? { metricReader } : {}),\n ...(sampler ? { sampler } : {}),\n ...(autoInstrumentations ? { instrumentations: autoInstrumentations } : {}),\n });\n console.log('[sdk] NodeSDK constructed, calling start()...');\n // NodeSDK.start() returns void in modern versions and Promise<void> in older\n // ones. Cast to a permissive thenable shape so awaiting works either way\n // without tripping `@typescript-eslint/await-thenable`.\n const startResult = nodeSdk.start() as unknown;\n if (isThenable(startResult)) {\n await startResult;\n }\n console.log('[sdk] NodeSDK started');\n\n // Stash the @opentelemetry/api reference for pino-logger's mixin.\n try {\n const otelApiMod = '@opentelemetry/api';\n (globalThis as unknown as { __otelApi?: unknown }).__otelApi = await import(otelApiMod);\n console.log('[sdk] @opentelemetry/api stashed for pino mixin');\n } catch {\n console.log('[sdk] @opentelemetry/api stash failed (non-fatal)');\n }\n\n console.log('[sdk] OTel SDK initialization complete');\n return {\n shutdown: async (): Promise<void> => nodeSdk.shutdown(),\n metricsEnabled,\n metricsDropReason,\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- export { DEFAULT_REDACT_PATHS, createPinoLogger } from '../chunk-E5USZ2MR.js';
1
+ export { DEFAULT_REDACT_PATHS, createPinoLogger } from '../chunk-NRSIT4VI.js';
2
2
  import { setActiveTelemetryLogger, setupInstrumentation } from '../chunk-ACYGOENW.js';
3
3
  export { initializeInstrumentation, setupInstrumentation } from '../chunk-ACYGOENW.js';
4
4
  import '../chunk-REF7PANB.js';
@@ -132,7 +132,7 @@ async function bootstrapTelemetry(cfg) {
132
132
  const serviceVersion = resolveVersion(cfg.serviceVersion);
133
133
  const otlpEndpoint = resolveEndpoint(cfg.otlpEndpoint);
134
134
  const sampleRatio = resolveSampling(cfg.sampleRatio, env);
135
- const { createPinoLogger: createPinoLogger2 } = await import('../pino-logger-NVZXQPWO.js');
135
+ const { createPinoLogger: createPinoLogger2 } = await import('../pino-logger-TSRWXWIU.js');
136
136
  const logger2 = await createPinoLogger2({
137
137
  serviceName: cfg.serviceName,
138
138
  env,
@@ -153,8 +153,9 @@ async function bootstrapTelemetry(cfg) {
153
153
  });
154
154
  let otelSdk;
155
155
  if (resolveOtelSdkEnabled()) {
156
+ console.log("[telemetry] OTel SDK bootstrap starting...");
156
157
  try {
157
- const { createOtelSdk } = await import('../sdk-UWFH5PY7.js');
158
+ const { createOtelSdk } = await import('../sdk-YS2M6RF5.js');
158
159
  otelSdk = await createOtelSdk({
159
160
  serviceName: cfg.serviceName,
160
161
  serviceVersion,
@@ -170,19 +171,23 @@ async function bootstrapTelemetry(cfg) {
170
171
  sampleRatio,
171
172
  metricsEnabled: otelSdk.metricsEnabled
172
173
  });
174
+ console.log("[telemetry] OTel SDK exporter pipeline started");
173
175
  if (!otelSdk.metricsEnabled && otelSdk.metricsDropReason) {
174
176
  logger2.warn("[telemetry] OpenTelemetry metrics reader disabled; continuing with traces only", {
175
177
  serviceName: cfg.serviceName,
176
178
  reason: otelSdk.metricsDropReason
177
179
  });
180
+ console.warn("[telemetry] OTel SDK metrics reader disabled:", otelSdk.metricsDropReason);
178
181
  }
179
182
  } catch (err) {
180
183
  logger2.warn("[telemetry] OpenTelemetry exporter pipeline failed to start; continuing with logs only", {
181
184
  error: err instanceof Error ? err.message : String(err)
182
185
  });
186
+ console.error("[telemetry] OTel SDK failed:", err);
183
187
  }
184
188
  } else {
185
189
  logger2.info("[telemetry] OTel SDK exporter disabled by env");
190
+ console.log("[telemetry] OTel SDK exporter disabled by env");
186
191
  }
187
192
  const shutdown = /* @__PURE__ */ __name(async () => {
188
193
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/telemetry/health.ts","../../src/telemetry/metrics-endpoint.ts","../../src/telemetry/prisma-logging.ts","../../src/telemetry/index.ts"],"names":["createHealthRoutes","_deps","Proxy","get","_target","prop","undefined","loadDefaultRegistry","mod","collectDefaultMetrics","register","createMetricsRoutesImpl","app","opts","path","ctx","registry","ctxWithSet","set","status","headers","contentType","metrics","createMetricsRoutes","createPrismaLoggingExtension","logger","name","query","$allOperations","model","operation","args","start","Date","now","result","debug","duration_ms","redactSensitiveFields","err","error","Error","message","String","resolveEnv","explicit","fromEnv","process","env","resolveVersion","resolveEndpoint","proto","resolveSampling","Number","isFinite","Math","min","max","parsed","resolveOtelSdkEnabled","sdkDisabled","otelEnabled","bootstrapTelemetry","cfg","serviceVersion","otlpEndpoint","sampleRatio","createPinoLogger","serviceName","version","setActiveTelemetryLogger","instrumentation","setupInstrumentation","tracing","samplingRate","otelSdk","createOtelSdk","boundary","module","info","metricsEnabled","metricsDropReason","warn","reason","shutdown","defaultLogger","setLevel","getLevel"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * `/health`, `/health/live`, `/health/ready` Elysia routes with a 1s\n * result cache so readiness checks can't stampede Postgres.\n *\n * Dependencies (prisma, eventQueue, valkey) are optional — omit any client and\n * the readiness check simply skips it.\n */\n\ninterface PrismaLike {\n $queryRaw: (strings: TemplateStringsArray) => Promise<unknown>;\n}\ninterface EventQueueLike {\n isConnected?: () => boolean | Promise<boolean>;\n healthCheck?: () => Promise<{ ok: boolean }>;\n}\ninterface ValkeyLike {\n ping: () => Promise<unknown>;\n}\n\nexport interface HealthDeps {\n prisma?: PrismaLike;\n eventQueue?: EventQueueLike;\n valkey?: ValkeyLike;\n /** Service version reported on /health. */\n version?: string;\n /** Service name reported on /health. */\n serviceName?: string;\n}\n\ninterface CachedStatus {\n ready: boolean;\n checked: Record<string, { ok: boolean; error?: string }>;\n at: number;\n}\n\nconst CACHE_TTL_MS = 1000;\n\nasync function probeReady(deps: HealthDeps): Promise<CachedStatus> {\n const checked: Record<string, { ok: boolean; error?: string }> = {};\n\n if (deps.prisma) {\n try {\n await deps.prisma.$queryRaw`SELECT 1`;\n checked['postgres'] = { ok: true };\n } catch (err) {\n checked['postgres'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n if (deps.eventQueue) {\n try {\n const connected =\n typeof deps.eventQueue.isConnected === 'function'\n ? await Promise.resolve(deps.eventQueue.isConnected())\n : ((await deps.eventQueue.healthCheck?.())?.ok ?? true);\n checked['eventQueue'] = { ok: Boolean(connected) };\n } catch (err) {\n checked['eventQueue'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n if (deps.valkey) {\n try {\n await deps.valkey.ping();\n checked['valkey'] = { ok: true };\n } catch (err) {\n checked['valkey'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n const ready = Object.values(checked).every((c) => c.ok);\n return { ready, checked, at: Date.now() };\n}\n\nexport function createHealthRoutes(_deps: HealthDeps = {}): unknown {\n // Return an Elysia app lazily so be-sdk doesn't hard-require elysia.\n return new Proxy(\n {},\n {\n get(_target, prop): unknown {\n // Tell TypeScript consumers the returned object is an Elysia plugin;\n // the actual mount happens via `createHealthRoutesImpl`. Services\n // that prefer direct use can call `createHealthRoutesImpl(elysia, deps)`.\n if (prop === 'use' || prop === 'then') return undefined;\n return undefined;\n },\n }\n );\n}\n\n/**\n * Mount health routes on an existing Elysia app. Callers hold a reference\n * to Elysia themselves; be-sdk stays decoupled.\n */\nexport function createHealthRoutesImpl<\n App extends {\n get: (path: string, handler: (ctx: unknown) => unknown) => App;\n },\n>(app: App, deps: HealthDeps = {}): App {\n let cache: CachedStatus | null = null;\n\n const getStatus = async (): Promise<CachedStatus> => {\n if (cache && Date.now() - cache.at < CACHE_TTL_MS) return cache;\n cache = await probeReady(deps);\n return cache;\n };\n\n app.get('/health/live', () => ({\n status: 'ok',\n serviceName: deps.serviceName,\n version: deps.version,\n }));\n\n app.get('/health/ready', async (ctx: unknown): Promise<unknown> => {\n const status = await getStatus();\n const ctxWithSet = ctx as { set?: { status?: number } };\n if (!status.ready && ctxWithSet.set) ctxWithSet.set.status = 503;\n return {\n status: status.ready ? 'ok' : 'degraded',\n serviceName: deps.serviceName,\n version: deps.version,\n checks: status.checked,\n };\n });\n\n app.get('/health', async (ctx: unknown): Promise<unknown> => {\n const status = await getStatus();\n const ctxWithSet = ctx as { set?: { status?: number } };\n if (!status.ready && ctxWithSet.set) ctxWithSet.set.status = 503;\n return {\n status: status.ready ? 'ok' : 'degraded',\n serviceName: deps.serviceName,\n version: deps.version,\n checks: status.checked,\n uptime_s: Math.round(process.uptime()),\n };\n });\n\n return app;\n}\n","/**\n * Prometheus `/metrics` route mounter. Uses the shared `prom-client`\n * default registry so all instrumentation (GraphQL Envelop, Prisma,\n * runtime) shows up on a single endpoint.\n */\n\ninterface PromRegistryLike {\n metrics: () => Promise<string> | string;\n contentType?: string;\n}\n\nexport interface MetricsMountOptions {\n registry?: PromRegistryLike;\n path?: string;\n}\n\nexport async function loadDefaultRegistry(): Promise<PromRegistryLike | null> {\n try {\n const mod = (await import('prom-client')) as unknown as {\n register: PromRegistryLike;\n collectDefaultMetrics: (opts?: Record<string, unknown>) => void;\n };\n // Kick runtime metrics into the default registry if not already.\n try {\n mod.collectDefaultMetrics({ register: mod.register });\n } catch {\n // Already registered — ignore duplicate-metric errors.\n }\n return mod.register;\n } catch {\n return null;\n }\n}\n\nexport function createMetricsRoutesImpl<\n App extends {\n get: (path: string, handler: (ctx: unknown) => unknown) => App;\n },\n>(app: App, opts: MetricsMountOptions = {}): App {\n const path = opts.path ?? '/metrics';\n\n app.get(path, async (ctx: unknown): Promise<unknown> => {\n const registry = opts.registry ?? (await loadDefaultRegistry());\n const ctxWithSet = ctx as { set?: { status?: number; headers?: Record<string, string> } };\n if (!registry) {\n if (ctxWithSet.set) ctxWithSet.set.status = 503;\n return '# prom-client not installed\\n';\n }\n if (ctxWithSet.set) {\n ctxWithSet.set.status = 200;\n ctxWithSet.set.headers = {\n 'content-type': registry.contentType ?? 'text/plain; version=0.0.4; charset=utf-8',\n };\n }\n return registry.metrics();\n });\n\n return app;\n}\n\n/**\n * Legacy export name used by the service template. Composes the Elysia\n * plugin-style function that `new Elysia().use(...)` accepts.\n */\nexport function createMetricsRoutes(opts: MetricsMountOptions = {}): unknown {\n return (app: Parameters<typeof createMetricsRoutesImpl>[0]): unknown => createMetricsRoutesImpl(app, opts);\n}\n","/**\n * Prisma client extension that pipes query events through the SDK logger\n * with trace/span correlation fields auto-injected. The\n * `@prisma/instrumentation` peer provides the spans\n * themselves; this extension only adds structured log events on top.\n */\nimport type { Logger } from '../logger/index.js';\nimport { redactSensitiveFields } from '../logger/index.js';\n\ntype PrismaQueryArgs = {\n model?: string;\n operation: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n};\n\n/**\n * Returns a Prisma Client extension object compatible with the\n * `$extends()` API (Prisma v5+).\n *\n * ```ts\n * export const prisma = new PrismaClient().$extends(\n * createPrismaLoggingExtension(logger)\n * );\n * ```\n */\nexport function createPrismaLoggingExtension(logger: Logger): {\n name: string;\n query: {\n $allOperations: (args: PrismaQueryArgs) => Promise<unknown>;\n };\n} {\n return {\n name: 'burdenoff-pino-logging',\n query: {\n async $allOperations({ model, operation, args, query }: PrismaQueryArgs): Promise<unknown> {\n const start = Date.now();\n try {\n const result = await query(args);\n logger.debug('prisma.query', {\n model,\n operation,\n duration_ms: Date.now() - start,\n args: redactSensitiveFields(args),\n });\n return result;\n } catch (err) {\n logger.error('prisma.error', {\n model,\n operation,\n duration_ms: Date.now() - start,\n error: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n },\n },\n };\n}\n","/**\n * Unified telemetry bootstrap for Burdenoff services.\n *\n * Composes the existing `instrumentation/` + `observability/` + `logger/`\n * modules and adds:\n * - `bootstrapTelemetry({ serviceName, boundary, module, env })` — single\n * call that initializes OTel, wires Pino logger with trace fields,\n * exposes GraphQL Yoga plugins, registers process exit hooks.\n * - `createHealthRoutes({ prisma, nats, valkey, version })` — `/health`,\n * `/health/live`, `/health/ready` Elysia routes.\n * - `createMetricsRoutes(registry?)` — `/metrics` Prometheus exposition.\n * - `createPrismaLoggingExtension(logger)` — Prisma extension that pipes\n * query events through Pino with trace/span correlation ids.\n *\n * The module does not pull in `@opentelemetry/sdk-node` or `pino` as direct\n * deps — services install those as optional peers, and imports are lazy so\n * services that don't install them still load.\n */\n\nimport type { Logger as BaseLogger } from '../logger/index.js';\nimport { logger as defaultLogger } from '../logger/index.js';\nimport {\n initializeInstrumentation,\n setupInstrumentation,\n type SetupInstrumentationOptions,\n type InstrumentationSetupResult,\n} from '../instrumentation/index.js';\nimport { setActiveTelemetryLogger } from './logger-state.js';\nimport type { OtelSdkHandle } from './sdk.js';\n\nexport { createHealthRoutes } from './health.js';\nexport { createMetricsRoutes } from './metrics-endpoint.js';\nexport { createPrismaLoggingExtension } from './prisma-logging.js';\nexport { DEFAULT_REDACT_PATHS } from './pino-redaction.js';\nexport { createPinoLogger } from './pino-logger.js';\n\nexport type Boundary = 'wspace' | 'global' | 'gateway';\nexport type Env = 'alpha' | 'prod' | 'dev';\n\nexport interface TelemetryConfig {\n /** Full service name, e.g. \"wspace-auth-svc\". */\n serviceName: string;\n /** Semver of the service deployment; defaults to `process.env.npm_package_version`. */\n serviceVersion?: string;\n /** Monorepo boundary: `wspace`, `global`, or `gateway`. */\n boundary: Boundary;\n /** Module slug, e.g. `auth` (omit for gateways). */\n module?: string;\n /** Deployment environment; defaults to alpha for non-production NODE_ENV. */\n env?: Env;\n /**\n * OTLP endpoint for spans/metrics/logs. Defaults to\n * `$OTEL_EXPORTER_OTLP_ENDPOINT` or\n * `http://alloy.sre.svc.cluster.local:4318`.\n */\n otlpEndpoint?: string;\n /** Head-based sampling ratio. Default: alpha=1.0, prod=0.1. */\n sampleRatio?: number;\n /** Extra options forwarded to `setupInstrumentation`. */\n instrumentation?: SetupInstrumentationOptions;\n}\n\nexport interface TelemetryHandle {\n /** The configured service name (for use in health routes, etc.). */\n serviceName: string;\n /** The resolved service version. */\n serviceVersion: string;\n /** Environment. */\n env: Env;\n /** The Pino-backed logger. */\n logger: BaseLogger;\n /** Initialized instrumentation (tracer + metrics + plugins). */\n instrumentation: InstrumentationSetupResult;\n /** Cleanup hook; services call on SIGTERM. */\n shutdown: () => Promise<void>;\n}\n\nfunction resolveEnv(explicit?: Env): Env {\n if (explicit) return explicit;\n const fromEnv = process.env['DEPLOY_ENV'] ?? process.env['NODE_ENV'] ?? '';\n if (fromEnv === 'production' || fromEnv === 'prod') return 'prod';\n if (fromEnv === 'development' || fromEnv === 'dev') return 'dev';\n return 'alpha';\n}\n\nfunction resolveVersion(explicit?: string): string {\n if (explicit) return explicit;\n return process.env['npm_package_version'] ?? process.env['SERVICE_VERSION'] ?? '0.0.0';\n}\n\nfunction resolveEndpoint(explicit?: string): string {\n if (explicit) return explicit;\n const proto = 'http';\n // NOTE (ACA / current prod): the `alloy.sre.svc.cluster.local` fallback is a\n // LEGACY Kubernetes in-cluster DNS name and does NOT resolve on Azure\n // Container Apps. In ACA, service metrics reach Grafana/Azure Monitor via the\n // Prometheus `/metrics` *pull* path (the otel-collector scrapes each app) —\n // see `~/products/dev/platform/context/sre/HOW_TO_INTEGRATE_SRE_BACKEND.md`.\n // OTLP *push* (traces/metrics) only works where `OTEL_EXPORTER_OTLP_ENDPOINT`\n // is explicitly set to the env's otel-collector OTLP receiver. Kept as the\n // default for local/K8s remnants; override via env in ACA.\n return process.env['OTEL_EXPORTER_OTLP_ENDPOINT'] ?? `${proto}://alloy.sre.svc.cluster.local:4318`;\n}\n\nfunction resolveSampling(explicit: number | undefined, env: Env): number {\n if (typeof explicit === 'number' && Number.isFinite(explicit)) return Math.min(1, Math.max(0, explicit));\n const fromEnv = process.env['OTEL_TRACES_SAMPLER_ARG'];\n if (fromEnv) {\n const parsed = Number(fromEnv);\n if (Number.isFinite(parsed)) return Math.min(1, Math.max(0, parsed));\n }\n if (env === 'prod') return 0.1;\n return 1.0;\n}\n\nfunction resolveOtelSdkEnabled(): boolean {\n const sdkDisabled = process.env['OTEL_SDK_DISABLED'];\n if (sdkDisabled === 'true' || sdkDisabled === '1') return false;\n const otelEnabled = process.env['OTEL_ENABLED'];\n if (otelEnabled === 'false' || otelEnabled === '0') return false;\n return true;\n}\n\n/**\n * Bootstrap the full telemetry stack for a service.\n *\n * Services call this ONCE at startup **before** importing Prisma / GraphQL\n * Yoga / NATS so OTel can auto-instrument their dependencies.\n *\n * ```ts\n * // src/telemetry.ts\n * import { bootstrapTelemetry } from '@burdenoff/be-sdk/telemetry';\n * export const telemetry = await bootstrapTelemetry({\n * serviceName: 'wspace-auth-svc',\n * boundary: 'wspace',\n * module: 'auth',\n * });\n *\n * // src/index.ts — must be the FIRST import line.\n * import './telemetry.js';\n * ```\n */\nexport async function bootstrapTelemetry(cfg: TelemetryConfig): Promise<TelemetryHandle> {\n const env = resolveEnv(cfg.env);\n const serviceVersion = resolveVersion(cfg.serviceVersion);\n const otlpEndpoint = resolveEndpoint(cfg.otlpEndpoint);\n const sampleRatio = resolveSampling(cfg.sampleRatio, env);\n\n // Pino logger with trace/span correlation + redaction.\n // createPinoLogger is async (loads pino via dynamic import); awaiting it\n // is required — without await, `logger` is a Promise and calls like\n // logger.warn(...) crash with \"logger.warn is not a function\" during the\n // sdk-node fallback path.\n const { createPinoLogger } = await import('./pino-logger.js');\n const logger = await createPinoLogger({\n serviceName: cfg.serviceName,\n env,\n version: serviceVersion,\n });\n setActiveTelemetryLogger(logger);\n\n // Initialize core instrumentation (tracer, metrics registry, envelop plugins).\n // `setupInstrumentation` internally calls `initializeInstrumentation`.\n const instrumentation = setupInstrumentation(cfg.serviceName, {\n ...cfg.instrumentation,\n tracing: {\n serviceName: cfg.serviceName,\n ...(cfg.instrumentation?.tracing ?? {}),\n samplingRate: sampleRatio,\n },\n metrics: {\n serviceName: cfg.serviceName,\n ...(cfg.instrumentation?.metrics ?? {}),\n },\n });\n\n // Start the NodeSDK exporter pipeline if sdk-node is present (optional).\n let otelSdk: OtelSdkHandle | undefined;\n if (resolveOtelSdkEnabled()) {\n try {\n const { createOtelSdk } = await import('./sdk.js');\n otelSdk = await createOtelSdk({\n serviceName: cfg.serviceName,\n serviceVersion,\n boundary: cfg.boundary,\n module: cfg.module,\n env,\n otlpEndpoint,\n sampleRatio,\n });\n // Explicit success log includes metrics path status so an operator can\n // distinguish traces-only startup from full traces+metrics startup.\n logger.info('[telemetry] OpenTelemetry exporter pipeline started', {\n serviceName: cfg.serviceName,\n otlpEndpoint: otlpEndpoint ? '<configured>' : '<not set>',\n sampleRatio,\n metricsEnabled: otelSdk.metricsEnabled,\n });\n\n if (!otelSdk.metricsEnabled && otelSdk.metricsDropReason) {\n logger.warn('[telemetry] OpenTelemetry metrics reader disabled; continuing with traces only', {\n serviceName: cfg.serviceName,\n reason: otelSdk.metricsDropReason,\n });\n }\n } catch (err) {\n logger.warn('[telemetry] OpenTelemetry exporter pipeline failed to start; continuing with logs only', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n } else {\n logger.info('[telemetry] OTel SDK exporter disabled by env');\n }\n\n const shutdown = async (): Promise<void> => {\n try {\n if (otelSdk?.shutdown) await otelSdk.shutdown();\n } catch (err) {\n logger.warn('[telemetry] shutdown error (ignored)', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n };\n\n // Mirror defaultLogger so services that still use the singleton get trace-enriched output.\n defaultLogger.setLevel(logger.getLevel?.() ?? 'info');\n\n return {\n serviceName: cfg.serviceName,\n serviceVersion,\n env,\n logger: logger,\n instrumentation,\n shutdown,\n };\n}\n\n// Re-export what services typically import.\nexport { initializeInstrumentation, setupInstrumentation };\n"]}
1
+ {"version":3,"sources":["../../src/telemetry/health.ts","../../src/telemetry/metrics-endpoint.ts","../../src/telemetry/prisma-logging.ts","../../src/telemetry/index.ts"],"names":["createHealthRoutes","_deps","Proxy","get","_target","prop","undefined","loadDefaultRegistry","mod","collectDefaultMetrics","register","createMetricsRoutesImpl","app","opts","path","ctx","registry","ctxWithSet","set","status","headers","contentType","metrics","createMetricsRoutes","createPrismaLoggingExtension","logger","name","query","$allOperations","model","operation","args","start","Date","now","result","debug","duration_ms","redactSensitiveFields","err","error","Error","message","String","resolveEnv","explicit","fromEnv","process","env","resolveVersion","resolveEndpoint","proto","resolveSampling","Number","isFinite","Math","min","max","parsed","resolveOtelSdkEnabled","sdkDisabled","otelEnabled","bootstrapTelemetry","cfg","serviceVersion","otlpEndpoint","sampleRatio","createPinoLogger","serviceName","version","setActiveTelemetryLogger","instrumentation","setupInstrumentation","tracing","samplingRate","otelSdk","console","log","createOtelSdk","boundary","module","info","metricsEnabled","metricsDropReason","warn","reason","shutdown","defaultLogger","setLevel","getLevel"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * `/health`, `/health/live`, `/health/ready` Elysia routes with a 1s\n * result cache so readiness checks can't stampede Postgres.\n *\n * Dependencies (prisma, eventQueue, valkey) are optional — omit any client and\n * the readiness check simply skips it.\n */\n\ninterface PrismaLike {\n $queryRaw: (strings: TemplateStringsArray) => Promise<unknown>;\n}\ninterface EventQueueLike {\n isConnected?: () => boolean | Promise<boolean>;\n healthCheck?: () => Promise<{ ok: boolean }>;\n}\ninterface ValkeyLike {\n ping: () => Promise<unknown>;\n}\n\nexport interface HealthDeps {\n prisma?: PrismaLike;\n eventQueue?: EventQueueLike;\n valkey?: ValkeyLike;\n /** Service version reported on /health. */\n version?: string;\n /** Service name reported on /health. */\n serviceName?: string;\n}\n\ninterface CachedStatus {\n ready: boolean;\n checked: Record<string, { ok: boolean; error?: string }>;\n at: number;\n}\n\nconst CACHE_TTL_MS = 1000;\n\nasync function probeReady(deps: HealthDeps): Promise<CachedStatus> {\n const checked: Record<string, { ok: boolean; error?: string }> = {};\n\n if (deps.prisma) {\n try {\n await deps.prisma.$queryRaw`SELECT 1`;\n checked['postgres'] = { ok: true };\n } catch (err) {\n checked['postgres'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n if (deps.eventQueue) {\n try {\n const connected =\n typeof deps.eventQueue.isConnected === 'function'\n ? await Promise.resolve(deps.eventQueue.isConnected())\n : ((await deps.eventQueue.healthCheck?.())?.ok ?? true);\n checked['eventQueue'] = { ok: Boolean(connected) };\n } catch (err) {\n checked['eventQueue'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n if (deps.valkey) {\n try {\n await deps.valkey.ping();\n checked['valkey'] = { ok: true };\n } catch (err) {\n checked['valkey'] = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n const ready = Object.values(checked).every((c) => c.ok);\n return { ready, checked, at: Date.now() };\n}\n\nexport function createHealthRoutes(_deps: HealthDeps = {}): unknown {\n // Return an Elysia app lazily so be-sdk doesn't hard-require elysia.\n return new Proxy(\n {},\n {\n get(_target, prop): unknown {\n // Tell TypeScript consumers the returned object is an Elysia plugin;\n // the actual mount happens via `createHealthRoutesImpl`. Services\n // that prefer direct use can call `createHealthRoutesImpl(elysia, deps)`.\n if (prop === 'use' || prop === 'then') return undefined;\n return undefined;\n },\n }\n );\n}\n\n/**\n * Mount health routes on an existing Elysia app. Callers hold a reference\n * to Elysia themselves; be-sdk stays decoupled.\n */\nexport function createHealthRoutesImpl<\n App extends {\n get: (path: string, handler: (ctx: unknown) => unknown) => App;\n },\n>(app: App, deps: HealthDeps = {}): App {\n let cache: CachedStatus | null = null;\n\n const getStatus = async (): Promise<CachedStatus> => {\n if (cache && Date.now() - cache.at < CACHE_TTL_MS) return cache;\n cache = await probeReady(deps);\n return cache;\n };\n\n app.get('/health/live', () => ({\n status: 'ok',\n serviceName: deps.serviceName,\n version: deps.version,\n }));\n\n app.get('/health/ready', async (ctx: unknown): Promise<unknown> => {\n const status = await getStatus();\n const ctxWithSet = ctx as { set?: { status?: number } };\n if (!status.ready && ctxWithSet.set) ctxWithSet.set.status = 503;\n return {\n status: status.ready ? 'ok' : 'degraded',\n serviceName: deps.serviceName,\n version: deps.version,\n checks: status.checked,\n };\n });\n\n app.get('/health', async (ctx: unknown): Promise<unknown> => {\n const status = await getStatus();\n const ctxWithSet = ctx as { set?: { status?: number } };\n if (!status.ready && ctxWithSet.set) ctxWithSet.set.status = 503;\n return {\n status: status.ready ? 'ok' : 'degraded',\n serviceName: deps.serviceName,\n version: deps.version,\n checks: status.checked,\n uptime_s: Math.round(process.uptime()),\n };\n });\n\n return app;\n}\n","/**\n * Prometheus `/metrics` route mounter. Uses the shared `prom-client`\n * default registry so all instrumentation (GraphQL Envelop, Prisma,\n * runtime) shows up on a single endpoint.\n */\n\ninterface PromRegistryLike {\n metrics: () => Promise<string> | string;\n contentType?: string;\n}\n\nexport interface MetricsMountOptions {\n registry?: PromRegistryLike;\n path?: string;\n}\n\nexport async function loadDefaultRegistry(): Promise<PromRegistryLike | null> {\n try {\n const mod = (await import('prom-client')) as unknown as {\n register: PromRegistryLike;\n collectDefaultMetrics: (opts?: Record<string, unknown>) => void;\n };\n // Kick runtime metrics into the default registry if not already.\n try {\n mod.collectDefaultMetrics({ register: mod.register });\n } catch {\n // Already registered — ignore duplicate-metric errors.\n }\n return mod.register;\n } catch {\n return null;\n }\n}\n\nexport function createMetricsRoutesImpl<\n App extends {\n get: (path: string, handler: (ctx: unknown) => unknown) => App;\n },\n>(app: App, opts: MetricsMountOptions = {}): App {\n const path = opts.path ?? '/metrics';\n\n app.get(path, async (ctx: unknown): Promise<unknown> => {\n const registry = opts.registry ?? (await loadDefaultRegistry());\n const ctxWithSet = ctx as { set?: { status?: number; headers?: Record<string, string> } };\n if (!registry) {\n if (ctxWithSet.set) ctxWithSet.set.status = 503;\n return '# prom-client not installed\\n';\n }\n if (ctxWithSet.set) {\n ctxWithSet.set.status = 200;\n ctxWithSet.set.headers = {\n 'content-type': registry.contentType ?? 'text/plain; version=0.0.4; charset=utf-8',\n };\n }\n return registry.metrics();\n });\n\n return app;\n}\n\n/**\n * Legacy export name used by the service template. Composes the Elysia\n * plugin-style function that `new Elysia().use(...)` accepts.\n */\nexport function createMetricsRoutes(opts: MetricsMountOptions = {}): unknown {\n return (app: Parameters<typeof createMetricsRoutesImpl>[0]): unknown => createMetricsRoutesImpl(app, opts);\n}\n","/**\n * Prisma client extension that pipes query events through the SDK logger\n * with trace/span correlation fields auto-injected. The\n * `@prisma/instrumentation` peer provides the spans\n * themselves; this extension only adds structured log events on top.\n */\nimport type { Logger } from '../logger/index.js';\nimport { redactSensitiveFields } from '../logger/index.js';\n\ntype PrismaQueryArgs = {\n model?: string;\n operation: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n};\n\n/**\n * Returns a Prisma Client extension object compatible with the\n * `$extends()` API (Prisma v5+).\n *\n * ```ts\n * export const prisma = new PrismaClient().$extends(\n * createPrismaLoggingExtension(logger)\n * );\n * ```\n */\nexport function createPrismaLoggingExtension(logger: Logger): {\n name: string;\n query: {\n $allOperations: (args: PrismaQueryArgs) => Promise<unknown>;\n };\n} {\n return {\n name: 'burdenoff-pino-logging',\n query: {\n async $allOperations({ model, operation, args, query }: PrismaQueryArgs): Promise<unknown> {\n const start = Date.now();\n try {\n const result = await query(args);\n logger.debug('prisma.query', {\n model,\n operation,\n duration_ms: Date.now() - start,\n args: redactSensitiveFields(args),\n });\n return result;\n } catch (err) {\n logger.error('prisma.error', {\n model,\n operation,\n duration_ms: Date.now() - start,\n error: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n },\n },\n };\n}\n","/**\n * Unified telemetry bootstrap for Burdenoff services.\n *\n * Composes the existing `instrumentation/` + `observability/` + `logger/`\n * modules and adds:\n * - `bootstrapTelemetry({ serviceName, boundary, module, env })` — single\n * call that initializes OTel, wires Pino logger with trace fields,\n * exposes GraphQL Yoga plugins, registers process exit hooks.\n * - `createHealthRoutes({ prisma, nats, valkey, version })` — `/health`,\n * `/health/live`, `/health/ready` Elysia routes.\n * - `createMetricsRoutes(registry?)` — `/metrics` Prometheus exposition.\n * - `createPrismaLoggingExtension(logger)` — Prisma extension that pipes\n * query events through Pino with trace/span correlation ids.\n *\n * The module does not pull in `@opentelemetry/sdk-node` or `pino` as direct\n * deps — services install those as optional peers, and imports are lazy so\n * services that don't install them still load.\n */\n\nimport type { Logger as BaseLogger } from '../logger/index.js';\nimport { logger as defaultLogger } from '../logger/index.js';\nimport {\n initializeInstrumentation,\n setupInstrumentation,\n type SetupInstrumentationOptions,\n type InstrumentationSetupResult,\n} from '../instrumentation/index.js';\nimport { setActiveTelemetryLogger } from './logger-state.js';\nimport type { OtelSdkHandle } from './sdk.js';\n\nexport { createHealthRoutes } from './health.js';\nexport { createMetricsRoutes } from './metrics-endpoint.js';\nexport { createPrismaLoggingExtension } from './prisma-logging.js';\nexport { DEFAULT_REDACT_PATHS } from './pino-redaction.js';\nexport { createPinoLogger } from './pino-logger.js';\n\nexport type Boundary = 'wspace' | 'global' | 'gateway';\nexport type Env = 'alpha' | 'prod' | 'dev';\n\nexport interface TelemetryConfig {\n /** Full service name, e.g. \"wspace-auth-svc\". */\n serviceName: string;\n /** Semver of the service deployment; defaults to `process.env.npm_package_version`. */\n serviceVersion?: string;\n /** Monorepo boundary: `wspace`, `global`, or `gateway`. */\n boundary: Boundary;\n /** Module slug, e.g. `auth` (omit for gateways). */\n module?: string;\n /** Deployment environment; defaults to alpha for non-production NODE_ENV. */\n env?: Env;\n /**\n * OTLP endpoint for spans/metrics/logs. Defaults to\n * `$OTEL_EXPORTER_OTLP_ENDPOINT` or\n * `http://alloy.sre.svc.cluster.local:4318`.\n */\n otlpEndpoint?: string;\n /** Head-based sampling ratio. Default: alpha=1.0, prod=0.1. */\n sampleRatio?: number;\n /** Extra options forwarded to `setupInstrumentation`. */\n instrumentation?: SetupInstrumentationOptions;\n}\n\nexport interface TelemetryHandle {\n /** The configured service name (for use in health routes, etc.). */\n serviceName: string;\n /** The resolved service version. */\n serviceVersion: string;\n /** Environment. */\n env: Env;\n /** The Pino-backed logger. */\n logger: BaseLogger;\n /** Initialized instrumentation (tracer + metrics + plugins). */\n instrumentation: InstrumentationSetupResult;\n /** Cleanup hook; services call on SIGTERM. */\n shutdown: () => Promise<void>;\n}\n\nfunction resolveEnv(explicit?: Env): Env {\n if (explicit) return explicit;\n const fromEnv = process.env['DEPLOY_ENV'] ?? process.env['NODE_ENV'] ?? '';\n if (fromEnv === 'production' || fromEnv === 'prod') return 'prod';\n if (fromEnv === 'development' || fromEnv === 'dev') return 'dev';\n return 'alpha';\n}\n\nfunction resolveVersion(explicit?: string): string {\n if (explicit) return explicit;\n return process.env['npm_package_version'] ?? process.env['SERVICE_VERSION'] ?? '0.0.0';\n}\n\nfunction resolveEndpoint(explicit?: string): string {\n if (explicit) return explicit;\n const proto = 'http';\n // NOTE (ACA / current prod): the `alloy.sre.svc.cluster.local` fallback is a\n // LEGACY Kubernetes in-cluster DNS name and does NOT resolve on Azure\n // Container Apps. In ACA, service metrics reach Grafana/Azure Monitor via the\n // Prometheus `/metrics` *pull* path (the otel-collector scrapes each app) —\n // see `~/products/dev/platform/context/sre/HOW_TO_INTEGRATE_SRE_BACKEND.md`.\n // OTLP *push* (traces/metrics) only works where `OTEL_EXPORTER_OTLP_ENDPOINT`\n // is explicitly set to the env's otel-collector OTLP receiver. Kept as the\n // default for local/K8s remnants; override via env in ACA.\n return process.env['OTEL_EXPORTER_OTLP_ENDPOINT'] ?? `${proto}://alloy.sre.svc.cluster.local:4318`;\n}\n\nfunction resolveSampling(explicit: number | undefined, env: Env): number {\n if (typeof explicit === 'number' && Number.isFinite(explicit)) return Math.min(1, Math.max(0, explicit));\n const fromEnv = process.env['OTEL_TRACES_SAMPLER_ARG'];\n if (fromEnv) {\n const parsed = Number(fromEnv);\n if (Number.isFinite(parsed)) return Math.min(1, Math.max(0, parsed));\n }\n if (env === 'prod') return 0.1;\n return 1.0;\n}\n\nfunction resolveOtelSdkEnabled(): boolean {\n const sdkDisabled = process.env['OTEL_SDK_DISABLED'];\n if (sdkDisabled === 'true' || sdkDisabled === '1') return false;\n const otelEnabled = process.env['OTEL_ENABLED'];\n if (otelEnabled === 'false' || otelEnabled === '0') return false;\n return true;\n}\n\n/**\n * Bootstrap the full telemetry stack for a service.\n *\n * Services call this ONCE at startup **before** importing Prisma / GraphQL\n * Yoga / NATS so OTel can auto-instrument their dependencies.\n *\n * ```ts\n * // src/telemetry.ts\n * import { bootstrapTelemetry } from '@burdenoff/be-sdk/telemetry';\n * export const telemetry = await bootstrapTelemetry({\n * serviceName: 'wspace-auth-svc',\n * boundary: 'wspace',\n * module: 'auth',\n * });\n *\n * // src/index.ts — must be the FIRST import line.\n * import './telemetry.js';\n * ```\n */\nexport async function bootstrapTelemetry(cfg: TelemetryConfig): Promise<TelemetryHandle> {\n const env = resolveEnv(cfg.env);\n const serviceVersion = resolveVersion(cfg.serviceVersion);\n const otlpEndpoint = resolveEndpoint(cfg.otlpEndpoint);\n const sampleRatio = resolveSampling(cfg.sampleRatio, env);\n\n // Pino logger with trace/span correlation + redaction.\n // createPinoLogger is async (loads pino via dynamic import); awaiting it\n // is required — without await, `logger` is a Promise and calls like\n // logger.warn(...) crash with \"logger.warn is not a function\" during the\n // sdk-node fallback path.\n const { createPinoLogger } = await import('./pino-logger.js');\n const logger = await createPinoLogger({\n serviceName: cfg.serviceName,\n env,\n version: serviceVersion,\n });\n setActiveTelemetryLogger(logger);\n\n // Initialize core instrumentation (tracer, metrics registry, envelop plugins).\n // `setupInstrumentation` internally calls `initializeInstrumentation`.\n const instrumentation = setupInstrumentation(cfg.serviceName, {\n ...cfg.instrumentation,\n tracing: {\n serviceName: cfg.serviceName,\n ...(cfg.instrumentation?.tracing ?? {}),\n samplingRate: sampleRatio,\n },\n metrics: {\n serviceName: cfg.serviceName,\n ...(cfg.instrumentation?.metrics ?? {}),\n },\n });\n\n // Start the NodeSDK exporter pipeline if sdk-node is present (optional).\n let otelSdk: OtelSdkHandle | undefined;\n if (resolveOtelSdkEnabled()) {\n // Use console.log as a Pino-independent fallback for the critical OTel\n // bootstrap path. In ACA, Pino's default async sonic-boom destination is\n // not captured by ContainerAppConsoleLogs (see pino-logger.ts), so if the\n // sync-destination fix hasn't been deployed yet the *only* way operators\n // can see OTel startup/failure messages is through console.log.\n console.log('[telemetry] OTel SDK bootstrap starting...');\n try {\n const { createOtelSdk } = await import('./sdk.js');\n otelSdk = await createOtelSdk({\n serviceName: cfg.serviceName,\n serviceVersion,\n boundary: cfg.boundary,\n module: cfg.module,\n env,\n otlpEndpoint,\n sampleRatio,\n });\n // Explicit success log includes metrics path status so an operator can\n // distinguish traces-only startup from full traces+metrics startup.\n logger.info('[telemetry] OpenTelemetry exporter pipeline started', {\n serviceName: cfg.serviceName,\n otlpEndpoint: otlpEndpoint ? '<configured>' : '<not set>',\n sampleRatio,\n metricsEnabled: otelSdk.metricsEnabled,\n });\n console.log('[telemetry] OTel SDK exporter pipeline started');\n\n if (!otelSdk.metricsEnabled && otelSdk.metricsDropReason) {\n logger.warn('[telemetry] OpenTelemetry metrics reader disabled; continuing with traces only', {\n serviceName: cfg.serviceName,\n reason: otelSdk.metricsDropReason,\n });\n console.warn('[telemetry] OTel SDK metrics reader disabled:', otelSdk.metricsDropReason);\n }\n } catch (err) {\n logger.warn('[telemetry] OpenTelemetry exporter pipeline failed to start; continuing with logs only', {\n error: err instanceof Error ? err.message : String(err),\n });\n // console.error is always captured by ACA, ensuring the failure reason\n // is visible to operators even when Pino output is not.\n console.error('[telemetry] OTel SDK failed:', err);\n }\n } else {\n logger.info('[telemetry] OTel SDK exporter disabled by env');\n console.log('[telemetry] OTel SDK exporter disabled by env');\n }\n\n const shutdown = async (): Promise<void> => {\n try {\n if (otelSdk?.shutdown) await otelSdk.shutdown();\n } catch (err) {\n logger.warn('[telemetry] shutdown error (ignored)', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n };\n\n // Mirror defaultLogger so services that still use the singleton get trace-enriched output.\n defaultLogger.setLevel(logger.getLevel?.() ?? 'info');\n\n return {\n serviceName: cfg.serviceName,\n serviceVersion,\n env,\n logger: logger,\n instrumentation,\n shutdown,\n };\n}\n\n// Re-export what services typically import.\nexport { initializeInstrumentation, setupInstrumentation };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/be-sdk",
3
- "version": "2026.624.1",
3
+ "version": "2026.701.1",
4
4
  "description": "Backend SDK for Burdenoff products providing unified access to notifications, RBAC, activity tracking, usage monitoring, and more",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/telemetry/pino-redaction.ts","../src/telemetry/pino-logger.ts"],"names":["DEFAULT_REDACT_PATHS","Object","freeze","tryLoadPino","mod","candidate","default","PinoAdapter","BaseLogger","pino","level","console","debug","message","args","mergeArgs","info","warn","error","log","trace","out","arg","Error","stack","name","assign","undefined","createPinoLogger","cfg","pinoFactory","fallback","env","setContext","service","serviceName","version","redactPaths","base","redact","paths","censor","remove","timestamp","Date","toISOString","mixin","pickTraceFields","api","globalThis","__otelApi","anyApi","span","getActiveSpan","ctx","spanContext","trace_id","traceId","span_id","spanId","trace_flags","traceFlags","toString","padStart"],"mappings":"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","file":"chunk-E5USZ2MR.js","sourcesContent":["/**\n * Default Pino redact paths — covers the Burdenoff authorization +\n * gateway header + NATS/GraphQL payload surface area.\n *\n * Services can extend this list via their own Pino options.\n */\nexport const DEFAULT_REDACT_PATHS: readonly string[] = Object.freeze([\n 'password',\n '*.password',\n '*.*.password',\n 'token',\n 'authToken',\n 'workspaceToken',\n 'accessToken',\n 'refreshToken',\n 'clientSecret',\n 'apiKey',\n '*.apiKey',\n 'authorization',\n 'req.headers.authorization',\n 'req.headers[\"x-workspace-authorization\"]',\n 'req.headers.cookie',\n 'res.headers[\"set-cookie\"]',\n 'params.*.password',\n 'params.*.token',\n 'params.*.secret',\n]);\n","/**\n * Pino logger wrapper that emits structured JSON with trace/span correlation\n * fields. Falls back to the SDK's built-in Logger when `pino` isn't installed\n * so services without the peer dep still compile and run.\n */\nimport { Logger as BaseLogger } from '../logger/index.js';\nimport { DEFAULT_REDACT_PATHS } from './pino-redaction.js';\n\nexport interface PinoLoggerConfig {\n serviceName: string;\n env: 'alpha' | 'prod' | 'dev';\n version: string;\n /** Override Pino log level. Default: warn (prod), info (alpha/dev). */\n level?: 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';\n /** Extra redact paths appended to DEFAULT_REDACT_PATHS. */\n redactPaths?: string[];\n}\n\ninterface PinoLike {\n level: string;\n fatal: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n debug: (...args: unknown[]) => void;\n trace: (...args: unknown[]) => void;\n child: (bindings: Record<string, unknown>) => PinoLike;\n}\n\nasync function tryLoadPino(): Promise<((opts: unknown) => PinoLike) | null> {\n try {\n const mod = (await import('pino')) as unknown as { default?: unknown };\n const candidate = (mod.default ?? mod) as unknown;\n if (typeof candidate === 'function') {\n return candidate as (opts: unknown) => PinoLike;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nclass PinoAdapter extends BaseLogger {\n constructor(private readonly pino: PinoLike) {\n super({\n level: (pino.level as BaseLogger['getLevel'] extends () => infer L ? L : never) ?? 'info',\n console: false,\n });\n }\n\n public override debug(message: string, ...args: unknown[]): void {\n this.pino.debug(this.mergeArgs(args), message);\n }\n public override info(message: string, ...args: unknown[]): void {\n this.pino.info(this.mergeArgs(args), message);\n }\n public override warn(message: string, ...args: unknown[]): void {\n this.pino.warn(this.mergeArgs(args), message);\n }\n public override error(message: string, ...args: unknown[]): void {\n this.pino.error(this.mergeArgs(args), message);\n }\n public override log(message: string, ...args: unknown[]): void {\n this.pino.info(this.mergeArgs(args), message);\n }\n public override trace(message: string, ...args: unknown[]): void {\n this.pino.trace(this.mergeArgs(args), message);\n }\n\n private mergeArgs(args: unknown[]): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const arg of args) {\n if (arg instanceof Error) {\n out['err'] = { message: arg.message, stack: arg.stack, name: arg.name };\n } else if (arg && typeof arg === 'object') {\n Object.assign(out, arg as Record<string, unknown>);\n } else if (arg !== undefined && arg !== null) {\n out['data'] = arg;\n }\n }\n return out;\n }\n}\n\n/**\n * Build a logger instance. Returns a Pino-backed adapter when `pino` is\n * installed; otherwise falls back to the SDK's built-in JSON Logger.\n *\n * Services call this through `bootstrapTelemetry`, not directly.\n */\nexport async function createPinoLogger(cfg: PinoLoggerConfig): Promise<BaseLogger> {\n const pinoFactory = await tryLoadPino();\n if (!pinoFactory) {\n // No pino — fall back to the built-in Logger with console output.\n const fallback = new BaseLogger({ level: cfg.env === 'prod' ? 'warn' : 'info', console: true });\n fallback.setContext({\n service: cfg.serviceName,\n env: cfg.env,\n version: cfg.version,\n });\n return fallback;\n }\n\n const redactPaths = [...DEFAULT_REDACT_PATHS, ...(cfg.redactPaths ?? [])];\n const pino = pinoFactory({\n name: cfg.serviceName,\n level: cfg.level ?? (cfg.env === 'prod' ? 'warn' : 'info'),\n base: {\n service: { name: cfg.serviceName, version: cfg.version },\n env: cfg.env,\n },\n redact: {\n paths: redactPaths,\n censor: '[REDACTED]',\n remove: false,\n },\n timestamp: () => `,\"time\":\"${new Date().toISOString()}\"`,\n mixin: () => pickTraceFields(),\n });\n return new PinoAdapter(pino);\n}\n\nfunction pickTraceFields(): Record<string, string> {\n try {\n // Pull active span context via @opentelemetry/api if installed.\n // Use require-style dynamic access to keep this file dep-free.\n const api = (globalThis as unknown as { __otelApi?: unknown }).__otelApi;\n if (!api) return {};\n const anyApi = api as {\n trace: {\n getActiveSpan: () => { spanContext: () => { traceId: string; spanId: string; traceFlags: number } } | undefined;\n };\n };\n const span = anyApi.trace.getActiveSpan();\n if (!span) return {};\n const ctx = span.spanContext();\n return {\n trace_id: ctx.traceId,\n span_id: ctx.spanId,\n trace_flags: ctx.traceFlags.toString(16).padStart(2, '0'),\n };\n } catch {\n return {};\n }\n}\n"]}
@@ -1,5 +0,0 @@
1
- export { createPinoLogger } from './chunk-E5USZ2MR.js';
2
- import './chunk-CBZNP6RF.js';
3
- import './chunk-XE4OXN2W.js';
4
- //# sourceMappingURL=pino-logger-NVZXQPWO.js.map
5
- //# sourceMappingURL=pino-logger-NVZXQPWO.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/telemetry/sdk.ts"],"names":["isThenable","value","then","asyncDisposeMetricReader","metricReaderCandidate","shutdown","result","call","createOtelSdk","cfg","sdkNodeMod","sdkMod","resourcesMod","resources","semMod","sem","traceExpMod","traceExp","metricsExp","metricsExpMod","undefined","metricReader","metricsEnabled","metricsDropReason","OTLPMetricExporter","metricsSdkMod","metricsSdk","candidate","PeriodicExportingMetricReader","exporter","url","otlpEndpoint","replace","setProducer","setMetricProducer","sampler","traceBaseMod","traceBase","ParentBasedSampler","root","TraceIdRatioBasedSampler","Math","min","max","sampleRatio","autoInstrumentations","autoMod","auto","getNodeAutoInstrumentations","enabled","serviceNamespaceByBoundary","wspace","global","gateway","resourceAttributes","serviceName","serviceVersion","boundary","env","module","serviceInstanceId","process","clusterName","resource","resourceFromAttributes","traceExporter","OTLPTraceExporter","nodeSdk","NodeSDK","instrumentations","startResult","start","otelApiMod","globalThis","__otelApi"],"mappings":"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","file":"sdk-UWFH5PY7.js","sourcesContent":["/**\n * Thin wrapper that initializes `@opentelemetry/sdk-node` with the\n * OTLPTrace + OTLPMetric exporters and standard auto-instrumentations.\n *\n * All imports are dynamic so services that haven't installed sdk-node\n * still compile and run. The function resolves `undefined` when the SDK\n * isn't available, letting `bootstrapTelemetry` fall back gracefully.\n */\nimport type { Boundary, Env } from './index.js';\n\nexport interface OtelSdkConfig {\n serviceName: string;\n serviceVersion: string;\n boundary: Boundary;\n module?: string;\n env: Env;\n otlpEndpoint: string;\n sampleRatio: number;\n}\n\nexport interface OtelSdkHandle {\n shutdown: () => Promise<void>;\n metricsEnabled: boolean;\n metricsDropReason?: string;\n}\n\ntype Thenable = {\n then: (onfulfilled?: (value: void) => void, onrejected?: (reason: unknown) => void) => unknown;\n};\n\nconst isThenable = (value: unknown): value is Thenable => {\n return typeof value === 'object' && value !== null && typeof (value as { then?: unknown }).then === 'function';\n};\n\nconst asyncDisposeMetricReader = async (metricReaderCandidate: unknown): Promise<void> => {\n const shutdown = (metricReaderCandidate as { shutdown?: () => void | Promise<void> }).shutdown;\n if (typeof shutdown === 'function') {\n const result = shutdown.call(metricReaderCandidate) as unknown;\n if (isThenable(result)) await result;\n }\n};\n\nexport async function createOtelSdk(cfg: OtelSdkConfig): Promise<OtelSdkHandle> {\n // Use local string variables so TypeScript skips static module resolution for\n // optional peer dependencies that may not be installed.\n const sdkNodeMod = '@opentelemetry/sdk-node';\n const sdkMod = (await import(sdkNodeMod)) as unknown as {\n NodeSDK: new (init: Record<string, unknown>) => {\n start: () => void;\n shutdown: () => Promise<void>;\n };\n };\n\n const resourcesMod = '@opentelemetry/resources';\n const resources = (await import(resourcesMod)) as unknown as {\n resourceFromAttributes: (attrs: Record<string, string | number>) => unknown;\n };\n\n const semMod = '@opentelemetry/semantic-conventions';\n const sem = (await import(semMod)) as unknown as Record<string, string>;\n\n const traceExpMod = '@opentelemetry/exporter-trace-otlp-http';\n const traceExp = (await import(traceExpMod)) as unknown as {\n OTLPTraceExporter: new (init: Record<string, string>) => unknown;\n };\n\n let metricsExp: { OTLPMetricExporter?: new (init: Record<string, string>) => unknown } | undefined;\n try {\n const metricsExpMod = '@opentelemetry/exporter-metrics-otlp-http';\n metricsExp = await import(metricsExpMod);\n } catch {\n metricsExp = undefined;\n }\n\n let metricReader: unknown;\n let metricsEnabled = false;\n let metricsDropReason: string | undefined;\n if (metricsExp?.OTLPMetricExporter) {\n try {\n const metricsSdkMod = '@opentelemetry/sdk-metrics';\n const metricsSdk = (await import(metricsSdkMod)) as unknown as {\n PeriodicExportingMetricReader: new (init: Record<string, unknown>) => unknown;\n };\n const candidate = new metricsSdk.PeriodicExportingMetricReader({\n exporter: new metricsExp.OTLPMetricExporter({\n url: `${cfg.otlpEndpoint.replace(/\\/$/, '')}/v1/metrics`,\n }),\n });\n // Pre-flight API compatibility check. Some OTel package version\n // combinations construct `PeriodicExportingMetricReader` successfully\n // but lack `setMetricProducer` on the prototype chain (mixed\n // sdk-metrics versions, or runtime-specific class-inheritance\n // quirks — Bun has surfaced this in the past). Without the check,\n // `NodeSDK.start()` may register the global tracer provider BEFORE\n // it tries to call `setMetricProducer` and throws — leaving the\n // global tracer pointing at a half-initialized provider whose\n // span pipeline never drains. Skipping the metric reader when the\n // API isn't there avoids that whole failure mode in one pass.\n const setProducer = (candidate as { setMetricProducer?: unknown }).setMetricProducer;\n if (typeof setProducer === 'function') {\n metricReader = candidate;\n metricsEnabled = true;\n } else {\n metricsDropReason =\n 'setMetricProducer is not a function on PeriodicExportingMetricReader; skipping metrics path';\n await asyncDisposeMetricReader(candidate);\n metricReader = undefined;\n }\n } catch {\n if (metricsDropReason === undefined) {\n metricsDropReason = 'metric reader construction or compatibility check failed';\n }\n metricReader = undefined;\n }\n }\n\n let sampler: unknown;\n try {\n const traceBaseMod = '@opentelemetry/sdk-trace-base';\n const traceBase = (await import(traceBaseMod)) as unknown as {\n ParentBasedSampler: new (init: Record<string, unknown>) => unknown;\n TraceIdRatioBasedSampler: new (ratio: number) => unknown;\n };\n sampler = new traceBase.ParentBasedSampler({\n root: new traceBase.TraceIdRatioBasedSampler(Math.min(1, Math.max(0, cfg.sampleRatio))),\n });\n } catch {\n sampler = undefined;\n }\n\n // Some services have auto-instrumentations installed; optional.\n let autoInstrumentations: unknown[] | undefined;\n try {\n const autoMod = '@opentelemetry/auto-instrumentations-node';\n const auto = (await import(autoMod)) as unknown as {\n getNodeAutoInstrumentations: (cfg?: Record<string, unknown>) => unknown[];\n };\n autoInstrumentations = auto.getNodeAutoInstrumentations({\n '@opentelemetry/instrumentation-fs': { enabled: false },\n });\n } catch {\n autoInstrumentations = undefined;\n }\n\n const serviceNamespaceByBoundary: Record<Boundary, string> = {\n wspace: 'workspaces',\n global: 'tenant',\n gateway: 'gateways',\n };\n const resourceAttributes: Record<string, string> = {\n [sem['SEMRESATTRS_SERVICE_NAME'] ?? 'service.name']: cfg.serviceName,\n [sem['SEMRESATTRS_SERVICE_VERSION'] ?? 'service.version']: cfg.serviceVersion,\n [sem['SEMRESATTRS_SERVICE_NAMESPACE'] ?? 'service.namespace']: serviceNamespaceByBoundary[cfg.boundary],\n [sem['SEMRESATTRS_DEPLOYMENT_ENVIRONMENT'] ?? 'deployment.environment']: cfg.env,\n 'burdenoff.boundary': cfg.boundary,\n };\n if (cfg.module) resourceAttributes['burdenoff.module'] = cfg.module;\n const serviceInstanceId = process.env['POD_NAME'] ?? process.env['HOSTNAME'];\n if (serviceInstanceId) resourceAttributes['service.instance.id'] = serviceInstanceId;\n const clusterName = process.env['CLUSTER_NAME'];\n if (clusterName) {\n resourceAttributes['cluster'] = clusterName;\n resourceAttributes['k8s.cluster.name'] = clusterName;\n }\n\n const resource = resources.resourceFromAttributes(resourceAttributes);\n\n const traceExporter = new traceExp.OTLPTraceExporter({\n url: `${cfg.otlpEndpoint.replace(/\\/$/, '')}/v1/traces`,\n });\n\n // Single NodeSDK, single start. The pre-flight `setMetricProducer`\n // check above means we never pass an incompatible metric reader into\n // NodeSDK construction — so we no longer need the prior catch+rebuild\n // fallback dance, which had its own side-effect: the failed first\n // NodeSDK could leave the global tracer provider partially registered,\n // and the second NodeSDK's `setGlobalTracerProvider` becomes a no-op\n // — meaning spans flow into the FIRST (broken) provider and never\n // reach the exporter. Eliminating the fallback eliminates that hazard.\n const nodeSdk = new sdkMod.NodeSDK({\n resource,\n traceExporter,\n ...(metricReader ? { metricReader } : {}),\n ...(sampler ? { sampler } : {}),\n ...(autoInstrumentations ? { instrumentations: autoInstrumentations } : {}),\n });\n // NodeSDK.start() returns void in modern versions and Promise<void> in older\n // ones. Cast to a permissive thenable shape so awaiting works either way\n // without tripping `@typescript-eslint/await-thenable`.\n const startResult = nodeSdk.start() as unknown;\n if (isThenable(startResult)) {\n await startResult;\n }\n\n // Stash the @opentelemetry/api reference for pino-logger's mixin.\n try {\n const otelApiMod = '@opentelemetry/api';\n (globalThis as unknown as { __otelApi?: unknown }).__otelApi = await import(otelApiMod);\n } catch {\n // Non-fatal.\n }\n\n return {\n shutdown: async (): Promise<void> => nodeSdk.shutdown(),\n metricsEnabled,\n metricsDropReason,\n };\n}\n"]}