@celerity-sdk/telemetry 0.3.1 → 0.5.0
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.
- package/README.md +1 -1
- package/dist/index.cjs +91 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -9
- package/dist/index.d.ts +6 -9
- package/dist/index.js +74 -34
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -33,16 +33,16 @@ var index_exports = {};
|
|
|
33
33
|
__export(index_exports, {
|
|
34
34
|
CelerityLoggerImpl: () => CelerityLoggerImpl,
|
|
35
35
|
ContextAwareLogger: () => ContextAwareLogger,
|
|
36
|
-
LOGGER_TOKEN: () => LOGGER_TOKEN,
|
|
36
|
+
LOGGER_TOKEN: () => import_common.LOGGER_TOKEN,
|
|
37
37
|
NOOP_SPAN: () => NOOP_SPAN,
|
|
38
38
|
NoopTracer: () => NoopTracer,
|
|
39
39
|
OTelSpan: () => OTelSpan,
|
|
40
40
|
OTelTracer: () => OTelTracer,
|
|
41
|
-
TRACER_TOKEN: () => TRACER_TOKEN,
|
|
41
|
+
TRACER_TOKEN: () => import_common.TRACER_TOKEN,
|
|
42
42
|
TelemetryLayer: () => TelemetryLayer,
|
|
43
43
|
createLogger: () => createLogger,
|
|
44
44
|
extractTraceContext: () => extractTraceContext,
|
|
45
|
-
extractUserId: () =>
|
|
45
|
+
extractUserId: () => import_common3.extractUserId,
|
|
46
46
|
getLogger: () => getLogger,
|
|
47
47
|
getRequestLogger: () => getRequestLogger,
|
|
48
48
|
getTracer: () => getTracer,
|
|
@@ -52,8 +52,8 @@ module.exports = __toCommonJS(index_exports);
|
|
|
52
52
|
|
|
53
53
|
// src/telemetry-layer.ts
|
|
54
54
|
var import_debug3 = __toESM(require("debug"), 1);
|
|
55
|
-
var
|
|
56
|
-
var
|
|
55
|
+
var import_api2 = require("@opentelemetry/api");
|
|
56
|
+
var import_common2 = require("@celerity-sdk/common");
|
|
57
57
|
|
|
58
58
|
// src/env.ts
|
|
59
59
|
var VALID_LOG_LEVELS = /* @__PURE__ */ new Set([
|
|
@@ -278,18 +278,18 @@ var CelerityLoggerImpl = class _CelerityLoggerImpl {
|
|
|
278
278
|
this.pinoLogger.level = level;
|
|
279
279
|
}
|
|
280
280
|
};
|
|
281
|
-
function createLogger(config) {
|
|
281
|
+
async function createLogger(config) {
|
|
282
282
|
const streams = [];
|
|
283
283
|
const isLocal = !process.env.CELERITY_PLATFORM || process.env.CELERITY_PLATFORM === "local";
|
|
284
284
|
const useHumanFormat = config.logFormat === "human" || config.logFormat === "auto" && isLocal;
|
|
285
285
|
if (useHumanFormat) {
|
|
286
|
+
const pinoPrettyPkg = "pino-pretty";
|
|
287
|
+
const { default: pinoPretty } = await import(pinoPrettyPkg);
|
|
286
288
|
streams.push({
|
|
287
289
|
level: config.logLevel,
|
|
288
|
-
stream:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
destination: 1
|
|
292
|
-
}
|
|
290
|
+
stream: pinoPretty({
|
|
291
|
+
destination: 1,
|
|
292
|
+
translateTime: "SYS:standard"
|
|
293
293
|
})
|
|
294
294
|
});
|
|
295
295
|
} else {
|
|
@@ -367,21 +367,13 @@ var ContextAwareLogger = class {
|
|
|
367
367
|
}
|
|
368
368
|
};
|
|
369
369
|
|
|
370
|
-
// src/context.ts
|
|
371
|
-
var import_api = require("@opentelemetry/api");
|
|
372
|
-
function extractTraceContext(request) {
|
|
373
|
-
if (!request.traceContext) return import_api.ROOT_CONTEXT;
|
|
374
|
-
return import_api.propagation.extract(import_api.ROOT_CONTEXT, request.traceContext);
|
|
375
|
-
}
|
|
376
|
-
__name(extractTraceContext, "extractTraceContext");
|
|
377
|
-
|
|
378
370
|
// src/tracer.ts
|
|
379
|
-
var
|
|
371
|
+
var import_api = require("@opentelemetry/api");
|
|
380
372
|
var OTelTracer = class {
|
|
381
373
|
static {
|
|
382
374
|
__name(this, "OTelTracer");
|
|
383
375
|
}
|
|
384
|
-
tracer =
|
|
376
|
+
tracer = import_api.trace.getTracer("celerity");
|
|
385
377
|
startSpan(name, attributes) {
|
|
386
378
|
const span = this.tracer.startSpan(name, {
|
|
387
379
|
attributes
|
|
@@ -392,18 +384,18 @@ var OTelTracer = class {
|
|
|
392
384
|
const span = this.tracer.startSpan(name, {
|
|
393
385
|
attributes
|
|
394
386
|
});
|
|
395
|
-
const ctx =
|
|
396
|
-
return
|
|
387
|
+
const ctx = import_api.trace.setSpan(import_api.context.active(), span);
|
|
388
|
+
return import_api.context.with(ctx, async () => {
|
|
397
389
|
const wrapped = new OTelSpan(span);
|
|
398
390
|
try {
|
|
399
391
|
const result = await fn(wrapped);
|
|
400
392
|
span.setStatus({
|
|
401
|
-
code:
|
|
393
|
+
code: import_api.SpanStatusCode.OK
|
|
402
394
|
});
|
|
403
395
|
return result;
|
|
404
396
|
} catch (error) {
|
|
405
397
|
span.setStatus({
|
|
406
|
-
code:
|
|
398
|
+
code: import_api.SpanStatusCode.ERROR
|
|
407
399
|
});
|
|
408
400
|
if (error instanceof Error) span.recordException(error);
|
|
409
401
|
throw error;
|
|
@@ -430,13 +422,13 @@ var OTelSpan = class {
|
|
|
430
422
|
recordError(error) {
|
|
431
423
|
this.span.recordException(error);
|
|
432
424
|
this.span.setStatus({
|
|
433
|
-
code:
|
|
425
|
+
code: import_api.SpanStatusCode.ERROR,
|
|
434
426
|
message: error.message
|
|
435
427
|
});
|
|
436
428
|
}
|
|
437
429
|
setOk() {
|
|
438
430
|
this.span.setStatus({
|
|
439
|
-
code:
|
|
431
|
+
code: import_api.SpanStatusCode.OK
|
|
440
432
|
});
|
|
441
433
|
}
|
|
442
434
|
end() {
|
|
@@ -470,11 +462,18 @@ var NOOP_SPAN = {
|
|
|
470
462
|
};
|
|
471
463
|
|
|
472
464
|
// src/tokens.ts
|
|
473
|
-
var
|
|
474
|
-
var TRACER_TOKEN = "CelerityTracer";
|
|
465
|
+
var import_common = require("@celerity-sdk/common");
|
|
475
466
|
|
|
476
467
|
// src/telemetry-layer.ts
|
|
477
468
|
var debugLog = (0, import_debug3.default)("celerity:telemetry");
|
|
469
|
+
function isHttpContext(context) {
|
|
470
|
+
return "request" in context && typeof context.request === "object";
|
|
471
|
+
}
|
|
472
|
+
__name(isHttpContext, "isHttpContext");
|
|
473
|
+
function isConsumerContext(context) {
|
|
474
|
+
return "event" in context && typeof context.event === "object" && "messages" in (context.event ?? {});
|
|
475
|
+
}
|
|
476
|
+
__name(isConsumerContext, "isConsumerContext");
|
|
478
477
|
var LOG_LEVEL_CONFIG_KEYS = [
|
|
479
478
|
"CELERITY_LOG_LEVEL",
|
|
480
479
|
"celerityLogLevel",
|
|
@@ -509,35 +508,68 @@ var TelemetryLayer = class {
|
|
|
509
508
|
}
|
|
510
509
|
if (!this.rootLogger) {
|
|
511
510
|
debugLog("creating root logger (format=%s, level=%s)", this.config.logFormat, this.config.logLevel);
|
|
512
|
-
this.rootLogger = createLogger(this.config);
|
|
513
|
-
context.container.register(LOGGER_TOKEN, {
|
|
511
|
+
this.rootLogger = await createLogger(this.config);
|
|
512
|
+
context.container.register(import_common.LOGGER_TOKEN, {
|
|
514
513
|
useValue: new ContextAwareLogger(this.rootLogger)
|
|
515
514
|
});
|
|
516
|
-
context.container.register(TRACER_TOKEN, {
|
|
515
|
+
context.container.register(import_common.TRACER_TOKEN, {
|
|
517
516
|
useValue: this.config.tracingEnabled ? new OTelTracer() : new NoopTracer()
|
|
518
517
|
});
|
|
519
518
|
debugLog("registered logger and tracer (tracing=%s)", this.config.tracingEnabled);
|
|
520
519
|
}
|
|
521
520
|
await this.refreshLogLevelFromConfig(context.container);
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
521
|
+
const handlerName = context.metadata.get("handlerName");
|
|
522
|
+
let handlerLogger;
|
|
523
|
+
let traceCarrier;
|
|
524
|
+
if (isHttpContext(context)) {
|
|
525
|
+
const userId = (0, import_common2.extractUserId)(context.request.auth);
|
|
526
|
+
handlerLogger = this.rootLogger.child("request", {
|
|
527
|
+
...handlerName ? {
|
|
528
|
+
handlerName
|
|
529
|
+
} : {},
|
|
530
|
+
requestId: context.request.requestId,
|
|
531
|
+
method: context.request.method,
|
|
532
|
+
path: context.request.path,
|
|
533
|
+
matchedRoute: context.request.matchedRoute,
|
|
534
|
+
clientIp: context.request.clientIp,
|
|
535
|
+
userAgent: context.request.userAgent,
|
|
536
|
+
...userId ? {
|
|
537
|
+
userId
|
|
538
|
+
} : {}
|
|
539
|
+
});
|
|
540
|
+
traceCarrier = context.request.traceContext ?? void 0;
|
|
541
|
+
} else if (isConsumerContext(context)) {
|
|
542
|
+
const { messages } = context.event;
|
|
543
|
+
const first = messages[0];
|
|
544
|
+
const sourceMessageId = first?.messageAttributes?.sourceMessageId?.stringValue;
|
|
545
|
+
handlerLogger = this.rootLogger.child("consumer", {
|
|
546
|
+
...handlerName ? {
|
|
547
|
+
handlerName
|
|
548
|
+
} : {},
|
|
549
|
+
source: first?.source,
|
|
550
|
+
messageCount: messages.length,
|
|
551
|
+
...sourceMessageId ? {
|
|
552
|
+
sourceMessageId
|
|
553
|
+
} : {}
|
|
554
|
+
});
|
|
555
|
+
traceCarrier = context.event.traceContext ?? void 0;
|
|
556
|
+
} else {
|
|
557
|
+
handlerLogger = this.rootLogger.child("handler", {
|
|
558
|
+
...handlerName ? {
|
|
559
|
+
handlerName
|
|
560
|
+
} : {}
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
context.logger = handlerLogger;
|
|
535
564
|
const runWithLogger = /* @__PURE__ */ __name(() => requestStore.run({
|
|
536
|
-
logger:
|
|
565
|
+
logger: handlerLogger
|
|
537
566
|
}, () => next()), "runWithLogger");
|
|
538
567
|
if (!this.config.tracingEnabled) return runWithLogger();
|
|
539
|
-
|
|
540
|
-
|
|
568
|
+
if (traceCarrier) {
|
|
569
|
+
const parentContext = import_api2.propagation.extract(import_api2.ROOT_CONTEXT, traceCarrier);
|
|
570
|
+
return import_api2.context.with(parentContext, runWithLogger);
|
|
571
|
+
}
|
|
572
|
+
return runWithLogger();
|
|
541
573
|
}
|
|
542
574
|
async dispose() {
|
|
543
575
|
if (this.config.tracingEnabled) await shutdownTelemetry();
|
|
@@ -561,15 +593,23 @@ var TelemetryLayer = class {
|
|
|
561
593
|
};
|
|
562
594
|
|
|
563
595
|
// src/index.ts
|
|
564
|
-
var
|
|
596
|
+
var import_common3 = require("@celerity-sdk/common");
|
|
597
|
+
|
|
598
|
+
// src/context.ts
|
|
599
|
+
var import_api3 = require("@opentelemetry/api");
|
|
600
|
+
function extractTraceContext(request) {
|
|
601
|
+
if (!request.traceContext) return import_api3.ROOT_CONTEXT;
|
|
602
|
+
return import_api3.propagation.extract(import_api3.ROOT_CONTEXT, request.traceContext);
|
|
603
|
+
}
|
|
604
|
+
__name(extractTraceContext, "extractTraceContext");
|
|
565
605
|
|
|
566
606
|
// src/helpers.ts
|
|
567
607
|
async function getLogger(container) {
|
|
568
|
-
return container.resolve(LOGGER_TOKEN);
|
|
608
|
+
return container.resolve(import_common.LOGGER_TOKEN);
|
|
569
609
|
}
|
|
570
610
|
__name(getLogger, "getLogger");
|
|
571
611
|
async function getTracer(container) {
|
|
572
|
-
return container.resolve(TRACER_TOKEN);
|
|
612
|
+
return container.resolve(import_common.TRACER_TOKEN);
|
|
573
613
|
}
|
|
574
614
|
__name(getTracer, "getTracer");
|
|
575
615
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/telemetry-layer.ts","../src/env.ts","../src/init.ts","../src/instrumentations.ts","../src/logger.ts","../src/otel-transport.ts","../src/request-context.ts","../src/context.ts","../src/tracer.ts","../src/noop.ts","../src/tokens.ts","../src/helpers.ts"],"sourcesContent":["export { TelemetryLayer } from \"./telemetry-layer\";\nexport { extractUserId } from \"@celerity-sdk/common\";\nexport { CelerityLoggerImpl, createLogger } from \"./logger\";\nexport { ContextAwareLogger, getRequestLogger } from \"./request-context\";\nexport { OTelTracer, OTelSpan } from \"./tracer\";\nexport { NoopTracer, NOOP_SPAN } from \"./noop\";\nexport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\nexport { extractTraceContext } from \"./context\";\nexport { getLogger, getTracer } from \"./helpers\";\nexport { readTelemetryEnv } from \"./env\";\nexport type { TelemetryConfig } from \"./env\";\n","import createDebug from \"debug\";\nimport { context as otelContext } from \"@opentelemetry/api\";\nimport type {\n CelerityLayer,\n HandlerContext,\n HandlerResponse,\n LogLevel,\n ServiceContainer,\n} from \"@celerity-sdk/types\";\nimport { extractUserId } from \"@celerity-sdk/common\";\nimport { readTelemetryEnv, type TelemetryConfig } from \"./env\";\nimport { initTelemetry, shutdownTelemetry } from \"./init\";\nimport { CelerityLoggerImpl, createLogger } from \"./logger\";\nimport { ContextAwareLogger, requestStore } from \"./request-context\";\nimport { extractTraceContext } from \"./context\";\nimport { OTelTracer } from \"./tracer\";\nimport { NoopTracer } from \"./noop\";\nimport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\n\nconst debugLog = createDebug(\"celerity:telemetry\");\n\nconst LOG_LEVEL_CONFIG_KEYS = [\n \"CELERITY_LOG_LEVEL\",\n \"celerityLogLevel\",\n \"celerity_log_level\",\n \"CelerityLogLevel\",\n];\n\nconst VALID_LOG_LEVELS = new Set<string>([\"debug\", \"info\", \"warn\", \"error\"]);\n\ntype ConfigService = {\n get(key: string): Promise<string | undefined>;\n};\n\nexport class TelemetryLayer implements CelerityLayer {\n private config: TelemetryConfig;\n private rootLogger: CelerityLoggerImpl | null = null;\n private currentLevel: LogLevel;\n private initPromise: Promise<void> | null = null;\n\n constructor() {\n this.config = readTelemetryEnv();\n this.currentLevel = this.config.logLevel;\n\n if (this.config.tracingEnabled) {\n this.initPromise = initTelemetry();\n }\n }\n\n async handle(\n context: HandlerContext,\n next: () => Promise<HandlerResponse>,\n ): Promise<HandlerResponse> {\n if (this.initPromise) {\n await this.initPromise;\n this.initPromise = null;\n }\n\n if (!this.rootLogger) {\n debugLog(\n \"creating root logger (format=%s, level=%s)\",\n this.config.logFormat,\n this.config.logLevel,\n );\n this.rootLogger = createLogger(this.config);\n context.container.register(LOGGER_TOKEN, {\n useValue: new ContextAwareLogger(this.rootLogger),\n });\n context.container.register(TRACER_TOKEN, {\n useValue: this.config.tracingEnabled ? new OTelTracer() : new NoopTracer(),\n });\n debugLog(\"registered logger and tracer (tracing=%s)\", this.config.tracingEnabled);\n }\n\n await this.refreshLogLevelFromConfig(context.container);\n\n const userId = extractUserId(context.request.auth);\n const requestLogger = this.rootLogger.child(\"request\", {\n requestId: context.request.requestId,\n method: context.request.method,\n path: context.request.path,\n matchedRoute: context.request.matchedRoute,\n clientIp: context.request.clientIp,\n userAgent: context.request.userAgent,\n ...(userId ? { userId } : {}),\n });\n context.logger = requestLogger;\n\n const runWithLogger = () => requestStore.run({ logger: requestLogger }, () => next());\n\n if (!this.config.tracingEnabled) return runWithLogger();\n\n const parentContext = extractTraceContext(context.request);\n return otelContext.with(parentContext, runWithLogger);\n }\n\n async dispose(): Promise<void> {\n if (this.config.tracingEnabled) await shutdownTelemetry();\n }\n\n private async refreshLogLevelFromConfig(container: ServiceContainer): Promise<void> {\n if (!container.has(\"ConfigService\")) return;\n\n try {\n const configService = await container.resolve<ConfigService>(\"ConfigService\");\n for (const key of LOG_LEVEL_CONFIG_KEYS) {\n const value = await configService.get(key);\n if (value && VALID_LOG_LEVELS.has(value) && value !== this.currentLevel) {\n debugLog(\"log level changed %s → %s\", this.currentLevel, value);\n this.rootLogger?.setLevel(value as LogLevel);\n this.currentLevel = value as LogLevel;\n return;\n }\n }\n } catch {\n // Config resolution failed — keep current level\n }\n }\n}\n","import type { LogLevel } from \"@celerity-sdk/types\";\n\nexport type TelemetryConfig = {\n tracingEnabled: boolean;\n otlpEndpoint: string;\n serviceName: string;\n serviceVersion: string;\n logLevel: LogLevel;\n logFormat: \"json\" | \"human\" | \"auto\";\n logFilePath: string | null;\n};\n\nconst VALID_LOG_LEVELS = new Set<string>([\"debug\", \"info\", \"warn\", \"error\"]);\nconst VALID_LOG_FORMATS = new Set<string>([\"json\", \"human\", \"auto\"]);\n\nexport function readTelemetryEnv(): TelemetryConfig {\n const rawLevel = process.env.CELERITY_LOG_LEVEL;\n const rawFormat = process.env.CELERITY_LOG_FORMAT;\n\n return {\n tracingEnabled: process.env.CELERITY_TELEMETRY_ENABLED === \"true\",\n otlpEndpoint:\n process.env.OTEL_EXPORTER_OTLP_ENDPOINT ??\n process.env.CELERITY_TRACE_OTLP_COLLECTOR_ENDPOINT ??\n \"http://otelcollector:4317\",\n serviceName: process.env.OTEL_SERVICE_NAME ?? \"celerity-app\",\n serviceVersion: process.env.OTEL_SERVICE_VERSION ?? \"0.0.0\",\n logLevel: rawLevel && VALID_LOG_LEVELS.has(rawLevel) ? (rawLevel as LogLevel) : \"info\",\n logFormat:\n rawFormat && VALID_LOG_FORMATS.has(rawFormat)\n ? (rawFormat as \"json\" | \"human\" | \"auto\")\n : \"auto\",\n logFilePath: process.env.CELERITY_LOG_FILE_PATH ?? null,\n };\n}\n","import createDebug from \"debug\";\nimport { NodeSDK } from \"@opentelemetry/sdk-node\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from \"@opentelemetry/semantic-conventions\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-grpc\";\nimport { OTLPLogExporter } from \"@opentelemetry/exporter-logs-otlp-grpc\";\nimport { BatchLogRecordProcessor } from \"@opentelemetry/sdk-logs\";\nimport { CompositePropagator, W3CTraceContextPropagator } from \"@opentelemetry/core\";\nimport { AWSXRayPropagator } from \"@opentelemetry/propagator-aws-xray\";\nimport { AWSXRayIdGenerator } from \"@opentelemetry/id-generator-aws-xray\";\nimport { readTelemetryEnv } from \"./env\";\nimport { buildInstrumentations } from \"./instrumentations\";\n\nconst debug = createDebug(\"celerity:telemetry\");\n\nlet initialized = false;\nlet sdk: NodeSDK | null = null;\n\nexport function isInitialized(): boolean {\n return initialized;\n}\n\nexport async function initTelemetry(): Promise<void> {\n if (initialized) {\n debug(\"initTelemetry: already initialized, skipping\");\n return;\n }\n\n const config = readTelemetryEnv();\n if (!config.tracingEnabled) {\n debug(\"initTelemetry: tracing disabled, skipping\");\n return;\n }\n\n const platform = process.env.CELERITY_PLATFORM ?? \"local\";\n const isAws = platform === \"aws\";\n debug(\n \"initTelemetry: platform=%s endpoint=%s service=%s\",\n platform,\n config.otlpEndpoint,\n config.serviceName,\n );\n\n const instrumentations = await buildInstrumentations();\n\n sdk = new NodeSDK({\n resource: resourceFromAttributes({\n [ATTR_SERVICE_NAME]: config.serviceName,\n [ATTR_SERVICE_VERSION]: config.serviceVersion,\n }),\n traceExporter: new OTLPTraceExporter({ url: config.otlpEndpoint }),\n logRecordProcessors: [\n new BatchLogRecordProcessor(new OTLPLogExporter({ url: config.otlpEndpoint })),\n ],\n textMapPropagator: new CompositePropagator({\n propagators: [new W3CTraceContextPropagator(), new AWSXRayPropagator()],\n }),\n ...(isAws ? { idGenerator: new AWSXRayIdGenerator() } : {}),\n instrumentations,\n });\n\n sdk.start();\n initialized = true;\n debug(\"initTelemetry: SDK started\");\n}\n\nexport async function shutdownTelemetry(): Promise<void> {\n if (sdk) {\n debug(\"shutdownTelemetry: shutting down SDK\");\n await sdk.shutdown();\n sdk = null;\n initialized = false;\n }\n}\n","import createDebug from \"debug\";\nimport { HttpInstrumentation } from \"@opentelemetry/instrumentation-http\";\nimport { UndiciInstrumentation } from \"@opentelemetry/instrumentation-undici\";\nimport type { Instrumentation } from \"@opentelemetry/instrumentation\";\n\nconst debug = createDebug(\"celerity:telemetry\");\n\nexport async function buildInstrumentations(): Promise<Instrumentation[]> {\n // Core instrumentation: always active — covers all HTTP/HTTPS and fetch() calls\n const instrumentations: Instrumentation[] = [\n new HttpInstrumentation() as Instrumentation,\n new UndiciInstrumentation() as Instrumentation,\n ];\n\n // Dynamically load optional instrumentation packages.\n // Each targets a specific library and silently no-ops if the library isn't installed.\n const optionalPackages = [\n \"@opentelemetry/instrumentation-aws-sdk\",\n \"@opentelemetry/instrumentation-ioredis\",\n \"@opentelemetry/instrumentation-pg\",\n \"@opentelemetry/instrumentation-mysql2\",\n ];\n\n for (const name of optionalPackages) {\n try {\n const pkg = name;\n const mod = (await import(pkg)) as Record<string, unknown>;\n const InstrumentationClass = findInstrumentationExport(mod);\n if (InstrumentationClass) {\n debug(\"instrumentation: loaded %s\", name);\n instrumentations.push(new InstrumentationClass() as Instrumentation);\n }\n } catch (err) {\n const code = (err as { code?: string }).code;\n if (code !== \"ERR_MODULE_NOT_FOUND\" && code !== \"MODULE_NOT_FOUND\") {\n debug(\"instrumentation: failed to load %s: %O\", name, err);\n }\n }\n }\n\n return instrumentations;\n}\n\nfunction findInstrumentationExport(mod: Record<string, unknown>): (new () => unknown) | null {\n for (const value of Object.values(mod)) {\n if (typeof value === \"function\" && value.prototype && \"enable\" in value.prototype) {\n return value as new () => unknown;\n }\n }\n return null;\n}\n","import pino from \"pino\";\nimport type { CelerityLogger, LogLevel } from \"@celerity-sdk/types\";\nimport type { TelemetryConfig } from \"./env\";\nimport { createOTelStream } from \"./otel-transport\";\n\n/**\n * Thin pino wrapper implementing CelerityLogger.\n * Every method delegates directly to the underlying pino instance.\n */\nexport class CelerityLoggerImpl implements CelerityLogger {\n constructor(private pinoLogger: pino.Logger) {}\n\n debug(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"debug\", message, attributes);\n }\n\n info(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"info\", message, attributes);\n }\n\n warn(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"warn\", message, attributes);\n }\n\n error(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"error\", message, attributes);\n }\n\n private log(level: LogLevel, message: string, attributes?: Record<string, unknown>): void {\n const fn = this.pinoLogger[level].bind(this.pinoLogger);\n if (attributes) fn(attributes, message);\n else fn(message);\n }\n\n child(name: string, attributes?: Record<string, unknown>): CelerityLogger {\n return new CelerityLoggerImpl(this.pinoLogger.child({ name, ...attributes }));\n }\n\n withContext(attributes: Record<string, unknown>): CelerityLogger {\n return new CelerityLoggerImpl(this.pinoLogger.child(attributes));\n }\n\n /** Update the log level at runtime. Internal — used by TelemetryLayer for dynamic config. */\n setLevel(level: LogLevel): void {\n this.pinoLogger.level = level;\n }\n}\n\nexport function createLogger(config: TelemetryConfig): CelerityLoggerImpl {\n const streams: pino.StreamEntry[] = [];\n\n const isLocal = !process.env.CELERITY_PLATFORM || process.env.CELERITY_PLATFORM === \"local\";\n const useHumanFormat = config.logFormat === \"human\" || (config.logFormat === \"auto\" && isLocal);\n\n if (useHumanFormat) {\n // pino-pretty via worker thread — fine for local dev only\n streams.push({\n level: config.logLevel,\n stream: pino.transport({ target: \"pino-pretty\", options: { destination: 1 } }),\n });\n } else {\n // Raw JSON to stdout — synchronous, Lambda-safe\n streams.push({ level: config.logLevel, stream: pino.destination(1) });\n }\n\n // File stream — if configured (synchronous SonicBoom destination)\n if (config.logFilePath) {\n streams.push({\n level: config.logLevel,\n stream: pino.destination(config.logFilePath),\n });\n }\n\n // OTel log stream — main-thread writable (NOT worker-thread transport).\n // Runs in main thread so it can read active OTel context (traceId/spanId)\n // and is safe for Lambda (no worker thread flush issues).\n if (config.tracingEnabled) {\n streams.push({\n level: config.logLevel,\n stream: createOTelStream(),\n });\n }\n\n const redactPaths = resolveRedactPaths();\n\n const logger = pino(\n {\n level: config.logLevel,\n redact: redactPaths.length > 0 ? { paths: redactPaths, censor: \"[REDACTED]\" } : undefined,\n timestamp: pino.stdTimeFunctions.isoTime,\n },\n pino.multistream(streams),\n );\n\n return new CelerityLoggerImpl(logger);\n}\n\nfunction resolveRedactPaths(): string[] {\n const keys = process.env.CELERITY_LOG_REDACT_KEYS;\n if (!keys) return [];\n return keys.split(\",\").map((k) => k.trim());\n}\n","import { Writable } from \"node:stream\";\nimport { logs, SeverityNumber } from \"@opentelemetry/api-logs\";\n\nconst LEVEL_MAP: Record<number, SeverityNumber> = {\n 10: SeverityNumber.TRACE,\n 20: SeverityNumber.DEBUG,\n 30: SeverityNumber.INFO,\n 40: SeverityNumber.WARN,\n 50: SeverityNumber.ERROR,\n 60: SeverityNumber.FATAL,\n};\n\n/**\n * Creates a main-thread writable stream that bridges pino log records\n * to the OTel Logs API.\n *\n * Runs in the main thread (NOT a pino worker-thread transport) so it can:\n * 1. Read traceId/spanId from the active OTel context (trace correlation)\n * 2. Flush reliably in Lambda (no worker thread lifecycle issues)\n */\nexport function createOTelStream(): Writable {\n const otelLogger = logs.getLogger(\"celerity\");\n\n return new Writable({\n write(chunk: Buffer | string, _encoding, callback) {\n try {\n const obj = JSON.parse(typeof chunk === \"string\" ? chunk : chunk.toString()) as Record<\n string,\n unknown\n >;\n const { level, msg, name, ...rest } = obj;\n delete rest.time;\n const attributes: Record<string, string | number | boolean> = {};\n if (typeof name === \"string\") attributes[\"logger.name\"] = name;\n for (const [key, val] of Object.entries(rest)) {\n if (typeof val === \"string\" || typeof val === \"number\" || typeof val === \"boolean\") {\n attributes[key] = val;\n }\n }\n otelLogger.emit({\n severityNumber: LEVEL_MAP[level as number] ?? SeverityNumber.INFO,\n body: msg as string,\n attributes,\n });\n } catch {\n // Malformed JSON — skip\n }\n callback();\n },\n });\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { CelerityLogger } from \"@celerity-sdk/types\";\n\ntype RequestStore = {\n logger: CelerityLogger;\n};\n\nexport const requestStore = new AsyncLocalStorage<RequestStore>();\n\n/**\n * Get the request-scoped logger from the current async context.\n *\n * Works anywhere in the async call chain during request handling —\n * handlers, services, repositories, API clients.\n *\n * Returns `undefined` outside a request context (e.g., startup code, background tasks).\n */\nexport function getRequestLogger(): CelerityLogger | undefined {\n return requestStore.getStore()?.logger;\n}\n\n/**\n * Context-aware logger proxy registered under LOGGER_TOKEN.\n *\n * Delegates to the request-scoped logger (via AsyncLocalStorage) when inside\n * a request context, falls back to the root logger otherwise.\n *\n * This means `@Inject(LOGGER_TOKEN)` automatically resolves to the most\n * appropriate logger for the current context — no manual wiring needed.\n */\nexport class ContextAwareLogger implements CelerityLogger {\n constructor(private rootLogger: CelerityLogger) {}\n\n private get current(): CelerityLogger {\n return getRequestLogger() ?? this.rootLogger;\n }\n\n debug(message: string, attributes?: Record<string, unknown>): void {\n this.current.debug(message, attributes);\n }\n\n info(message: string, attributes?: Record<string, unknown>): void {\n this.current.info(message, attributes);\n }\n\n warn(message: string, attributes?: Record<string, unknown>): void {\n this.current.warn(message, attributes);\n }\n\n error(message: string, attributes?: Record<string, unknown>): void {\n this.current.error(message, attributes);\n }\n\n child(name: string, attributes?: Record<string, unknown>): CelerityLogger {\n return this.current.child(name, attributes);\n }\n\n withContext(attributes: Record<string, unknown>): CelerityLogger {\n return this.current.withContext(attributes);\n }\n}\n","import { propagation, ROOT_CONTEXT, type Context } from \"@opentelemetry/api\";\nimport type { HttpRequest } from \"@celerity-sdk/types\";\n\nexport function extractTraceContext(request: HttpRequest): Context {\n if (!request.traceContext) return ROOT_CONTEXT;\n\n // The traceContext map is used directly as a carrier.\n // The composite propagator (W3C + X-Ray) extracts the appropriate context.\n return propagation.extract(ROOT_CONTEXT, request.traceContext);\n}\n","import {\n trace,\n context as otelContext,\n SpanStatusCode,\n type Span,\n type Attributes,\n} from \"@opentelemetry/api\";\nimport type { CelerityTracer, CeleritySpan } from \"@celerity-sdk/types\";\n\nexport class OTelTracer implements CelerityTracer {\n private tracer = trace.getTracer(\"celerity\");\n\n startSpan(name: string, attributes?: Record<string, unknown>): CeleritySpan {\n const span = this.tracer.startSpan(name, {\n attributes: attributes as Attributes,\n });\n return new OTelSpan(span);\n }\n\n async withSpan<T>(\n name: string,\n fn: (span: CeleritySpan) => T | Promise<T>,\n attributes?: Record<string, unknown>,\n ): Promise<T> {\n const span = this.tracer.startSpan(name, {\n attributes: attributes as Attributes,\n });\n const ctx = trace.setSpan(otelContext.active(), span);\n\n return otelContext.with(ctx, async () => {\n const wrapped = new OTelSpan(span);\n try {\n const result = await fn(wrapped);\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) span.recordException(error);\n throw error;\n } finally {\n span.end();\n }\n });\n }\n}\n\nexport class OTelSpan implements CeleritySpan {\n constructor(private span: Span) {}\n\n setAttribute(key: string, value: string | number | boolean): void {\n this.span.setAttribute(key, value);\n }\n\n setAttributes(attributes: Record<string, string | number | boolean>): void {\n this.span.setAttributes(attributes);\n }\n\n recordError(error: Error): void {\n this.span.recordException(error);\n this.span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n }\n\n setOk(): void {\n this.span.setStatus({ code: SpanStatusCode.OK });\n }\n\n end(): void {\n this.span.end();\n }\n}\n","import type { CelerityTracer, CeleritySpan } from \"@celerity-sdk/types\";\n\nexport class NoopTracer implements CelerityTracer {\n startSpan(): CeleritySpan {\n return NOOP_SPAN;\n }\n\n async withSpan<T>(_name: string, fn: (span: CeleritySpan) => T | Promise<T>): Promise<T> {\n return fn(NOOP_SPAN);\n }\n}\n\nexport const NOOP_SPAN: CeleritySpan = {\n setAttribute() {},\n setAttributes() {},\n recordError() {},\n setOk() {},\n end() {},\n};\n","export const LOGGER_TOKEN = \"CelerityLogger\";\nexport const TRACER_TOKEN = \"CelerityTracer\";\n","import type { CelerityLogger, CelerityTracer, ServiceContainer } from \"@celerity-sdk/types\";\nimport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\n\nexport async function getLogger(container: ServiceContainer): Promise<CelerityLogger> {\n return container.resolve<CelerityLogger>(LOGGER_TOKEN);\n}\n\nexport async function getTracer(container: ServiceContainer): Promise<CelerityTracer> {\n return container.resolve<CelerityTracer>(TRACER_TOKEN);\n}\n"],"mappings":"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","names":["import_debug","import_api","VALID_LOG_LEVELS","Set","VALID_LOG_FORMATS","readTelemetryEnv","rawLevel","process","env","CELERITY_LOG_LEVEL","rawFormat","CELERITY_LOG_FORMAT","tracingEnabled","CELERITY_TELEMETRY_ENABLED","otlpEndpoint","OTEL_EXPORTER_OTLP_ENDPOINT","CELERITY_TRACE_OTLP_COLLECTOR_ENDPOINT","serviceName","OTEL_SERVICE_NAME","serviceVersion","OTEL_SERVICE_VERSION","logLevel","has","logFormat","logFilePath","CELERITY_LOG_FILE_PATH","import_debug","debug","createDebug","buildInstrumentations","instrumentations","HttpInstrumentation","UndiciInstrumentation","optionalPackages","name","pkg","mod","InstrumentationClass","findInstrumentationExport","push","err","code","value","Object","values","prototype","debug","createDebug","initialized","sdk","initTelemetry","initialized","debug","config","readTelemetryEnv","tracingEnabled","platform","process","env","CELERITY_PLATFORM","isAws","otlpEndpoint","serviceName","instrumentations","buildInstrumentations","sdk","NodeSDK","resource","resourceFromAttributes","ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","serviceVersion","traceExporter","OTLPTraceExporter","url","logRecordProcessors","BatchLogRecordProcessor","OTLPLogExporter","textMapPropagator","CompositePropagator","propagators","W3CTraceContextPropagator","AWSXRayPropagator","idGenerator","AWSXRayIdGenerator","start","shutdownTelemetry","shutdown","LEVEL_MAP","SeverityNumber","TRACE","DEBUG","INFO","WARN","ERROR","FATAL","createOTelStream","otelLogger","logs","getLogger","Writable","write","chunk","_encoding","callback","obj","JSON","parse","toString","level","msg","name","rest","time","attributes","key","val","Object","entries","emit","severityNumber","body","CelerityLoggerImpl","pinoLogger","debug","message","attributes","log","info","warn","error","level","fn","bind","child","name","withContext","setLevel","createLogger","config","streams","isLocal","process","env","CELERITY_PLATFORM","useHumanFormat","logFormat","push","logLevel","stream","pino","transport","target","options","destination","logFilePath","tracingEnabled","createOTelStream","redactPaths","resolveRedactPaths","logger","redact","length","paths","censor","undefined","timestamp","stdTimeFunctions","isoTime","multistream","keys","CELERITY_LOG_REDACT_KEYS","split","map","k","trim","requestStore","AsyncLocalStorage","getRequestLogger","getStore","logger","ContextAwareLogger","rootLogger","current","debug","message","attributes","info","warn","error","child","name","withContext","extractTraceContext","request","traceContext","ROOT_CONTEXT","propagation","extract","import_api","OTelTracer","tracer","trace","getTracer","startSpan","name","attributes","span","OTelSpan","withSpan","fn","ctx","setSpan","otelContext","active","with","wrapped","result","setStatus","code","SpanStatusCode","OK","error","ERROR","Error","recordException","end","setAttribute","key","value","setAttributes","recordError","message","setOk","NoopTracer","startSpan","NOOP_SPAN","withSpan","_name","fn","setAttribute","setAttributes","recordError","setOk","end","LOGGER_TOKEN","TRACER_TOKEN","debugLog","createDebug","LOG_LEVEL_CONFIG_KEYS","VALID_LOG_LEVELS","Set","TelemetryLayer","config","rootLogger","currentLevel","initPromise","readTelemetryEnv","logLevel","tracingEnabled","initTelemetry","handle","context","next","logFormat","createLogger","container","register","LOGGER_TOKEN","useValue","ContextAwareLogger","TRACER_TOKEN","OTelTracer","NoopTracer","refreshLogLevelFromConfig","userId","extractUserId","request","auth","requestLogger","child","requestId","method","path","matchedRoute","clientIp","userAgent","logger","runWithLogger","requestStore","run","parentContext","extractTraceContext","otelContext","with","dispose","shutdownTelemetry","has","configService","resolve","key","value","get","setLevel","import_common","getLogger","container","resolve","LOGGER_TOKEN","getTracer","TRACER_TOKEN"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/telemetry-layer.ts","../src/env.ts","../src/init.ts","../src/instrumentations.ts","../src/logger.ts","../src/otel-transport.ts","../src/request-context.ts","../src/tracer.ts","../src/noop.ts","../src/tokens.ts","../src/context.ts","../src/helpers.ts"],"sourcesContent":["export { TelemetryLayer } from \"./telemetry-layer\";\nexport { extractUserId } from \"@celerity-sdk/common\";\nexport { CelerityLoggerImpl, createLogger } from \"./logger\";\nexport { ContextAwareLogger, getRequestLogger } from \"./request-context\";\nexport { OTelTracer, OTelSpan } from \"./tracer\";\nexport { NoopTracer, NOOP_SPAN } from \"./noop\";\nexport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\nexport { extractTraceContext } from \"./context\";\nexport { getLogger, getTracer } from \"./helpers\";\nexport { readTelemetryEnv } from \"./env\";\nexport type { TelemetryConfig } from \"./env\";\n","import createDebug from \"debug\";\nimport { context as otelContext, propagation, ROOT_CONTEXT } from \"@opentelemetry/api\";\nimport type {\n CelerityLayer,\n BaseHandlerContext,\n HttpHandlerContext,\n ConsumerHandlerContext,\n LogLevel,\n ServiceContainer,\n} from \"@celerity-sdk/types\";\nimport { extractUserId } from \"@celerity-sdk/common\";\nimport { readTelemetryEnv, type TelemetryConfig } from \"./env\";\nimport { initTelemetry, shutdownTelemetry } from \"./init\";\nimport { CelerityLoggerImpl, createLogger } from \"./logger\";\nimport { ContextAwareLogger, requestStore } from \"./request-context\";\nimport { OTelTracer } from \"./tracer\";\nimport { NoopTracer } from \"./noop\";\nimport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\n\nconst debugLog = createDebug(\"celerity:telemetry\");\n\nfunction isHttpContext(context: BaseHandlerContext): context is HttpHandlerContext {\n return \"request\" in context && typeof (context as HttpHandlerContext).request === \"object\";\n}\n\nfunction isConsumerContext(context: BaseHandlerContext): context is ConsumerHandlerContext {\n return (\n \"event\" in context &&\n typeof (context as ConsumerHandlerContext).event === \"object\" &&\n \"messages\" in ((context as ConsumerHandlerContext).event ?? {})\n );\n}\n\nconst LOG_LEVEL_CONFIG_KEYS = [\n \"CELERITY_LOG_LEVEL\",\n \"celerityLogLevel\",\n \"celerity_log_level\",\n \"CelerityLogLevel\",\n];\n\nconst VALID_LOG_LEVELS = new Set<string>([\"debug\", \"info\", \"warn\", \"error\"]);\n\ntype ConfigService = {\n get(key: string): Promise<string | undefined>;\n};\n\nexport class TelemetryLayer implements CelerityLayer<BaseHandlerContext> {\n private config: TelemetryConfig;\n private rootLogger: CelerityLoggerImpl | null = null;\n private currentLevel: LogLevel;\n private initPromise: Promise<void> | null = null;\n\n constructor() {\n this.config = readTelemetryEnv();\n this.currentLevel = this.config.logLevel;\n\n if (this.config.tracingEnabled) {\n this.initPromise = initTelemetry();\n }\n }\n\n async handle(context: BaseHandlerContext, next: () => Promise<unknown>): Promise<unknown> {\n if (this.initPromise) {\n await this.initPromise;\n this.initPromise = null;\n }\n\n if (!this.rootLogger) {\n debugLog(\n \"creating root logger (format=%s, level=%s)\",\n this.config.logFormat,\n this.config.logLevel,\n );\n this.rootLogger = await createLogger(this.config);\n context.container.register(LOGGER_TOKEN, {\n useValue: new ContextAwareLogger(this.rootLogger),\n });\n context.container.register(TRACER_TOKEN, {\n useValue: this.config.tracingEnabled ? new OTelTracer() : new NoopTracer(),\n });\n debugLog(\"registered logger and tracer (tracing=%s)\", this.config.tracingEnabled);\n }\n\n await this.refreshLogLevelFromConfig(context.container);\n\n const handlerName = context.metadata.get(\"handlerName\") as string | undefined;\n let handlerLogger;\n let traceCarrier: Record<string, string> | undefined;\n\n if (isHttpContext(context)) {\n const userId = extractUserId(context.request.auth);\n handlerLogger = this.rootLogger.child(\"request\", {\n ...(handlerName ? { handlerName } : {}),\n requestId: context.request.requestId,\n method: context.request.method,\n path: context.request.path,\n matchedRoute: context.request.matchedRoute,\n clientIp: context.request.clientIp,\n userAgent: context.request.userAgent,\n ...(userId ? { userId } : {}),\n });\n traceCarrier = context.request.traceContext ?? undefined;\n } else if (isConsumerContext(context)) {\n const { messages } = context.event;\n const first = messages[0];\n const sourceMessageId = first?.messageAttributes?.sourceMessageId?.stringValue;\n handlerLogger = this.rootLogger.child(\"consumer\", {\n ...(handlerName ? { handlerName } : {}),\n source: first?.source,\n messageCount: messages.length,\n ...(sourceMessageId ? { sourceMessageId } : {}),\n });\n traceCarrier = context.event.traceContext ?? undefined;\n } else {\n handlerLogger = this.rootLogger.child(\"handler\", {\n ...(handlerName ? { handlerName } : {}),\n });\n }\n\n context.logger = handlerLogger;\n\n const runWithLogger = () => requestStore.run({ logger: handlerLogger }, () => next());\n\n if (!this.config.tracingEnabled) return runWithLogger();\n\n if (traceCarrier) {\n const parentContext = propagation.extract(ROOT_CONTEXT, traceCarrier);\n return otelContext.with(parentContext, runWithLogger);\n }\n\n return runWithLogger();\n }\n\n async dispose(): Promise<void> {\n if (this.config.tracingEnabled) await shutdownTelemetry();\n }\n\n private async refreshLogLevelFromConfig(container: ServiceContainer): Promise<void> {\n if (!container.has(\"ConfigService\")) return;\n\n try {\n const configService = await container.resolve<ConfigService>(\"ConfigService\");\n for (const key of LOG_LEVEL_CONFIG_KEYS) {\n const value = await configService.get(key);\n if (value && VALID_LOG_LEVELS.has(value) && value !== this.currentLevel) {\n debugLog(\"log level changed %s → %s\", this.currentLevel, value);\n this.rootLogger?.setLevel(value as LogLevel);\n this.currentLevel = value as LogLevel;\n return;\n }\n }\n } catch {\n // Config resolution failed — keep current level\n }\n }\n}\n","import type { LogLevel } from \"@celerity-sdk/types\";\n\nexport type TelemetryConfig = {\n tracingEnabled: boolean;\n otlpEndpoint: string;\n serviceName: string;\n serviceVersion: string;\n logLevel: LogLevel;\n logFormat: \"json\" | \"human\" | \"auto\";\n logFilePath: string | null;\n};\n\nconst VALID_LOG_LEVELS = new Set<string>([\"debug\", \"info\", \"warn\", \"error\"]);\nconst VALID_LOG_FORMATS = new Set<string>([\"json\", \"human\", \"auto\"]);\n\nexport function readTelemetryEnv(): TelemetryConfig {\n const rawLevel = process.env.CELERITY_LOG_LEVEL;\n const rawFormat = process.env.CELERITY_LOG_FORMAT;\n\n return {\n tracingEnabled: process.env.CELERITY_TELEMETRY_ENABLED === \"true\",\n otlpEndpoint:\n process.env.OTEL_EXPORTER_OTLP_ENDPOINT ??\n process.env.CELERITY_TRACE_OTLP_COLLECTOR_ENDPOINT ??\n \"http://otelcollector:4317\",\n serviceName: process.env.OTEL_SERVICE_NAME ?? \"celerity-app\",\n serviceVersion: process.env.OTEL_SERVICE_VERSION ?? \"0.0.0\",\n logLevel: rawLevel && VALID_LOG_LEVELS.has(rawLevel) ? (rawLevel as LogLevel) : \"info\",\n logFormat:\n rawFormat && VALID_LOG_FORMATS.has(rawFormat)\n ? (rawFormat as \"json\" | \"human\" | \"auto\")\n : \"auto\",\n logFilePath: process.env.CELERITY_LOG_FILE_PATH ?? null,\n };\n}\n","import createDebug from \"debug\";\nimport { NodeSDK } from \"@opentelemetry/sdk-node\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from \"@opentelemetry/semantic-conventions\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-grpc\";\nimport { OTLPLogExporter } from \"@opentelemetry/exporter-logs-otlp-grpc\";\nimport { BatchLogRecordProcessor } from \"@opentelemetry/sdk-logs\";\nimport { CompositePropagator, W3CTraceContextPropagator } from \"@opentelemetry/core\";\nimport { AWSXRayPropagator } from \"@opentelemetry/propagator-aws-xray\";\nimport { AWSXRayIdGenerator } from \"@opentelemetry/id-generator-aws-xray\";\nimport { readTelemetryEnv } from \"./env\";\nimport { buildInstrumentations } from \"./instrumentations\";\n\nconst debug = createDebug(\"celerity:telemetry\");\n\nlet initialized = false;\nlet sdk: NodeSDK | null = null;\n\nexport function isInitialized(): boolean {\n return initialized;\n}\n\nexport async function initTelemetry(): Promise<void> {\n if (initialized) {\n debug(\"initTelemetry: already initialized, skipping\");\n return;\n }\n\n const config = readTelemetryEnv();\n if (!config.tracingEnabled) {\n debug(\"initTelemetry: tracing disabled, skipping\");\n return;\n }\n\n const platform = process.env.CELERITY_PLATFORM ?? \"local\";\n const isAws = platform === \"aws\";\n debug(\n \"initTelemetry: platform=%s endpoint=%s service=%s\",\n platform,\n config.otlpEndpoint,\n config.serviceName,\n );\n\n const instrumentations = await buildInstrumentations();\n\n sdk = new NodeSDK({\n resource: resourceFromAttributes({\n [ATTR_SERVICE_NAME]: config.serviceName,\n [ATTR_SERVICE_VERSION]: config.serviceVersion,\n }),\n traceExporter: new OTLPTraceExporter({ url: config.otlpEndpoint }),\n logRecordProcessors: [\n new BatchLogRecordProcessor(new OTLPLogExporter({ url: config.otlpEndpoint })),\n ],\n textMapPropagator: new CompositePropagator({\n propagators: [new W3CTraceContextPropagator(), new AWSXRayPropagator()],\n }),\n ...(isAws ? { idGenerator: new AWSXRayIdGenerator() } : {}),\n instrumentations,\n });\n\n sdk.start();\n initialized = true;\n debug(\"initTelemetry: SDK started\");\n}\n\nexport async function shutdownTelemetry(): Promise<void> {\n if (sdk) {\n debug(\"shutdownTelemetry: shutting down SDK\");\n await sdk.shutdown();\n sdk = null;\n initialized = false;\n }\n}\n","import createDebug from \"debug\";\nimport { HttpInstrumentation } from \"@opentelemetry/instrumentation-http\";\nimport { UndiciInstrumentation } from \"@opentelemetry/instrumentation-undici\";\nimport type { Instrumentation } from \"@opentelemetry/instrumentation\";\n\nconst debug = createDebug(\"celerity:telemetry\");\n\nexport async function buildInstrumentations(): Promise<Instrumentation[]> {\n // Core instrumentation: always active — covers all HTTP/HTTPS and fetch() calls\n const instrumentations: Instrumentation[] = [\n new HttpInstrumentation() as Instrumentation,\n new UndiciInstrumentation() as Instrumentation,\n ];\n\n // Dynamically load optional instrumentation packages.\n // Each targets a specific library and silently no-ops if the library isn't installed.\n const optionalPackages = [\n \"@opentelemetry/instrumentation-aws-sdk\",\n \"@opentelemetry/instrumentation-ioredis\",\n \"@opentelemetry/instrumentation-pg\",\n \"@opentelemetry/instrumentation-mysql2\",\n ];\n\n for (const name of optionalPackages) {\n try {\n const pkg = name;\n const mod = (await import(pkg)) as Record<string, unknown>;\n const InstrumentationClass = findInstrumentationExport(mod);\n if (InstrumentationClass) {\n debug(\"instrumentation: loaded %s\", name);\n instrumentations.push(new InstrumentationClass() as Instrumentation);\n }\n } catch (err) {\n const code = (err as { code?: string }).code;\n if (code !== \"ERR_MODULE_NOT_FOUND\" && code !== \"MODULE_NOT_FOUND\") {\n debug(\"instrumentation: failed to load %s: %O\", name, err);\n }\n }\n }\n\n return instrumentations;\n}\n\nfunction findInstrumentationExport(mod: Record<string, unknown>): (new () => unknown) | null {\n for (const value of Object.values(mod)) {\n if (typeof value === \"function\" && value.prototype && \"enable\" in value.prototype) {\n return value as new () => unknown;\n }\n }\n return null;\n}\n","import pino from \"pino\";\nimport type { CelerityLogger, LogLevel } from \"@celerity-sdk/types\";\nimport type { TelemetryConfig } from \"./env\";\nimport { createOTelStream } from \"./otel-transport\";\n\n/**\n * Thin pino wrapper implementing CelerityLogger.\n * Every method delegates directly to the underlying pino instance.\n */\nexport class CelerityLoggerImpl implements CelerityLogger {\n constructor(private pinoLogger: pino.Logger) {}\n\n debug(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"debug\", message, attributes);\n }\n\n info(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"info\", message, attributes);\n }\n\n warn(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"warn\", message, attributes);\n }\n\n error(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"error\", message, attributes);\n }\n\n private log(level: LogLevel, message: string, attributes?: Record<string, unknown>): void {\n const fn = this.pinoLogger[level].bind(this.pinoLogger);\n if (attributes) fn(attributes, message);\n else fn(message);\n }\n\n child(name: string, attributes?: Record<string, unknown>): CelerityLogger {\n return new CelerityLoggerImpl(this.pinoLogger.child({ name, ...attributes }));\n }\n\n withContext(attributes: Record<string, unknown>): CelerityLogger {\n return new CelerityLoggerImpl(this.pinoLogger.child(attributes));\n }\n\n /** Update the log level at runtime. Internal — used by TelemetryLayer for dynamic config. */\n setLevel(level: LogLevel): void {\n this.pinoLogger.level = level;\n }\n}\n\nexport async function createLogger(config: TelemetryConfig): Promise<CelerityLoggerImpl> {\n const streams: pino.StreamEntry[] = [];\n\n const isLocal = !process.env.CELERITY_PLATFORM || process.env.CELERITY_PLATFORM === \"local\";\n const useHumanFormat = config.logFormat === \"human\" || (config.logFormat === \"auto\" && isLocal);\n\n if (useHumanFormat) {\n // pino-pretty in main thread for consistent output ordering with core runtime logs\n const pinoPrettyPkg = \"pino-pretty\";\n const { default: pinoPretty } = (await import(pinoPrettyPkg)) as {\n default: (opts: Record<string, unknown>) => NodeJS.WritableStream;\n };\n streams.push({\n level: config.logLevel,\n stream: pinoPretty({ destination: 1, translateTime: \"SYS:standard\" }),\n });\n } else {\n // Raw JSON to stdout — synchronous, Lambda-safe\n streams.push({ level: config.logLevel, stream: pino.destination(1) });\n }\n\n // File stream — if configured (synchronous SonicBoom destination)\n if (config.logFilePath) {\n streams.push({\n level: config.logLevel,\n stream: pino.destination(config.logFilePath),\n });\n }\n\n // OTel log stream — main-thread writable (NOT worker-thread transport).\n // Runs in main thread so it can read active OTel context (traceId/spanId)\n // and is safe for Lambda (no worker thread flush issues).\n if (config.tracingEnabled) {\n streams.push({\n level: config.logLevel,\n stream: createOTelStream(),\n });\n }\n\n const redactPaths = resolveRedactPaths();\n\n const logger = pino(\n {\n level: config.logLevel,\n redact: redactPaths.length > 0 ? { paths: redactPaths, censor: \"[REDACTED]\" } : undefined,\n timestamp: pino.stdTimeFunctions.isoTime,\n },\n pino.multistream(streams),\n );\n\n return new CelerityLoggerImpl(logger);\n}\n\nfunction resolveRedactPaths(): string[] {\n const keys = process.env.CELERITY_LOG_REDACT_KEYS;\n if (!keys) return [];\n return keys.split(\",\").map((k) => k.trim());\n}\n","import { Writable } from \"node:stream\";\nimport { logs, SeverityNumber } from \"@opentelemetry/api-logs\";\n\nconst LEVEL_MAP: Record<number, SeverityNumber> = {\n 10: SeverityNumber.TRACE,\n 20: SeverityNumber.DEBUG,\n 30: SeverityNumber.INFO,\n 40: SeverityNumber.WARN,\n 50: SeverityNumber.ERROR,\n 60: SeverityNumber.FATAL,\n};\n\n/**\n * Creates a main-thread writable stream that bridges pino log records\n * to the OTel Logs API.\n *\n * Runs in the main thread (NOT a pino worker-thread transport) so it can:\n * 1. Read traceId/spanId from the active OTel context (trace correlation)\n * 2. Flush reliably in Lambda (no worker thread lifecycle issues)\n */\nexport function createOTelStream(): Writable {\n const otelLogger = logs.getLogger(\"celerity\");\n\n return new Writable({\n write(chunk: Buffer | string, _encoding, callback) {\n try {\n const obj = JSON.parse(typeof chunk === \"string\" ? chunk : chunk.toString()) as Record<\n string,\n unknown\n >;\n const { level, msg, name, ...rest } = obj;\n delete rest.time;\n const attributes: Record<string, string | number | boolean> = {};\n if (typeof name === \"string\") attributes[\"logger.name\"] = name;\n for (const [key, val] of Object.entries(rest)) {\n if (typeof val === \"string\" || typeof val === \"number\" || typeof val === \"boolean\") {\n attributes[key] = val;\n }\n }\n otelLogger.emit({\n severityNumber: LEVEL_MAP[level as number] ?? SeverityNumber.INFO,\n body: msg as string,\n attributes,\n });\n } catch {\n // Malformed JSON — skip\n }\n callback();\n },\n });\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { CelerityLogger } from \"@celerity-sdk/types\";\n\ntype RequestStore = {\n logger: CelerityLogger;\n};\n\nexport const requestStore = new AsyncLocalStorage<RequestStore>();\n\n/**\n * Get the request-scoped logger from the current async context.\n *\n * Works anywhere in the async call chain during request handling —\n * handlers, services, repositories, API clients.\n *\n * Returns `undefined` outside a request context (e.g., startup code, background tasks).\n */\nexport function getRequestLogger(): CelerityLogger | undefined {\n return requestStore.getStore()?.logger;\n}\n\n/**\n * Context-aware logger proxy registered under LOGGER_TOKEN.\n *\n * Delegates to the request-scoped logger (via AsyncLocalStorage) when inside\n * a request context, falls back to the root logger otherwise.\n *\n * This means `@Inject(LOGGER_TOKEN)` automatically resolves to the most\n * appropriate logger for the current context — no manual wiring needed.\n */\nexport class ContextAwareLogger implements CelerityLogger {\n constructor(private rootLogger: CelerityLogger) {}\n\n private get current(): CelerityLogger {\n return getRequestLogger() ?? this.rootLogger;\n }\n\n debug(message: string, attributes?: Record<string, unknown>): void {\n this.current.debug(message, attributes);\n }\n\n info(message: string, attributes?: Record<string, unknown>): void {\n this.current.info(message, attributes);\n }\n\n warn(message: string, attributes?: Record<string, unknown>): void {\n this.current.warn(message, attributes);\n }\n\n error(message: string, attributes?: Record<string, unknown>): void {\n this.current.error(message, attributes);\n }\n\n child(name: string, attributes?: Record<string, unknown>): CelerityLogger {\n return this.current.child(name, attributes);\n }\n\n withContext(attributes: Record<string, unknown>): CelerityLogger {\n return this.current.withContext(attributes);\n }\n}\n","import {\n trace,\n context as otelContext,\n SpanStatusCode,\n type Span,\n type Attributes,\n} from \"@opentelemetry/api\";\nimport type { CelerityTracer, CeleritySpan } from \"@celerity-sdk/types\";\n\nexport class OTelTracer implements CelerityTracer {\n private tracer = trace.getTracer(\"celerity\");\n\n startSpan(name: string, attributes?: Record<string, unknown>): CeleritySpan {\n const span = this.tracer.startSpan(name, {\n attributes: attributes as Attributes,\n });\n return new OTelSpan(span);\n }\n\n async withSpan<T>(\n name: string,\n fn: (span: CeleritySpan) => T | Promise<T>,\n attributes?: Record<string, unknown>,\n ): Promise<T> {\n const span = this.tracer.startSpan(name, {\n attributes: attributes as Attributes,\n });\n const ctx = trace.setSpan(otelContext.active(), span);\n\n return otelContext.with(ctx, async () => {\n const wrapped = new OTelSpan(span);\n try {\n const result = await fn(wrapped);\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) span.recordException(error);\n throw error;\n } finally {\n span.end();\n }\n });\n }\n}\n\nexport class OTelSpan implements CeleritySpan {\n constructor(private span: Span) {}\n\n setAttribute(key: string, value: string | number | boolean): void {\n this.span.setAttribute(key, value);\n }\n\n setAttributes(attributes: Record<string, string | number | boolean>): void {\n this.span.setAttributes(attributes);\n }\n\n recordError(error: Error): void {\n this.span.recordException(error);\n this.span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n }\n\n setOk(): void {\n this.span.setStatus({ code: SpanStatusCode.OK });\n }\n\n end(): void {\n this.span.end();\n }\n}\n","import type { CelerityTracer, CeleritySpan } from \"@celerity-sdk/types\";\n\nexport class NoopTracer implements CelerityTracer {\n startSpan(): CeleritySpan {\n return NOOP_SPAN;\n }\n\n async withSpan<T>(_name: string, fn: (span: CeleritySpan) => T | Promise<T>): Promise<T> {\n return fn(NOOP_SPAN);\n }\n}\n\nexport const NOOP_SPAN: CeleritySpan = {\n setAttribute() {},\n setAttributes() {},\n recordError() {},\n setOk() {},\n end() {},\n};\n","export { LOGGER_TOKEN, TRACER_TOKEN } from \"@celerity-sdk/common\";\n","import { propagation, ROOT_CONTEXT, type Context } from \"@opentelemetry/api\";\nimport type { HttpRequest } from \"@celerity-sdk/types\";\n\nexport function extractTraceContext(request: HttpRequest): Context {\n if (!request.traceContext) return ROOT_CONTEXT;\n\n // The traceContext map is used directly as a carrier.\n // The composite propagator (W3C + X-Ray) extracts the appropriate context.\n return propagation.extract(ROOT_CONTEXT, request.traceContext);\n}\n","import type { CelerityLogger, CelerityTracer, ServiceContainer } from \"@celerity-sdk/types\";\nimport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\n\nexport async function getLogger(container: ServiceContainer): Promise<CelerityLogger> {\n return container.resolve<CelerityLogger>(LOGGER_TOKEN);\n}\n\nexport async function getTracer(container: ServiceContainer): Promise<CelerityTracer> {\n return container.resolve<CelerityTracer>(TRACER_TOKEN);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;ACAA,IAAAA,gBAAwB;AACxB,IAAAC,cAAkE;AASlE,IAAAC,iBAA8B;;;ACE9B,IAAMC,mBAAmB,oBAAIC,IAAY;EAAC;EAAS;EAAQ;EAAQ;CAAQ;AAC3E,IAAMC,oBAAoB,oBAAID,IAAY;EAAC;EAAQ;EAAS;CAAO;AAE5D,SAASE,mBAAAA;AACd,QAAMC,WAAWC,QAAQC,IAAIC;AAC7B,QAAMC,YAAYH,QAAQC,IAAIG;AAE9B,SAAO;IACLC,gBAAgBL,QAAQC,IAAIK,+BAA+B;IAC3DC,cACEP,QAAQC,IAAIO,+BACZR,QAAQC,IAAIQ,0CACZ;IACFC,aAAaV,QAAQC,IAAIU,qBAAqB;IAC9CC,gBAAgBZ,QAAQC,IAAIY,wBAAwB;IACpDC,UAAUf,YAAYJ,iBAAiBoB,IAAIhB,QAAAA,IAAaA,WAAwB;IAChFiB,WACEb,aAAaN,kBAAkBkB,IAAIZ,SAAAA,IAC9BA,YACD;IACNc,aAAajB,QAAQC,IAAIiB,0BAA0B;EACrD;AACF;AAnBgBpB;;;ACfhB,IAAAqB,gBAAwB;AACxB,sBAAwB;AACxB,uBAAuC;AACvC,kCAAwD;AACxD,sCAAkC;AAClC,qCAAgC;AAChC,sBAAwC;AACxC,kBAA+D;AAC/D,iCAAkC;AAClC,mCAAmC;;;ACTnC,mBAAwB;AACxB,kCAAoC;AACpC,oCAAsC;AAGtC,IAAMC,YAAQC,aAAAA,SAAY,oBAAA;AAE1B,eAAsBC,wBAAAA;AAEpB,QAAMC,mBAAsC;IAC1C,IAAIC,gDAAAA;IACJ,IAAIC,oDAAAA;;AAKN,QAAMC,mBAAmB;IACvB;IACA;IACA;IACA;;AAGF,aAAWC,QAAQD,kBAAkB;AACnC,QAAI;AACF,YAAME,MAAMD;AACZ,YAAME,MAAO,MAAM,OAAOD;AAC1B,YAAME,uBAAuBC,0BAA0BF,GAAAA;AACvD,UAAIC,sBAAsB;AACxBV,cAAM,8BAA8BO,IAAAA;AACpCJ,yBAAiBS,KAAK,IAAIF,qBAAAA,CAAAA;MAC5B;IACF,SAASG,KAAK;AACZ,YAAMC,OAAQD,IAA0BC;AACxC,UAAIA,SAAS,0BAA0BA,SAAS,oBAAoB;AAClEd,cAAM,0CAA0CO,MAAMM,GAAAA;MACxD;IACF;EACF;AAEA,SAAOV;AACT;AAlCsBD;AAoCtB,SAASS,0BAA0BF,KAA4B;AAC7D,aAAWM,SAASC,OAAOC,OAAOR,GAAAA,GAAM;AACtC,QAAI,OAAOM,UAAU,cAAcA,MAAMG,aAAa,YAAYH,MAAMG,WAAW;AACjF,aAAOH;IACT;EACF;AACA,SAAO;AACT;AAPSJ;;;AD9BT,IAAMQ,aAAQC,cAAAA,SAAY,oBAAA;AAE1B,IAAIC,cAAc;AAClB,IAAIC,MAAsB;AAM1B,eAAsBC,gBAAAA;AACpB,MAAIC,aAAa;AACfC,IAAAA,OAAM,8CAAA;AACN;EACF;AAEA,QAAMC,SAASC,iBAAAA;AACf,MAAI,CAACD,OAAOE,gBAAgB;AAC1BH,IAAAA,OAAM,2CAAA;AACN;EACF;AAEA,QAAMI,WAAWC,QAAQC,IAAIC,qBAAqB;AAClD,QAAMC,QAAQJ,aAAa;AAC3BJ,EAAAA,OACE,qDACAI,UACAH,OAAOQ,cACPR,OAAOS,WAAW;AAGpB,QAAMC,mBAAmB,MAAMC,sBAAAA;AAE/BC,QAAM,IAAIC,wBAAQ;IAChBC,cAAUC,yCAAuB;MAC/B,CAACC,6CAAAA,GAAoBhB,OAAOS;MAC5B,CAACQ,gDAAAA,GAAuBjB,OAAOkB;IACjC,CAAA;IACAC,eAAe,IAAIC,kDAAkB;MAAEC,KAAKrB,OAAOQ;IAAa,CAAA;IAChEc,qBAAqB;MACnB,IAAIC,wCAAwB,IAAIC,+CAAgB;QAAEH,KAAKrB,OAAOQ;MAAa,CAAA,CAAA;;IAE7EiB,mBAAmB,IAAIC,gCAAoB;MACzCC,aAAa;QAAC,IAAIC,sCAAAA;QAA6B,IAAIC,6CAAAA;;IACrD,CAAA;IACA,GAAItB,QAAQ;MAAEuB,aAAa,IAAIC,gDAAAA;IAAqB,IAAI,CAAC;IACzDrB;EACF,CAAA;AAEAE,MAAIoB,MAAK;AACTlC,gBAAc;AACdC,EAAAA,OAAM,4BAAA;AACR;AA1CsBF;AA4CtB,eAAsBoC,oBAAAA;AACpB,MAAIrB,KAAK;AACPb,IAAAA,OAAM,sCAAA;AACN,UAAMa,IAAIsB,SAAQ;AAClBtB,UAAM;AACNd,kBAAc;EAChB;AACF;AAPsBmC;;;AElEtB,kBAAiB;;;ACAjB,yBAAyB;AACzB,sBAAqC;AAErC,IAAME,YAA4C;EAChD,IAAIC,+BAAeC;EACnB,IAAID,+BAAeE;EACnB,IAAIF,+BAAeG;EACnB,IAAIH,+BAAeI;EACnB,IAAIJ,+BAAeK;EACnB,IAAIL,+BAAeM;AACrB;AAUO,SAASC,mBAAAA;AACd,QAAMC,aAAaC,qBAAKC,UAAU,UAAA;AAElC,SAAO,IAAIC,4BAAS;IAClBC,MAAMC,OAAwBC,WAAWC,UAAQ;AAC/C,UAAI;AACF,cAAMC,MAAMC,KAAKC,MAAM,OAAOL,UAAU,WAAWA,QAAQA,MAAMM,SAAQ,CAAA;AAIzE,cAAM,EAAEC,OAAOC,KAAKC,MAAM,GAAGC,KAAAA,IAASP;AACtC,eAAOO,KAAKC;AACZ,cAAMC,aAAwD,CAAC;AAC/D,YAAI,OAAOH,SAAS,SAAUG,YAAW,aAAA,IAAiBH;AAC1D,mBAAW,CAACI,KAAKC,GAAAA,KAAQC,OAAOC,QAAQN,IAAAA,GAAO;AAC7C,cAAI,OAAOI,QAAQ,YAAY,OAAOA,QAAQ,YAAY,OAAOA,QAAQ,WAAW;AAClFF,uBAAWC,GAAAA,IAAOC;UACpB;QACF;AACAnB,mBAAWsB,KAAK;UACdC,gBAAgBhC,UAAUqB,KAAAA,KAAoBpB,+BAAeG;UAC7D6B,MAAMX;UACNI;QACF,CAAA;MACF,QAAQ;MAER;AACAV,eAAAA;IACF;EACF,CAAA;AACF;AA9BgBR;;;ADXT,IAAM0B,qBAAN,MAAMA,oBAAAA;EATb,OASaA;;;;EACX,YAAoBC,YAAyB;SAAzBA,aAAAA;EAA0B;EAE9CC,MAAMC,SAAiBC,YAA4C;AACjE,SAAKC,IAAI,SAASF,SAASC,UAAAA;EAC7B;EAEAE,KAAKH,SAAiBC,YAA4C;AAChE,SAAKC,IAAI,QAAQF,SAASC,UAAAA;EAC5B;EAEAG,KAAKJ,SAAiBC,YAA4C;AAChE,SAAKC,IAAI,QAAQF,SAASC,UAAAA;EAC5B;EAEAI,MAAML,SAAiBC,YAA4C;AACjE,SAAKC,IAAI,SAASF,SAASC,UAAAA;EAC7B;EAEQC,IAAII,OAAiBN,SAAiBC,YAA4C;AACxF,UAAMM,KAAK,KAAKT,WAAWQ,KAAAA,EAAOE,KAAK,KAAKV,UAAU;AACtD,QAAIG,WAAYM,IAAGN,YAAYD,OAAAA;QAC1BO,IAAGP,OAAAA;EACV;EAEAS,MAAMC,MAAcT,YAAsD;AACxE,WAAO,IAAIJ,oBAAmB,KAAKC,WAAWW,MAAM;MAAEC;MAAM,GAAGT;IAAW,CAAA,CAAA;EAC5E;EAEAU,YAAYV,YAAqD;AAC/D,WAAO,IAAIJ,oBAAmB,KAAKC,WAAWW,MAAMR,UAAAA,CAAAA;EACtD;;EAGAW,SAASN,OAAuB;AAC9B,SAAKR,WAAWQ,QAAQA;EAC1B;AACF;AAEA,eAAsBO,aAAaC,QAAuB;AACxD,QAAMC,UAA8B,CAAA;AAEpC,QAAMC,UAAU,CAACC,QAAQC,IAAIC,qBAAqBF,QAAQC,IAAIC,sBAAsB;AACpF,QAAMC,iBAAiBN,OAAOO,cAAc,WAAYP,OAAOO,cAAc,UAAUL;AAEvF,MAAII,gBAAgB;AAElB,UAAME,gBAAgB;AACtB,UAAM,EAAEC,SAASC,WAAU,IAAM,MAAM,OAAOF;AAG9CP,YAAQU,KAAK;MACXnB,OAAOQ,OAAOY;MACdC,QAAQH,WAAW;QAAEI,aAAa;QAAGC,eAAe;MAAe,CAAA;IACrE,CAAA;EACF,OAAO;AAELd,YAAQU,KAAK;MAAEnB,OAAOQ,OAAOY;MAAUC,QAAQG,YAAAA,QAAKF,YAAY,CAAA;IAAG,CAAA;EACrE;AAGA,MAAId,OAAOiB,aAAa;AACtBhB,YAAQU,KAAK;MACXnB,OAAOQ,OAAOY;MACdC,QAAQG,YAAAA,QAAKF,YAAYd,OAAOiB,WAAW;IAC7C,CAAA;EACF;AAKA,MAAIjB,OAAOkB,gBAAgB;AACzBjB,YAAQU,KAAK;MACXnB,OAAOQ,OAAOY;MACdC,QAAQM,iBAAAA;IACV,CAAA;EACF;AAEA,QAAMC,cAAcC,mBAAAA;AAEpB,QAAMC,aAASN,YAAAA,SACb;IACExB,OAAOQ,OAAOY;IACdW,QAAQH,YAAYI,SAAS,IAAI;MAAEC,OAAOL;MAAaM,QAAQ;IAAa,IAAIC;IAChFC,WAAWZ,YAAAA,QAAKa,iBAAiBC;EACnC,GACAd,YAAAA,QAAKe,YAAY9B,OAAAA,CAAAA;AAGnB,SAAO,IAAIlB,mBAAmBuC,MAAAA;AAChC;AAnDsBvB;AAqDtB,SAASsB,qBAAAA;AACP,QAAMW,OAAO7B,QAAQC,IAAI6B;AACzB,MAAI,CAACD,KAAM,QAAO,CAAA;AAClB,SAAOA,KAAKE,MAAM,GAAA,EAAKC,IAAI,CAACC,MAAMA,EAAEC,KAAI,CAAA;AAC1C;AAJShB;;;AErGT,8BAAkC;AAO3B,IAAMiB,eAAe,IAAIC,0CAAAA;AAUzB,SAASC,mBAAAA;AACd,SAAOF,aAAaG,SAAQ,GAAIC;AAClC;AAFgBF;AAaT,IAAMG,qBAAN,MAAMA;EA9Bb,OA8BaA;;;;EACX,YAAoBC,YAA4B;SAA5BA,aAAAA;EAA6B;EAEjD,IAAYC,UAA0B;AACpC,WAAOL,iBAAAA,KAAsB,KAAKI;EACpC;EAEAE,MAAMC,SAAiBC,YAA4C;AACjE,SAAKH,QAAQC,MAAMC,SAASC,UAAAA;EAC9B;EAEAC,KAAKF,SAAiBC,YAA4C;AAChE,SAAKH,QAAQI,KAAKF,SAASC,UAAAA;EAC7B;EAEAE,KAAKH,SAAiBC,YAA4C;AAChE,SAAKH,QAAQK,KAAKH,SAASC,UAAAA;EAC7B;EAEAG,MAAMJ,SAAiBC,YAA4C;AACjE,SAAKH,QAAQM,MAAMJ,SAASC,UAAAA;EAC9B;EAEAI,MAAMC,MAAcL,YAAsD;AACxE,WAAO,KAAKH,QAAQO,MAAMC,MAAML,UAAAA;EAClC;EAEAM,YAAYN,YAAqD;AAC/D,WAAO,KAAKH,QAAQS,YAAYN,UAAAA;EAClC;AACF;;;AC5DA,iBAMO;AAGA,IAAMO,aAAN,MAAMA;EATb,OASaA;;;EACHC,SAASC,iBAAMC,UAAU,UAAA;EAEjCC,UAAUC,MAAcC,YAAoD;AAC1E,UAAMC,OAAO,KAAKN,OAAOG,UAAUC,MAAM;MACvCC;IACF,CAAA;AACA,WAAO,IAAIE,SAASD,IAAAA;EACtB;EAEA,MAAME,SACJJ,MACAK,IACAJ,YACY;AACZ,UAAMC,OAAO,KAAKN,OAAOG,UAAUC,MAAM;MACvCC;IACF,CAAA;AACA,UAAMK,MAAMT,iBAAMU,QAAQC,WAAAA,QAAYC,OAAM,GAAIP,IAAAA;AAEhD,WAAOM,WAAAA,QAAYE,KAAKJ,KAAK,YAAA;AAC3B,YAAMK,UAAU,IAAIR,SAASD,IAAAA;AAC7B,UAAI;AACF,cAAMU,SAAS,MAAMP,GAAGM,OAAAA;AACxBT,aAAKW,UAAU;UAAEC,MAAMC,0BAAeC;QAAG,CAAA;AACzC,eAAOJ;MACT,SAASK,OAAO;AACdf,aAAKW,UAAU;UAAEC,MAAMC,0BAAeG;QAAM,CAAA;AAC5C,YAAID,iBAAiBE,MAAOjB,MAAKkB,gBAAgBH,KAAAA;AACjD,cAAMA;MACR,UAAA;AACEf,aAAKmB,IAAG;MACV;IACF,CAAA;EACF;AACF;AAEO,IAAMlB,WAAN,MAAMA;EA9Cb,OA8CaA;;;;EACX,YAAoBD,MAAY;SAAZA,OAAAA;EAAa;EAEjCoB,aAAaC,KAAaC,OAAwC;AAChE,SAAKtB,KAAKoB,aAAaC,KAAKC,KAAAA;EAC9B;EAEAC,cAAcxB,YAA6D;AACzE,SAAKC,KAAKuB,cAAcxB,UAAAA;EAC1B;EAEAyB,YAAYT,OAAoB;AAC9B,SAAKf,KAAKkB,gBAAgBH,KAAAA;AAC1B,SAAKf,KAAKW,UAAU;MAAEC,MAAMC,0BAAeG;MAAOS,SAASV,MAAMU;IAAQ,CAAA;EAC3E;EAEAC,QAAc;AACZ,SAAK1B,KAAKW,UAAU;MAAEC,MAAMC,0BAAeC;IAAG,CAAA;EAChD;EAEAK,MAAY;AACV,SAAKnB,KAAKmB,IAAG;EACf;AACF;;;ACnEO,IAAMQ,aAAN,MAAMA;EAAb,OAAaA;;;EACXC,YAA0B;AACxB,WAAOC;EACT;EAEA,MAAMC,SAAYC,OAAeC,IAAwD;AACvF,WAAOA,GAAGH,SAAAA;EACZ;AACF;AAEO,IAAMA,YAA0B;EACrCI,eAAAA;EAAgB;EAChBC,gBAAAA;EAAiB;EACjBC,cAAAA;EAAe;EACfC,QAAAA;EAAS;EACTC,MAAAA;EAAO;AACT;;;AClBA,oBAA2C;;;ATmB3C,IAAMC,eAAWC,cAAAA,SAAY,oBAAA;AAE7B,SAASC,cAAcC,SAA2B;AAChD,SAAO,aAAaA,WAAW,OAAQA,QAA+BC,YAAY;AACpF;AAFSF;AAIT,SAASG,kBAAkBF,SAA2B;AACpD,SACE,WAAWA,WACX,OAAQA,QAAmCG,UAAU,YACrD,eAAgBH,QAAmCG,SAAS,CAAC;AAEjE;AANSD;AAQT,IAAME,wBAAwB;EAC5B;EACA;EACA;EACA;;AAGF,IAAMC,oBAAmB,oBAAIC,IAAY;EAAC;EAAS;EAAQ;EAAQ;CAAQ;AAMpE,IAAMC,iBAAN,MAAMA;EA9Cb,OA8CaA;;;EACHC;EACAC,aAAwC;EACxCC;EACAC,cAAoC;EAE5C,cAAc;AACZ,SAAKH,SAASI,iBAAAA;AACd,SAAKF,eAAe,KAAKF,OAAOK;AAEhC,QAAI,KAAKL,OAAOM,gBAAgB;AAC9B,WAAKH,cAAcI,cAAAA;IACrB;EACF;EAEA,MAAMC,OAAOhB,SAA6BiB,MAAgD;AACxF,QAAI,KAAKN,aAAa;AACpB,YAAM,KAAKA;AACX,WAAKA,cAAc;IACrB;AAEA,QAAI,CAAC,KAAKF,YAAY;AACpBZ,eACE,8CACA,KAAKW,OAAOU,WACZ,KAAKV,OAAOK,QAAQ;AAEtB,WAAKJ,aAAa,MAAMU,aAAa,KAAKX,MAAM;AAChDR,cAAQoB,UAAUC,SAASC,4BAAc;QACvCC,UAAU,IAAIC,mBAAmB,KAAKf,UAAU;MAClD,CAAA;AACAT,cAAQoB,UAAUC,SAASI,4BAAc;QACvCF,UAAU,KAAKf,OAAOM,iBAAiB,IAAIY,WAAAA,IAAe,IAAIC,WAAAA;MAChE,CAAA;AACA9B,eAAS,6CAA6C,KAAKW,OAAOM,cAAc;IAClF;AAEA,UAAM,KAAKc,0BAA0B5B,QAAQoB,SAAS;AAEtD,UAAMS,cAAc7B,QAAQ8B,SAASC,IAAI,aAAA;AACzC,QAAIC;AACJ,QAAIC;AAEJ,QAAIlC,cAAcC,OAAAA,GAAU;AAC1B,YAAMkC,aAASC,8BAAcnC,QAAQC,QAAQmC,IAAI;AACjDJ,sBAAgB,KAAKvB,WAAW4B,MAAM,WAAW;QAC/C,GAAIR,cAAc;UAAEA;QAAY,IAAI,CAAC;QACrCS,WAAWtC,QAAQC,QAAQqC;QAC3BC,QAAQvC,QAAQC,QAAQsC;QACxBC,MAAMxC,QAAQC,QAAQuC;QACtBC,cAAczC,QAAQC,QAAQwC;QAC9BC,UAAU1C,QAAQC,QAAQyC;QAC1BC,WAAW3C,QAAQC,QAAQ0C;QAC3B,GAAIT,SAAS;UAAEA;QAAO,IAAI,CAAC;MAC7B,CAAA;AACAD,qBAAejC,QAAQC,QAAQ2C,gBAAgBC;IACjD,WAAW3C,kBAAkBF,OAAAA,GAAU;AACrC,YAAM,EAAE8C,SAAQ,IAAK9C,QAAQG;AAC7B,YAAM4C,QAAQD,SAAS,CAAA;AACvB,YAAME,kBAAkBD,OAAOE,mBAAmBD,iBAAiBE;AACnElB,sBAAgB,KAAKvB,WAAW4B,MAAM,YAAY;QAChD,GAAIR,cAAc;UAAEA;QAAY,IAAI,CAAC;QACrCsB,QAAQJ,OAAOI;QACfC,cAAcN,SAASO;QACvB,GAAIL,kBAAkB;UAAEA;QAAgB,IAAI,CAAC;MAC/C,CAAA;AACAf,qBAAejC,QAAQG,MAAMyC,gBAAgBC;IAC/C,OAAO;AACLb,sBAAgB,KAAKvB,WAAW4B,MAAM,WAAW;QAC/C,GAAIR,cAAc;UAAEA;QAAY,IAAI,CAAC;MACvC,CAAA;IACF;AAEA7B,YAAQsD,SAAStB;AAEjB,UAAMuB,gBAAgB,6BAAMC,aAAaC,IAAI;MAAEH,QAAQtB;IAAc,GAAG,MAAMf,KAAAA,CAAAA,GAAxD;AAEtB,QAAI,CAAC,KAAKT,OAAOM,eAAgB,QAAOyC,cAAAA;AAExC,QAAItB,cAAc;AAChB,YAAMyB,gBAAgBC,wBAAYC,QAAQC,0BAAc5B,YAAAA;AACxD,aAAO6B,YAAAA,QAAYC,KAAKL,eAAeH,aAAAA;IACzC;AAEA,WAAOA,cAAAA;EACT;EAEA,MAAMS,UAAyB;AAC7B,QAAI,KAAKxD,OAAOM,eAAgB,OAAMmD,kBAAAA;EACxC;EAEA,MAAcrC,0BAA0BR,WAA4C;AAClF,QAAI,CAACA,UAAU8C,IAAI,eAAA,EAAkB;AAErC,QAAI;AACF,YAAMC,gBAAgB,MAAM/C,UAAUgD,QAAuB,eAAA;AAC7D,iBAAWC,OAAOjE,uBAAuB;AACvC,cAAMkE,QAAQ,MAAMH,cAAcpC,IAAIsC,GAAAA;AACtC,YAAIC,SAASjE,kBAAiB6D,IAAII,KAAAA,KAAUA,UAAU,KAAK5D,cAAc;AACvEb,mBAAS,kCAA6B,KAAKa,cAAc4D,KAAAA;AACzD,eAAK7D,YAAY8D,SAASD,KAAAA;AAC1B,eAAK5D,eAAe4D;AACpB;QACF;MACF;IACF,QAAQ;IAER;EACF;AACF;;;AD1JA,IAAAE,iBAA8B;;;AWD9B,IAAAC,cAAwD;AAGjD,SAASC,oBAAoBC,SAAoB;AACtD,MAAI,CAACA,QAAQC,aAAc,QAAOC;AAIlC,SAAOC,wBAAYC,QAAQF,0BAAcF,QAAQC,YAAY;AAC/D;AANgBF;;;ACAhB,eAAsBM,UAAUC,WAA2B;AACzD,SAAOA,UAAUC,QAAwBC,0BAAAA;AAC3C;AAFsBH;AAItB,eAAsBI,UAAUH,WAA2B;AACzD,SAAOA,UAAUC,QAAwBG,0BAAAA;AAC3C;AAFsBD;","names":["import_debug","import_api","import_common","VALID_LOG_LEVELS","Set","VALID_LOG_FORMATS","readTelemetryEnv","rawLevel","process","env","CELERITY_LOG_LEVEL","rawFormat","CELERITY_LOG_FORMAT","tracingEnabled","CELERITY_TELEMETRY_ENABLED","otlpEndpoint","OTEL_EXPORTER_OTLP_ENDPOINT","CELERITY_TRACE_OTLP_COLLECTOR_ENDPOINT","serviceName","OTEL_SERVICE_NAME","serviceVersion","OTEL_SERVICE_VERSION","logLevel","has","logFormat","logFilePath","CELERITY_LOG_FILE_PATH","import_debug","debug","createDebug","buildInstrumentations","instrumentations","HttpInstrumentation","UndiciInstrumentation","optionalPackages","name","pkg","mod","InstrumentationClass","findInstrumentationExport","push","err","code","value","Object","values","prototype","debug","createDebug","initialized","sdk","initTelemetry","initialized","debug","config","readTelemetryEnv","tracingEnabled","platform","process","env","CELERITY_PLATFORM","isAws","otlpEndpoint","serviceName","instrumentations","buildInstrumentations","sdk","NodeSDK","resource","resourceFromAttributes","ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","serviceVersion","traceExporter","OTLPTraceExporter","url","logRecordProcessors","BatchLogRecordProcessor","OTLPLogExporter","textMapPropagator","CompositePropagator","propagators","W3CTraceContextPropagator","AWSXRayPropagator","idGenerator","AWSXRayIdGenerator","start","shutdownTelemetry","shutdown","LEVEL_MAP","SeverityNumber","TRACE","DEBUG","INFO","WARN","ERROR","FATAL","createOTelStream","otelLogger","logs","getLogger","Writable","write","chunk","_encoding","callback","obj","JSON","parse","toString","level","msg","name","rest","time","attributes","key","val","Object","entries","emit","severityNumber","body","CelerityLoggerImpl","pinoLogger","debug","message","attributes","log","info","warn","error","level","fn","bind","child","name","withContext","setLevel","createLogger","config","streams","isLocal","process","env","CELERITY_PLATFORM","useHumanFormat","logFormat","pinoPrettyPkg","default","pinoPretty","push","logLevel","stream","destination","translateTime","pino","logFilePath","tracingEnabled","createOTelStream","redactPaths","resolveRedactPaths","logger","redact","length","paths","censor","undefined","timestamp","stdTimeFunctions","isoTime","multistream","keys","CELERITY_LOG_REDACT_KEYS","split","map","k","trim","requestStore","AsyncLocalStorage","getRequestLogger","getStore","logger","ContextAwareLogger","rootLogger","current","debug","message","attributes","info","warn","error","child","name","withContext","OTelTracer","tracer","trace","getTracer","startSpan","name","attributes","span","OTelSpan","withSpan","fn","ctx","setSpan","otelContext","active","with","wrapped","result","setStatus","code","SpanStatusCode","OK","error","ERROR","Error","recordException","end","setAttribute","key","value","setAttributes","recordError","message","setOk","NoopTracer","startSpan","NOOP_SPAN","withSpan","_name","fn","setAttribute","setAttributes","recordError","setOk","end","debugLog","createDebug","isHttpContext","context","request","isConsumerContext","event","LOG_LEVEL_CONFIG_KEYS","VALID_LOG_LEVELS","Set","TelemetryLayer","config","rootLogger","currentLevel","initPromise","readTelemetryEnv","logLevel","tracingEnabled","initTelemetry","handle","next","logFormat","createLogger","container","register","LOGGER_TOKEN","useValue","ContextAwareLogger","TRACER_TOKEN","OTelTracer","NoopTracer","refreshLogLevelFromConfig","handlerName","metadata","get","handlerLogger","traceCarrier","userId","extractUserId","auth","child","requestId","method","path","matchedRoute","clientIp","userAgent","traceContext","undefined","messages","first","sourceMessageId","messageAttributes","stringValue","source","messageCount","length","logger","runWithLogger","requestStore","run","parentContext","propagation","extract","ROOT_CONTEXT","otelContext","with","dispose","shutdownTelemetry","has","configService","resolve","key","value","setLevel","import_common","import_api","extractTraceContext","request","traceContext","ROOT_CONTEXT","propagation","extract","getLogger","container","resolve","LOGGER_TOKEN","getTracer","TRACER_TOKEN"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { CelerityLayer,
|
|
2
|
-
export { extractUserId } from '@celerity-sdk/common';
|
|
1
|
+
import { CelerityLayer, BaseHandlerContext, LogLevel, CelerityLogger, CeleritySpan, CelerityTracer, HttpRequest, ServiceContainer } from '@celerity-sdk/types';
|
|
2
|
+
export { LOGGER_TOKEN, TRACER_TOKEN, extractUserId } from '@celerity-sdk/common';
|
|
3
3
|
import pino from 'pino';
|
|
4
4
|
import { Span, Context } from '@opentelemetry/api';
|
|
5
5
|
|
|
6
|
-
declare class TelemetryLayer implements CelerityLayer {
|
|
6
|
+
declare class TelemetryLayer implements CelerityLayer<BaseHandlerContext> {
|
|
7
7
|
private config;
|
|
8
8
|
private rootLogger;
|
|
9
9
|
private currentLevel;
|
|
10
10
|
private initPromise;
|
|
11
11
|
constructor();
|
|
12
|
-
handle(context:
|
|
12
|
+
handle(context: BaseHandlerContext, next: () => Promise<unknown>): Promise<unknown>;
|
|
13
13
|
dispose(): Promise<void>;
|
|
14
14
|
private refreshLogLevelFromConfig;
|
|
15
15
|
}
|
|
@@ -42,7 +42,7 @@ declare class CelerityLoggerImpl implements CelerityLogger {
|
|
|
42
42
|
/** Update the log level at runtime. Internal — used by TelemetryLayer for dynamic config. */
|
|
43
43
|
setLevel(level: LogLevel): void;
|
|
44
44
|
}
|
|
45
|
-
declare function createLogger(config: TelemetryConfig): CelerityLoggerImpl
|
|
45
|
+
declare function createLogger(config: TelemetryConfig): Promise<CelerityLoggerImpl>;
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* Get the request-scoped logger from the current async context.
|
|
@@ -95,12 +95,9 @@ declare class NoopTracer implements CelerityTracer {
|
|
|
95
95
|
}
|
|
96
96
|
declare const NOOP_SPAN: CeleritySpan;
|
|
97
97
|
|
|
98
|
-
declare const LOGGER_TOKEN = "CelerityLogger";
|
|
99
|
-
declare const TRACER_TOKEN = "CelerityTracer";
|
|
100
|
-
|
|
101
98
|
declare function extractTraceContext(request: HttpRequest): Context;
|
|
102
99
|
|
|
103
100
|
declare function getLogger(container: ServiceContainer): Promise<CelerityLogger>;
|
|
104
101
|
declare function getTracer(container: ServiceContainer): Promise<CelerityTracer>;
|
|
105
102
|
|
|
106
|
-
export { CelerityLoggerImpl, ContextAwareLogger,
|
|
103
|
+
export { CelerityLoggerImpl, ContextAwareLogger, NOOP_SPAN, NoopTracer, OTelSpan, OTelTracer, type TelemetryConfig, TelemetryLayer, createLogger, extractTraceContext, getLogger, getRequestLogger, getTracer, readTelemetryEnv };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { CelerityLayer,
|
|
2
|
-
export { extractUserId } from '@celerity-sdk/common';
|
|
1
|
+
import { CelerityLayer, BaseHandlerContext, LogLevel, CelerityLogger, CeleritySpan, CelerityTracer, HttpRequest, ServiceContainer } from '@celerity-sdk/types';
|
|
2
|
+
export { LOGGER_TOKEN, TRACER_TOKEN, extractUserId } from '@celerity-sdk/common';
|
|
3
3
|
import pino from 'pino';
|
|
4
4
|
import { Span, Context } from '@opentelemetry/api';
|
|
5
5
|
|
|
6
|
-
declare class TelemetryLayer implements CelerityLayer {
|
|
6
|
+
declare class TelemetryLayer implements CelerityLayer<BaseHandlerContext> {
|
|
7
7
|
private config;
|
|
8
8
|
private rootLogger;
|
|
9
9
|
private currentLevel;
|
|
10
10
|
private initPromise;
|
|
11
11
|
constructor();
|
|
12
|
-
handle(context:
|
|
12
|
+
handle(context: BaseHandlerContext, next: () => Promise<unknown>): Promise<unknown>;
|
|
13
13
|
dispose(): Promise<void>;
|
|
14
14
|
private refreshLogLevelFromConfig;
|
|
15
15
|
}
|
|
@@ -42,7 +42,7 @@ declare class CelerityLoggerImpl implements CelerityLogger {
|
|
|
42
42
|
/** Update the log level at runtime. Internal — used by TelemetryLayer for dynamic config. */
|
|
43
43
|
setLevel(level: LogLevel): void;
|
|
44
44
|
}
|
|
45
|
-
declare function createLogger(config: TelemetryConfig): CelerityLoggerImpl
|
|
45
|
+
declare function createLogger(config: TelemetryConfig): Promise<CelerityLoggerImpl>;
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* Get the request-scoped logger from the current async context.
|
|
@@ -95,12 +95,9 @@ declare class NoopTracer implements CelerityTracer {
|
|
|
95
95
|
}
|
|
96
96
|
declare const NOOP_SPAN: CeleritySpan;
|
|
97
97
|
|
|
98
|
-
declare const LOGGER_TOKEN = "CelerityLogger";
|
|
99
|
-
declare const TRACER_TOKEN = "CelerityTracer";
|
|
100
|
-
|
|
101
98
|
declare function extractTraceContext(request: HttpRequest): Context;
|
|
102
99
|
|
|
103
100
|
declare function getLogger(container: ServiceContainer): Promise<CelerityLogger>;
|
|
104
101
|
declare function getTracer(container: ServiceContainer): Promise<CelerityTracer>;
|
|
105
102
|
|
|
106
|
-
export { CelerityLoggerImpl, ContextAwareLogger,
|
|
103
|
+
export { CelerityLoggerImpl, ContextAwareLogger, NOOP_SPAN, NoopTracer, OTelSpan, OTelTracer, type TelemetryConfig, TelemetryLayer, createLogger, extractTraceContext, getLogger, getRequestLogger, getTracer, readTelemetryEnv };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
3
3
|
|
|
4
4
|
// src/telemetry-layer.ts
|
|
5
5
|
import createDebug3 from "debug";
|
|
6
|
-
import { context as otelContext2 } from "@opentelemetry/api";
|
|
6
|
+
import { context as otelContext2, propagation, ROOT_CONTEXT } from "@opentelemetry/api";
|
|
7
7
|
import { extractUserId } from "@celerity-sdk/common";
|
|
8
8
|
|
|
9
9
|
// src/env.ts
|
|
@@ -229,18 +229,18 @@ var CelerityLoggerImpl = class _CelerityLoggerImpl {
|
|
|
229
229
|
this.pinoLogger.level = level;
|
|
230
230
|
}
|
|
231
231
|
};
|
|
232
|
-
function createLogger(config) {
|
|
232
|
+
async function createLogger(config) {
|
|
233
233
|
const streams = [];
|
|
234
234
|
const isLocal = !process.env.CELERITY_PLATFORM || process.env.CELERITY_PLATFORM === "local";
|
|
235
235
|
const useHumanFormat = config.logFormat === "human" || config.logFormat === "auto" && isLocal;
|
|
236
236
|
if (useHumanFormat) {
|
|
237
|
+
const pinoPrettyPkg = "pino-pretty";
|
|
238
|
+
const { default: pinoPretty } = await import(pinoPrettyPkg);
|
|
237
239
|
streams.push({
|
|
238
240
|
level: config.logLevel,
|
|
239
|
-
stream:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
destination: 1
|
|
243
|
-
}
|
|
241
|
+
stream: pinoPretty({
|
|
242
|
+
destination: 1,
|
|
243
|
+
translateTime: "SYS:standard"
|
|
244
244
|
})
|
|
245
245
|
});
|
|
246
246
|
} else {
|
|
@@ -318,14 +318,6 @@ var ContextAwareLogger = class {
|
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
320
|
|
|
321
|
-
// src/context.ts
|
|
322
|
-
import { propagation, ROOT_CONTEXT } from "@opentelemetry/api";
|
|
323
|
-
function extractTraceContext(request) {
|
|
324
|
-
if (!request.traceContext) return ROOT_CONTEXT;
|
|
325
|
-
return propagation.extract(ROOT_CONTEXT, request.traceContext);
|
|
326
|
-
}
|
|
327
|
-
__name(extractTraceContext, "extractTraceContext");
|
|
328
|
-
|
|
329
321
|
// src/tracer.ts
|
|
330
322
|
import { trace, context as otelContext, SpanStatusCode } from "@opentelemetry/api";
|
|
331
323
|
var OTelTracer = class {
|
|
@@ -421,11 +413,18 @@ var NOOP_SPAN = {
|
|
|
421
413
|
};
|
|
422
414
|
|
|
423
415
|
// src/tokens.ts
|
|
424
|
-
|
|
425
|
-
var TRACER_TOKEN = "CelerityTracer";
|
|
416
|
+
import { LOGGER_TOKEN, TRACER_TOKEN } from "@celerity-sdk/common";
|
|
426
417
|
|
|
427
418
|
// src/telemetry-layer.ts
|
|
428
419
|
var debugLog = createDebug3("celerity:telemetry");
|
|
420
|
+
function isHttpContext(context) {
|
|
421
|
+
return "request" in context && typeof context.request === "object";
|
|
422
|
+
}
|
|
423
|
+
__name(isHttpContext, "isHttpContext");
|
|
424
|
+
function isConsumerContext(context) {
|
|
425
|
+
return "event" in context && typeof context.event === "object" && "messages" in (context.event ?? {});
|
|
426
|
+
}
|
|
427
|
+
__name(isConsumerContext, "isConsumerContext");
|
|
429
428
|
var LOG_LEVEL_CONFIG_KEYS = [
|
|
430
429
|
"CELERITY_LOG_LEVEL",
|
|
431
430
|
"celerityLogLevel",
|
|
@@ -460,7 +459,7 @@ var TelemetryLayer = class {
|
|
|
460
459
|
}
|
|
461
460
|
if (!this.rootLogger) {
|
|
462
461
|
debugLog("creating root logger (format=%s, level=%s)", this.config.logFormat, this.config.logLevel);
|
|
463
|
-
this.rootLogger = createLogger(this.config);
|
|
462
|
+
this.rootLogger = await createLogger(this.config);
|
|
464
463
|
context.container.register(LOGGER_TOKEN, {
|
|
465
464
|
useValue: new ContextAwareLogger(this.rootLogger)
|
|
466
465
|
});
|
|
@@ -470,25 +469,58 @@ var TelemetryLayer = class {
|
|
|
470
469
|
debugLog("registered logger and tracer (tracing=%s)", this.config.tracingEnabled);
|
|
471
470
|
}
|
|
472
471
|
await this.refreshLogLevelFromConfig(context.container);
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
472
|
+
const handlerName = context.metadata.get("handlerName");
|
|
473
|
+
let handlerLogger;
|
|
474
|
+
let traceCarrier;
|
|
475
|
+
if (isHttpContext(context)) {
|
|
476
|
+
const userId = extractUserId(context.request.auth);
|
|
477
|
+
handlerLogger = this.rootLogger.child("request", {
|
|
478
|
+
...handlerName ? {
|
|
479
|
+
handlerName
|
|
480
|
+
} : {},
|
|
481
|
+
requestId: context.request.requestId,
|
|
482
|
+
method: context.request.method,
|
|
483
|
+
path: context.request.path,
|
|
484
|
+
matchedRoute: context.request.matchedRoute,
|
|
485
|
+
clientIp: context.request.clientIp,
|
|
486
|
+
userAgent: context.request.userAgent,
|
|
487
|
+
...userId ? {
|
|
488
|
+
userId
|
|
489
|
+
} : {}
|
|
490
|
+
});
|
|
491
|
+
traceCarrier = context.request.traceContext ?? void 0;
|
|
492
|
+
} else if (isConsumerContext(context)) {
|
|
493
|
+
const { messages } = context.event;
|
|
494
|
+
const first = messages[0];
|
|
495
|
+
const sourceMessageId = first?.messageAttributes?.sourceMessageId?.stringValue;
|
|
496
|
+
handlerLogger = this.rootLogger.child("consumer", {
|
|
497
|
+
...handlerName ? {
|
|
498
|
+
handlerName
|
|
499
|
+
} : {},
|
|
500
|
+
source: first?.source,
|
|
501
|
+
messageCount: messages.length,
|
|
502
|
+
...sourceMessageId ? {
|
|
503
|
+
sourceMessageId
|
|
504
|
+
} : {}
|
|
505
|
+
});
|
|
506
|
+
traceCarrier = context.event.traceContext ?? void 0;
|
|
507
|
+
} else {
|
|
508
|
+
handlerLogger = this.rootLogger.child("handler", {
|
|
509
|
+
...handlerName ? {
|
|
510
|
+
handlerName
|
|
511
|
+
} : {}
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
context.logger = handlerLogger;
|
|
486
515
|
const runWithLogger = /* @__PURE__ */ __name(() => requestStore.run({
|
|
487
|
-
logger:
|
|
516
|
+
logger: handlerLogger
|
|
488
517
|
}, () => next()), "runWithLogger");
|
|
489
518
|
if (!this.config.tracingEnabled) return runWithLogger();
|
|
490
|
-
|
|
491
|
-
|
|
519
|
+
if (traceCarrier) {
|
|
520
|
+
const parentContext = propagation.extract(ROOT_CONTEXT, traceCarrier);
|
|
521
|
+
return otelContext2.with(parentContext, runWithLogger);
|
|
522
|
+
}
|
|
523
|
+
return runWithLogger();
|
|
492
524
|
}
|
|
493
525
|
async dispose() {
|
|
494
526
|
if (this.config.tracingEnabled) await shutdownTelemetry();
|
|
@@ -514,6 +546,14 @@ var TelemetryLayer = class {
|
|
|
514
546
|
// src/index.ts
|
|
515
547
|
import { extractUserId as extractUserId2 } from "@celerity-sdk/common";
|
|
516
548
|
|
|
549
|
+
// src/context.ts
|
|
550
|
+
import { propagation as propagation2, ROOT_CONTEXT as ROOT_CONTEXT2 } from "@opentelemetry/api";
|
|
551
|
+
function extractTraceContext(request) {
|
|
552
|
+
if (!request.traceContext) return ROOT_CONTEXT2;
|
|
553
|
+
return propagation2.extract(ROOT_CONTEXT2, request.traceContext);
|
|
554
|
+
}
|
|
555
|
+
__name(extractTraceContext, "extractTraceContext");
|
|
556
|
+
|
|
517
557
|
// src/helpers.ts
|
|
518
558
|
async function getLogger(container) {
|
|
519
559
|
return container.resolve(LOGGER_TOKEN);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/telemetry-layer.ts","../src/env.ts","../src/init.ts","../src/instrumentations.ts","../src/logger.ts","../src/otel-transport.ts","../src/request-context.ts","../src/context.ts","../src/tracer.ts","../src/noop.ts","../src/tokens.ts","../src/index.ts","../src/helpers.ts"],"sourcesContent":["import createDebug from \"debug\";\nimport { context as otelContext } from \"@opentelemetry/api\";\nimport type {\n CelerityLayer,\n HandlerContext,\n HandlerResponse,\n LogLevel,\n ServiceContainer,\n} from \"@celerity-sdk/types\";\nimport { extractUserId } from \"@celerity-sdk/common\";\nimport { readTelemetryEnv, type TelemetryConfig } from \"./env\";\nimport { initTelemetry, shutdownTelemetry } from \"./init\";\nimport { CelerityLoggerImpl, createLogger } from \"./logger\";\nimport { ContextAwareLogger, requestStore } from \"./request-context\";\nimport { extractTraceContext } from \"./context\";\nimport { OTelTracer } from \"./tracer\";\nimport { NoopTracer } from \"./noop\";\nimport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\n\nconst debugLog = createDebug(\"celerity:telemetry\");\n\nconst LOG_LEVEL_CONFIG_KEYS = [\n \"CELERITY_LOG_LEVEL\",\n \"celerityLogLevel\",\n \"celerity_log_level\",\n \"CelerityLogLevel\",\n];\n\nconst VALID_LOG_LEVELS = new Set<string>([\"debug\", \"info\", \"warn\", \"error\"]);\n\ntype ConfigService = {\n get(key: string): Promise<string | undefined>;\n};\n\nexport class TelemetryLayer implements CelerityLayer {\n private config: TelemetryConfig;\n private rootLogger: CelerityLoggerImpl | null = null;\n private currentLevel: LogLevel;\n private initPromise: Promise<void> | null = null;\n\n constructor() {\n this.config = readTelemetryEnv();\n this.currentLevel = this.config.logLevel;\n\n if (this.config.tracingEnabled) {\n this.initPromise = initTelemetry();\n }\n }\n\n async handle(\n context: HandlerContext,\n next: () => Promise<HandlerResponse>,\n ): Promise<HandlerResponse> {\n if (this.initPromise) {\n await this.initPromise;\n this.initPromise = null;\n }\n\n if (!this.rootLogger) {\n debugLog(\n \"creating root logger (format=%s, level=%s)\",\n this.config.logFormat,\n this.config.logLevel,\n );\n this.rootLogger = createLogger(this.config);\n context.container.register(LOGGER_TOKEN, {\n useValue: new ContextAwareLogger(this.rootLogger),\n });\n context.container.register(TRACER_TOKEN, {\n useValue: this.config.tracingEnabled ? new OTelTracer() : new NoopTracer(),\n });\n debugLog(\"registered logger and tracer (tracing=%s)\", this.config.tracingEnabled);\n }\n\n await this.refreshLogLevelFromConfig(context.container);\n\n const userId = extractUserId(context.request.auth);\n const requestLogger = this.rootLogger.child(\"request\", {\n requestId: context.request.requestId,\n method: context.request.method,\n path: context.request.path,\n matchedRoute: context.request.matchedRoute,\n clientIp: context.request.clientIp,\n userAgent: context.request.userAgent,\n ...(userId ? { userId } : {}),\n });\n context.logger = requestLogger;\n\n const runWithLogger = () => requestStore.run({ logger: requestLogger }, () => next());\n\n if (!this.config.tracingEnabled) return runWithLogger();\n\n const parentContext = extractTraceContext(context.request);\n return otelContext.with(parentContext, runWithLogger);\n }\n\n async dispose(): Promise<void> {\n if (this.config.tracingEnabled) await shutdownTelemetry();\n }\n\n private async refreshLogLevelFromConfig(container: ServiceContainer): Promise<void> {\n if (!container.has(\"ConfigService\")) return;\n\n try {\n const configService = await container.resolve<ConfigService>(\"ConfigService\");\n for (const key of LOG_LEVEL_CONFIG_KEYS) {\n const value = await configService.get(key);\n if (value && VALID_LOG_LEVELS.has(value) && value !== this.currentLevel) {\n debugLog(\"log level changed %s → %s\", this.currentLevel, value);\n this.rootLogger?.setLevel(value as LogLevel);\n this.currentLevel = value as LogLevel;\n return;\n }\n }\n } catch {\n // Config resolution failed — keep current level\n }\n }\n}\n","import type { LogLevel } from \"@celerity-sdk/types\";\n\nexport type TelemetryConfig = {\n tracingEnabled: boolean;\n otlpEndpoint: string;\n serviceName: string;\n serviceVersion: string;\n logLevel: LogLevel;\n logFormat: \"json\" | \"human\" | \"auto\";\n logFilePath: string | null;\n};\n\nconst VALID_LOG_LEVELS = new Set<string>([\"debug\", \"info\", \"warn\", \"error\"]);\nconst VALID_LOG_FORMATS = new Set<string>([\"json\", \"human\", \"auto\"]);\n\nexport function readTelemetryEnv(): TelemetryConfig {\n const rawLevel = process.env.CELERITY_LOG_LEVEL;\n const rawFormat = process.env.CELERITY_LOG_FORMAT;\n\n return {\n tracingEnabled: process.env.CELERITY_TELEMETRY_ENABLED === \"true\",\n otlpEndpoint:\n process.env.OTEL_EXPORTER_OTLP_ENDPOINT ??\n process.env.CELERITY_TRACE_OTLP_COLLECTOR_ENDPOINT ??\n \"http://otelcollector:4317\",\n serviceName: process.env.OTEL_SERVICE_NAME ?? \"celerity-app\",\n serviceVersion: process.env.OTEL_SERVICE_VERSION ?? \"0.0.0\",\n logLevel: rawLevel && VALID_LOG_LEVELS.has(rawLevel) ? (rawLevel as LogLevel) : \"info\",\n logFormat:\n rawFormat && VALID_LOG_FORMATS.has(rawFormat)\n ? (rawFormat as \"json\" | \"human\" | \"auto\")\n : \"auto\",\n logFilePath: process.env.CELERITY_LOG_FILE_PATH ?? null,\n };\n}\n","import createDebug from \"debug\";\nimport { NodeSDK } from \"@opentelemetry/sdk-node\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from \"@opentelemetry/semantic-conventions\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-grpc\";\nimport { OTLPLogExporter } from \"@opentelemetry/exporter-logs-otlp-grpc\";\nimport { BatchLogRecordProcessor } from \"@opentelemetry/sdk-logs\";\nimport { CompositePropagator, W3CTraceContextPropagator } from \"@opentelemetry/core\";\nimport { AWSXRayPropagator } from \"@opentelemetry/propagator-aws-xray\";\nimport { AWSXRayIdGenerator } from \"@opentelemetry/id-generator-aws-xray\";\nimport { readTelemetryEnv } from \"./env\";\nimport { buildInstrumentations } from \"./instrumentations\";\n\nconst debug = createDebug(\"celerity:telemetry\");\n\nlet initialized = false;\nlet sdk: NodeSDK | null = null;\n\nexport function isInitialized(): boolean {\n return initialized;\n}\n\nexport async function initTelemetry(): Promise<void> {\n if (initialized) {\n debug(\"initTelemetry: already initialized, skipping\");\n return;\n }\n\n const config = readTelemetryEnv();\n if (!config.tracingEnabled) {\n debug(\"initTelemetry: tracing disabled, skipping\");\n return;\n }\n\n const platform = process.env.CELERITY_PLATFORM ?? \"local\";\n const isAws = platform === \"aws\";\n debug(\n \"initTelemetry: platform=%s endpoint=%s service=%s\",\n platform,\n config.otlpEndpoint,\n config.serviceName,\n );\n\n const instrumentations = await buildInstrumentations();\n\n sdk = new NodeSDK({\n resource: resourceFromAttributes({\n [ATTR_SERVICE_NAME]: config.serviceName,\n [ATTR_SERVICE_VERSION]: config.serviceVersion,\n }),\n traceExporter: new OTLPTraceExporter({ url: config.otlpEndpoint }),\n logRecordProcessors: [\n new BatchLogRecordProcessor(new OTLPLogExporter({ url: config.otlpEndpoint })),\n ],\n textMapPropagator: new CompositePropagator({\n propagators: [new W3CTraceContextPropagator(), new AWSXRayPropagator()],\n }),\n ...(isAws ? { idGenerator: new AWSXRayIdGenerator() } : {}),\n instrumentations,\n });\n\n sdk.start();\n initialized = true;\n debug(\"initTelemetry: SDK started\");\n}\n\nexport async function shutdownTelemetry(): Promise<void> {\n if (sdk) {\n debug(\"shutdownTelemetry: shutting down SDK\");\n await sdk.shutdown();\n sdk = null;\n initialized = false;\n }\n}\n","import createDebug from \"debug\";\nimport { HttpInstrumentation } from \"@opentelemetry/instrumentation-http\";\nimport { UndiciInstrumentation } from \"@opentelemetry/instrumentation-undici\";\nimport type { Instrumentation } from \"@opentelemetry/instrumentation\";\n\nconst debug = createDebug(\"celerity:telemetry\");\n\nexport async function buildInstrumentations(): Promise<Instrumentation[]> {\n // Core instrumentation: always active — covers all HTTP/HTTPS and fetch() calls\n const instrumentations: Instrumentation[] = [\n new HttpInstrumentation() as Instrumentation,\n new UndiciInstrumentation() as Instrumentation,\n ];\n\n // Dynamically load optional instrumentation packages.\n // Each targets a specific library and silently no-ops if the library isn't installed.\n const optionalPackages = [\n \"@opentelemetry/instrumentation-aws-sdk\",\n \"@opentelemetry/instrumentation-ioredis\",\n \"@opentelemetry/instrumentation-pg\",\n \"@opentelemetry/instrumentation-mysql2\",\n ];\n\n for (const name of optionalPackages) {\n try {\n const pkg = name;\n const mod = (await import(pkg)) as Record<string, unknown>;\n const InstrumentationClass = findInstrumentationExport(mod);\n if (InstrumentationClass) {\n debug(\"instrumentation: loaded %s\", name);\n instrumentations.push(new InstrumentationClass() as Instrumentation);\n }\n } catch (err) {\n const code = (err as { code?: string }).code;\n if (code !== \"ERR_MODULE_NOT_FOUND\" && code !== \"MODULE_NOT_FOUND\") {\n debug(\"instrumentation: failed to load %s: %O\", name, err);\n }\n }\n }\n\n return instrumentations;\n}\n\nfunction findInstrumentationExport(mod: Record<string, unknown>): (new () => unknown) | null {\n for (const value of Object.values(mod)) {\n if (typeof value === \"function\" && value.prototype && \"enable\" in value.prototype) {\n return value as new () => unknown;\n }\n }\n return null;\n}\n","import pino from \"pino\";\nimport type { CelerityLogger, LogLevel } from \"@celerity-sdk/types\";\nimport type { TelemetryConfig } from \"./env\";\nimport { createOTelStream } from \"./otel-transport\";\n\n/**\n * Thin pino wrapper implementing CelerityLogger.\n * Every method delegates directly to the underlying pino instance.\n */\nexport class CelerityLoggerImpl implements CelerityLogger {\n constructor(private pinoLogger: pino.Logger) {}\n\n debug(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"debug\", message, attributes);\n }\n\n info(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"info\", message, attributes);\n }\n\n warn(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"warn\", message, attributes);\n }\n\n error(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"error\", message, attributes);\n }\n\n private log(level: LogLevel, message: string, attributes?: Record<string, unknown>): void {\n const fn = this.pinoLogger[level].bind(this.pinoLogger);\n if (attributes) fn(attributes, message);\n else fn(message);\n }\n\n child(name: string, attributes?: Record<string, unknown>): CelerityLogger {\n return new CelerityLoggerImpl(this.pinoLogger.child({ name, ...attributes }));\n }\n\n withContext(attributes: Record<string, unknown>): CelerityLogger {\n return new CelerityLoggerImpl(this.pinoLogger.child(attributes));\n }\n\n /** Update the log level at runtime. Internal — used by TelemetryLayer for dynamic config. */\n setLevel(level: LogLevel): void {\n this.pinoLogger.level = level;\n }\n}\n\nexport function createLogger(config: TelemetryConfig): CelerityLoggerImpl {\n const streams: pino.StreamEntry[] = [];\n\n const isLocal = !process.env.CELERITY_PLATFORM || process.env.CELERITY_PLATFORM === \"local\";\n const useHumanFormat = config.logFormat === \"human\" || (config.logFormat === \"auto\" && isLocal);\n\n if (useHumanFormat) {\n // pino-pretty via worker thread — fine for local dev only\n streams.push({\n level: config.logLevel,\n stream: pino.transport({ target: \"pino-pretty\", options: { destination: 1 } }),\n });\n } else {\n // Raw JSON to stdout — synchronous, Lambda-safe\n streams.push({ level: config.logLevel, stream: pino.destination(1) });\n }\n\n // File stream — if configured (synchronous SonicBoom destination)\n if (config.logFilePath) {\n streams.push({\n level: config.logLevel,\n stream: pino.destination(config.logFilePath),\n });\n }\n\n // OTel log stream — main-thread writable (NOT worker-thread transport).\n // Runs in main thread so it can read active OTel context (traceId/spanId)\n // and is safe for Lambda (no worker thread flush issues).\n if (config.tracingEnabled) {\n streams.push({\n level: config.logLevel,\n stream: createOTelStream(),\n });\n }\n\n const redactPaths = resolveRedactPaths();\n\n const logger = pino(\n {\n level: config.logLevel,\n redact: redactPaths.length > 0 ? { paths: redactPaths, censor: \"[REDACTED]\" } : undefined,\n timestamp: pino.stdTimeFunctions.isoTime,\n },\n pino.multistream(streams),\n );\n\n return new CelerityLoggerImpl(logger);\n}\n\nfunction resolveRedactPaths(): string[] {\n const keys = process.env.CELERITY_LOG_REDACT_KEYS;\n if (!keys) return [];\n return keys.split(\",\").map((k) => k.trim());\n}\n","import { Writable } from \"node:stream\";\nimport { logs, SeverityNumber } from \"@opentelemetry/api-logs\";\n\nconst LEVEL_MAP: Record<number, SeverityNumber> = {\n 10: SeverityNumber.TRACE,\n 20: SeverityNumber.DEBUG,\n 30: SeverityNumber.INFO,\n 40: SeverityNumber.WARN,\n 50: SeverityNumber.ERROR,\n 60: SeverityNumber.FATAL,\n};\n\n/**\n * Creates a main-thread writable stream that bridges pino log records\n * to the OTel Logs API.\n *\n * Runs in the main thread (NOT a pino worker-thread transport) so it can:\n * 1. Read traceId/spanId from the active OTel context (trace correlation)\n * 2. Flush reliably in Lambda (no worker thread lifecycle issues)\n */\nexport function createOTelStream(): Writable {\n const otelLogger = logs.getLogger(\"celerity\");\n\n return new Writable({\n write(chunk: Buffer | string, _encoding, callback) {\n try {\n const obj = JSON.parse(typeof chunk === \"string\" ? chunk : chunk.toString()) as Record<\n string,\n unknown\n >;\n const { level, msg, name, ...rest } = obj;\n delete rest.time;\n const attributes: Record<string, string | number | boolean> = {};\n if (typeof name === \"string\") attributes[\"logger.name\"] = name;\n for (const [key, val] of Object.entries(rest)) {\n if (typeof val === \"string\" || typeof val === \"number\" || typeof val === \"boolean\") {\n attributes[key] = val;\n }\n }\n otelLogger.emit({\n severityNumber: LEVEL_MAP[level as number] ?? SeverityNumber.INFO,\n body: msg as string,\n attributes,\n });\n } catch {\n // Malformed JSON — skip\n }\n callback();\n },\n });\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { CelerityLogger } from \"@celerity-sdk/types\";\n\ntype RequestStore = {\n logger: CelerityLogger;\n};\n\nexport const requestStore = new AsyncLocalStorage<RequestStore>();\n\n/**\n * Get the request-scoped logger from the current async context.\n *\n * Works anywhere in the async call chain during request handling —\n * handlers, services, repositories, API clients.\n *\n * Returns `undefined` outside a request context (e.g., startup code, background tasks).\n */\nexport function getRequestLogger(): CelerityLogger | undefined {\n return requestStore.getStore()?.logger;\n}\n\n/**\n * Context-aware logger proxy registered under LOGGER_TOKEN.\n *\n * Delegates to the request-scoped logger (via AsyncLocalStorage) when inside\n * a request context, falls back to the root logger otherwise.\n *\n * This means `@Inject(LOGGER_TOKEN)` automatically resolves to the most\n * appropriate logger for the current context — no manual wiring needed.\n */\nexport class ContextAwareLogger implements CelerityLogger {\n constructor(private rootLogger: CelerityLogger) {}\n\n private get current(): CelerityLogger {\n return getRequestLogger() ?? this.rootLogger;\n }\n\n debug(message: string, attributes?: Record<string, unknown>): void {\n this.current.debug(message, attributes);\n }\n\n info(message: string, attributes?: Record<string, unknown>): void {\n this.current.info(message, attributes);\n }\n\n warn(message: string, attributes?: Record<string, unknown>): void {\n this.current.warn(message, attributes);\n }\n\n error(message: string, attributes?: Record<string, unknown>): void {\n this.current.error(message, attributes);\n }\n\n child(name: string, attributes?: Record<string, unknown>): CelerityLogger {\n return this.current.child(name, attributes);\n }\n\n withContext(attributes: Record<string, unknown>): CelerityLogger {\n return this.current.withContext(attributes);\n }\n}\n","import { propagation, ROOT_CONTEXT, type Context } from \"@opentelemetry/api\";\nimport type { HttpRequest } from \"@celerity-sdk/types\";\n\nexport function extractTraceContext(request: HttpRequest): Context {\n if (!request.traceContext) return ROOT_CONTEXT;\n\n // The traceContext map is used directly as a carrier.\n // The composite propagator (W3C + X-Ray) extracts the appropriate context.\n return propagation.extract(ROOT_CONTEXT, request.traceContext);\n}\n","import {\n trace,\n context as otelContext,\n SpanStatusCode,\n type Span,\n type Attributes,\n} from \"@opentelemetry/api\";\nimport type { CelerityTracer, CeleritySpan } from \"@celerity-sdk/types\";\n\nexport class OTelTracer implements CelerityTracer {\n private tracer = trace.getTracer(\"celerity\");\n\n startSpan(name: string, attributes?: Record<string, unknown>): CeleritySpan {\n const span = this.tracer.startSpan(name, {\n attributes: attributes as Attributes,\n });\n return new OTelSpan(span);\n }\n\n async withSpan<T>(\n name: string,\n fn: (span: CeleritySpan) => T | Promise<T>,\n attributes?: Record<string, unknown>,\n ): Promise<T> {\n const span = this.tracer.startSpan(name, {\n attributes: attributes as Attributes,\n });\n const ctx = trace.setSpan(otelContext.active(), span);\n\n return otelContext.with(ctx, async () => {\n const wrapped = new OTelSpan(span);\n try {\n const result = await fn(wrapped);\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) span.recordException(error);\n throw error;\n } finally {\n span.end();\n }\n });\n }\n}\n\nexport class OTelSpan implements CeleritySpan {\n constructor(private span: Span) {}\n\n setAttribute(key: string, value: string | number | boolean): void {\n this.span.setAttribute(key, value);\n }\n\n setAttributes(attributes: Record<string, string | number | boolean>): void {\n this.span.setAttributes(attributes);\n }\n\n recordError(error: Error): void {\n this.span.recordException(error);\n this.span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n }\n\n setOk(): void {\n this.span.setStatus({ code: SpanStatusCode.OK });\n }\n\n end(): void {\n this.span.end();\n }\n}\n","import type { CelerityTracer, CeleritySpan } from \"@celerity-sdk/types\";\n\nexport class NoopTracer implements CelerityTracer {\n startSpan(): CeleritySpan {\n return NOOP_SPAN;\n }\n\n async withSpan<T>(_name: string, fn: (span: CeleritySpan) => T | Promise<T>): Promise<T> {\n return fn(NOOP_SPAN);\n }\n}\n\nexport const NOOP_SPAN: CeleritySpan = {\n setAttribute() {},\n setAttributes() {},\n recordError() {},\n setOk() {},\n end() {},\n};\n","export const LOGGER_TOKEN = \"CelerityLogger\";\nexport const TRACER_TOKEN = \"CelerityTracer\";\n","export { TelemetryLayer } from \"./telemetry-layer\";\nexport { extractUserId } from \"@celerity-sdk/common\";\nexport { CelerityLoggerImpl, createLogger } from \"./logger\";\nexport { ContextAwareLogger, getRequestLogger } from \"./request-context\";\nexport { OTelTracer, OTelSpan } from \"./tracer\";\nexport { NoopTracer, NOOP_SPAN } from \"./noop\";\nexport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\nexport { extractTraceContext } from \"./context\";\nexport { getLogger, getTracer } from \"./helpers\";\nexport { readTelemetryEnv } from \"./env\";\nexport type { TelemetryConfig } from \"./env\";\n","import type { CelerityLogger, CelerityTracer, ServiceContainer } from \"@celerity-sdk/types\";\nimport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\n\nexport async function getLogger(container: ServiceContainer): Promise<CelerityLogger> {\n return container.resolve<CelerityLogger>(LOGGER_TOKEN);\n}\n\nexport async function getTracer(container: ServiceContainer): Promise<CelerityTracer> {\n return container.resolve<CelerityTracer>(TRACER_TOKEN);\n}\n"],"mappings":"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","names":["createDebug","context","otelContext","extractUserId","VALID_LOG_LEVELS","Set","VALID_LOG_FORMATS","readTelemetryEnv","rawLevel","process","env","CELERITY_LOG_LEVEL","rawFormat","CELERITY_LOG_FORMAT","tracingEnabled","CELERITY_TELEMETRY_ENABLED","otlpEndpoint","OTEL_EXPORTER_OTLP_ENDPOINT","CELERITY_TRACE_OTLP_COLLECTOR_ENDPOINT","serviceName","OTEL_SERVICE_NAME","serviceVersion","OTEL_SERVICE_VERSION","logLevel","has","logFormat","logFilePath","CELERITY_LOG_FILE_PATH","createDebug","NodeSDK","resourceFromAttributes","ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","OTLPTraceExporter","OTLPLogExporter","BatchLogRecordProcessor","CompositePropagator","W3CTraceContextPropagator","AWSXRayPropagator","AWSXRayIdGenerator","createDebug","HttpInstrumentation","UndiciInstrumentation","debug","createDebug","buildInstrumentations","instrumentations","HttpInstrumentation","UndiciInstrumentation","optionalPackages","name","pkg","mod","InstrumentationClass","findInstrumentationExport","push","err","code","value","Object","values","prototype","debug","createDebug","initialized","sdk","initTelemetry","initialized","debug","config","readTelemetryEnv","tracingEnabled","platform","process","env","CELERITY_PLATFORM","isAws","otlpEndpoint","serviceName","instrumentations","buildInstrumentations","sdk","NodeSDK","resource","resourceFromAttributes","ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","serviceVersion","traceExporter","OTLPTraceExporter","url","logRecordProcessors","BatchLogRecordProcessor","OTLPLogExporter","textMapPropagator","CompositePropagator","propagators","W3CTraceContextPropagator","AWSXRayPropagator","idGenerator","AWSXRayIdGenerator","start","shutdownTelemetry","shutdown","pino","Writable","logs","SeverityNumber","LEVEL_MAP","SeverityNumber","TRACE","DEBUG","INFO","WARN","ERROR","FATAL","createOTelStream","otelLogger","logs","getLogger","Writable","write","chunk","_encoding","callback","obj","JSON","parse","toString","level","msg","name","rest","time","attributes","key","val","Object","entries","emit","severityNumber","body","CelerityLoggerImpl","pinoLogger","debug","message","attributes","log","info","warn","error","level","fn","bind","child","name","withContext","setLevel","createLogger","config","streams","isLocal","process","env","CELERITY_PLATFORM","useHumanFormat","logFormat","push","logLevel","stream","pino","transport","target","options","destination","logFilePath","tracingEnabled","createOTelStream","redactPaths","resolveRedactPaths","logger","redact","length","paths","censor","undefined","timestamp","stdTimeFunctions","isoTime","multistream","keys","CELERITY_LOG_REDACT_KEYS","split","map","k","trim","AsyncLocalStorage","requestStore","AsyncLocalStorage","getRequestLogger","getStore","logger","ContextAwareLogger","rootLogger","current","debug","message","attributes","info","warn","error","child","name","withContext","propagation","ROOT_CONTEXT","extractTraceContext","request","traceContext","ROOT_CONTEXT","propagation","extract","trace","context","otelContext","SpanStatusCode","OTelTracer","tracer","trace","getTracer","startSpan","name","attributes","span","OTelSpan","withSpan","fn","ctx","setSpan","otelContext","active","with","wrapped","result","setStatus","code","SpanStatusCode","OK","error","ERROR","Error","recordException","end","setAttribute","key","value","setAttributes","recordError","message","setOk","NoopTracer","startSpan","NOOP_SPAN","withSpan","_name","fn","setAttribute","setAttributes","recordError","setOk","end","LOGGER_TOKEN","TRACER_TOKEN","debugLog","createDebug","LOG_LEVEL_CONFIG_KEYS","VALID_LOG_LEVELS","Set","TelemetryLayer","config","rootLogger","currentLevel","initPromise","readTelemetryEnv","logLevel","tracingEnabled","initTelemetry","handle","context","next","logFormat","createLogger","container","register","LOGGER_TOKEN","useValue","ContextAwareLogger","TRACER_TOKEN","OTelTracer","NoopTracer","refreshLogLevelFromConfig","userId","extractUserId","request","auth","requestLogger","child","requestId","method","path","matchedRoute","clientIp","userAgent","logger","runWithLogger","requestStore","run","parentContext","extractTraceContext","otelContext","with","dispose","shutdownTelemetry","has","configService","resolve","key","value","get","setLevel","extractUserId","getLogger","container","resolve","LOGGER_TOKEN","getTracer","TRACER_TOKEN"]}
|
|
1
|
+
{"version":3,"sources":["../src/telemetry-layer.ts","../src/env.ts","../src/init.ts","../src/instrumentations.ts","../src/logger.ts","../src/otel-transport.ts","../src/request-context.ts","../src/tracer.ts","../src/noop.ts","../src/tokens.ts","../src/index.ts","../src/context.ts","../src/helpers.ts"],"sourcesContent":["import createDebug from \"debug\";\nimport { context as otelContext, propagation, ROOT_CONTEXT } from \"@opentelemetry/api\";\nimport type {\n CelerityLayer,\n BaseHandlerContext,\n HttpHandlerContext,\n ConsumerHandlerContext,\n LogLevel,\n ServiceContainer,\n} from \"@celerity-sdk/types\";\nimport { extractUserId } from \"@celerity-sdk/common\";\nimport { readTelemetryEnv, type TelemetryConfig } from \"./env\";\nimport { initTelemetry, shutdownTelemetry } from \"./init\";\nimport { CelerityLoggerImpl, createLogger } from \"./logger\";\nimport { ContextAwareLogger, requestStore } from \"./request-context\";\nimport { OTelTracer } from \"./tracer\";\nimport { NoopTracer } from \"./noop\";\nimport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\n\nconst debugLog = createDebug(\"celerity:telemetry\");\n\nfunction isHttpContext(context: BaseHandlerContext): context is HttpHandlerContext {\n return \"request\" in context && typeof (context as HttpHandlerContext).request === \"object\";\n}\n\nfunction isConsumerContext(context: BaseHandlerContext): context is ConsumerHandlerContext {\n return (\n \"event\" in context &&\n typeof (context as ConsumerHandlerContext).event === \"object\" &&\n \"messages\" in ((context as ConsumerHandlerContext).event ?? {})\n );\n}\n\nconst LOG_LEVEL_CONFIG_KEYS = [\n \"CELERITY_LOG_LEVEL\",\n \"celerityLogLevel\",\n \"celerity_log_level\",\n \"CelerityLogLevel\",\n];\n\nconst VALID_LOG_LEVELS = new Set<string>([\"debug\", \"info\", \"warn\", \"error\"]);\n\ntype ConfigService = {\n get(key: string): Promise<string | undefined>;\n};\n\nexport class TelemetryLayer implements CelerityLayer<BaseHandlerContext> {\n private config: TelemetryConfig;\n private rootLogger: CelerityLoggerImpl | null = null;\n private currentLevel: LogLevel;\n private initPromise: Promise<void> | null = null;\n\n constructor() {\n this.config = readTelemetryEnv();\n this.currentLevel = this.config.logLevel;\n\n if (this.config.tracingEnabled) {\n this.initPromise = initTelemetry();\n }\n }\n\n async handle(context: BaseHandlerContext, next: () => Promise<unknown>): Promise<unknown> {\n if (this.initPromise) {\n await this.initPromise;\n this.initPromise = null;\n }\n\n if (!this.rootLogger) {\n debugLog(\n \"creating root logger (format=%s, level=%s)\",\n this.config.logFormat,\n this.config.logLevel,\n );\n this.rootLogger = await createLogger(this.config);\n context.container.register(LOGGER_TOKEN, {\n useValue: new ContextAwareLogger(this.rootLogger),\n });\n context.container.register(TRACER_TOKEN, {\n useValue: this.config.tracingEnabled ? new OTelTracer() : new NoopTracer(),\n });\n debugLog(\"registered logger and tracer (tracing=%s)\", this.config.tracingEnabled);\n }\n\n await this.refreshLogLevelFromConfig(context.container);\n\n const handlerName = context.metadata.get(\"handlerName\") as string | undefined;\n let handlerLogger;\n let traceCarrier: Record<string, string> | undefined;\n\n if (isHttpContext(context)) {\n const userId = extractUserId(context.request.auth);\n handlerLogger = this.rootLogger.child(\"request\", {\n ...(handlerName ? { handlerName } : {}),\n requestId: context.request.requestId,\n method: context.request.method,\n path: context.request.path,\n matchedRoute: context.request.matchedRoute,\n clientIp: context.request.clientIp,\n userAgent: context.request.userAgent,\n ...(userId ? { userId } : {}),\n });\n traceCarrier = context.request.traceContext ?? undefined;\n } else if (isConsumerContext(context)) {\n const { messages } = context.event;\n const first = messages[0];\n const sourceMessageId = first?.messageAttributes?.sourceMessageId?.stringValue;\n handlerLogger = this.rootLogger.child(\"consumer\", {\n ...(handlerName ? { handlerName } : {}),\n source: first?.source,\n messageCount: messages.length,\n ...(sourceMessageId ? { sourceMessageId } : {}),\n });\n traceCarrier = context.event.traceContext ?? undefined;\n } else {\n handlerLogger = this.rootLogger.child(\"handler\", {\n ...(handlerName ? { handlerName } : {}),\n });\n }\n\n context.logger = handlerLogger;\n\n const runWithLogger = () => requestStore.run({ logger: handlerLogger }, () => next());\n\n if (!this.config.tracingEnabled) return runWithLogger();\n\n if (traceCarrier) {\n const parentContext = propagation.extract(ROOT_CONTEXT, traceCarrier);\n return otelContext.with(parentContext, runWithLogger);\n }\n\n return runWithLogger();\n }\n\n async dispose(): Promise<void> {\n if (this.config.tracingEnabled) await shutdownTelemetry();\n }\n\n private async refreshLogLevelFromConfig(container: ServiceContainer): Promise<void> {\n if (!container.has(\"ConfigService\")) return;\n\n try {\n const configService = await container.resolve<ConfigService>(\"ConfigService\");\n for (const key of LOG_LEVEL_CONFIG_KEYS) {\n const value = await configService.get(key);\n if (value && VALID_LOG_LEVELS.has(value) && value !== this.currentLevel) {\n debugLog(\"log level changed %s → %s\", this.currentLevel, value);\n this.rootLogger?.setLevel(value as LogLevel);\n this.currentLevel = value as LogLevel;\n return;\n }\n }\n } catch {\n // Config resolution failed — keep current level\n }\n }\n}\n","import type { LogLevel } from \"@celerity-sdk/types\";\n\nexport type TelemetryConfig = {\n tracingEnabled: boolean;\n otlpEndpoint: string;\n serviceName: string;\n serviceVersion: string;\n logLevel: LogLevel;\n logFormat: \"json\" | \"human\" | \"auto\";\n logFilePath: string | null;\n};\n\nconst VALID_LOG_LEVELS = new Set<string>([\"debug\", \"info\", \"warn\", \"error\"]);\nconst VALID_LOG_FORMATS = new Set<string>([\"json\", \"human\", \"auto\"]);\n\nexport function readTelemetryEnv(): TelemetryConfig {\n const rawLevel = process.env.CELERITY_LOG_LEVEL;\n const rawFormat = process.env.CELERITY_LOG_FORMAT;\n\n return {\n tracingEnabled: process.env.CELERITY_TELEMETRY_ENABLED === \"true\",\n otlpEndpoint:\n process.env.OTEL_EXPORTER_OTLP_ENDPOINT ??\n process.env.CELERITY_TRACE_OTLP_COLLECTOR_ENDPOINT ??\n \"http://otelcollector:4317\",\n serviceName: process.env.OTEL_SERVICE_NAME ?? \"celerity-app\",\n serviceVersion: process.env.OTEL_SERVICE_VERSION ?? \"0.0.0\",\n logLevel: rawLevel && VALID_LOG_LEVELS.has(rawLevel) ? (rawLevel as LogLevel) : \"info\",\n logFormat:\n rawFormat && VALID_LOG_FORMATS.has(rawFormat)\n ? (rawFormat as \"json\" | \"human\" | \"auto\")\n : \"auto\",\n logFilePath: process.env.CELERITY_LOG_FILE_PATH ?? null,\n };\n}\n","import createDebug from \"debug\";\nimport { NodeSDK } from \"@opentelemetry/sdk-node\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from \"@opentelemetry/semantic-conventions\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-grpc\";\nimport { OTLPLogExporter } from \"@opentelemetry/exporter-logs-otlp-grpc\";\nimport { BatchLogRecordProcessor } from \"@opentelemetry/sdk-logs\";\nimport { CompositePropagator, W3CTraceContextPropagator } from \"@opentelemetry/core\";\nimport { AWSXRayPropagator } from \"@opentelemetry/propagator-aws-xray\";\nimport { AWSXRayIdGenerator } from \"@opentelemetry/id-generator-aws-xray\";\nimport { readTelemetryEnv } from \"./env\";\nimport { buildInstrumentations } from \"./instrumentations\";\n\nconst debug = createDebug(\"celerity:telemetry\");\n\nlet initialized = false;\nlet sdk: NodeSDK | null = null;\n\nexport function isInitialized(): boolean {\n return initialized;\n}\n\nexport async function initTelemetry(): Promise<void> {\n if (initialized) {\n debug(\"initTelemetry: already initialized, skipping\");\n return;\n }\n\n const config = readTelemetryEnv();\n if (!config.tracingEnabled) {\n debug(\"initTelemetry: tracing disabled, skipping\");\n return;\n }\n\n const platform = process.env.CELERITY_PLATFORM ?? \"local\";\n const isAws = platform === \"aws\";\n debug(\n \"initTelemetry: platform=%s endpoint=%s service=%s\",\n platform,\n config.otlpEndpoint,\n config.serviceName,\n );\n\n const instrumentations = await buildInstrumentations();\n\n sdk = new NodeSDK({\n resource: resourceFromAttributes({\n [ATTR_SERVICE_NAME]: config.serviceName,\n [ATTR_SERVICE_VERSION]: config.serviceVersion,\n }),\n traceExporter: new OTLPTraceExporter({ url: config.otlpEndpoint }),\n logRecordProcessors: [\n new BatchLogRecordProcessor(new OTLPLogExporter({ url: config.otlpEndpoint })),\n ],\n textMapPropagator: new CompositePropagator({\n propagators: [new W3CTraceContextPropagator(), new AWSXRayPropagator()],\n }),\n ...(isAws ? { idGenerator: new AWSXRayIdGenerator() } : {}),\n instrumentations,\n });\n\n sdk.start();\n initialized = true;\n debug(\"initTelemetry: SDK started\");\n}\n\nexport async function shutdownTelemetry(): Promise<void> {\n if (sdk) {\n debug(\"shutdownTelemetry: shutting down SDK\");\n await sdk.shutdown();\n sdk = null;\n initialized = false;\n }\n}\n","import createDebug from \"debug\";\nimport { HttpInstrumentation } from \"@opentelemetry/instrumentation-http\";\nimport { UndiciInstrumentation } from \"@opentelemetry/instrumentation-undici\";\nimport type { Instrumentation } from \"@opentelemetry/instrumentation\";\n\nconst debug = createDebug(\"celerity:telemetry\");\n\nexport async function buildInstrumentations(): Promise<Instrumentation[]> {\n // Core instrumentation: always active — covers all HTTP/HTTPS and fetch() calls\n const instrumentations: Instrumentation[] = [\n new HttpInstrumentation() as Instrumentation,\n new UndiciInstrumentation() as Instrumentation,\n ];\n\n // Dynamically load optional instrumentation packages.\n // Each targets a specific library and silently no-ops if the library isn't installed.\n const optionalPackages = [\n \"@opentelemetry/instrumentation-aws-sdk\",\n \"@opentelemetry/instrumentation-ioredis\",\n \"@opentelemetry/instrumentation-pg\",\n \"@opentelemetry/instrumentation-mysql2\",\n ];\n\n for (const name of optionalPackages) {\n try {\n const pkg = name;\n const mod = (await import(pkg)) as Record<string, unknown>;\n const InstrumentationClass = findInstrumentationExport(mod);\n if (InstrumentationClass) {\n debug(\"instrumentation: loaded %s\", name);\n instrumentations.push(new InstrumentationClass() as Instrumentation);\n }\n } catch (err) {\n const code = (err as { code?: string }).code;\n if (code !== \"ERR_MODULE_NOT_FOUND\" && code !== \"MODULE_NOT_FOUND\") {\n debug(\"instrumentation: failed to load %s: %O\", name, err);\n }\n }\n }\n\n return instrumentations;\n}\n\nfunction findInstrumentationExport(mod: Record<string, unknown>): (new () => unknown) | null {\n for (const value of Object.values(mod)) {\n if (typeof value === \"function\" && value.prototype && \"enable\" in value.prototype) {\n return value as new () => unknown;\n }\n }\n return null;\n}\n","import pino from \"pino\";\nimport type { CelerityLogger, LogLevel } from \"@celerity-sdk/types\";\nimport type { TelemetryConfig } from \"./env\";\nimport { createOTelStream } from \"./otel-transport\";\n\n/**\n * Thin pino wrapper implementing CelerityLogger.\n * Every method delegates directly to the underlying pino instance.\n */\nexport class CelerityLoggerImpl implements CelerityLogger {\n constructor(private pinoLogger: pino.Logger) {}\n\n debug(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"debug\", message, attributes);\n }\n\n info(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"info\", message, attributes);\n }\n\n warn(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"warn\", message, attributes);\n }\n\n error(message: string, attributes?: Record<string, unknown>): void {\n this.log(\"error\", message, attributes);\n }\n\n private log(level: LogLevel, message: string, attributes?: Record<string, unknown>): void {\n const fn = this.pinoLogger[level].bind(this.pinoLogger);\n if (attributes) fn(attributes, message);\n else fn(message);\n }\n\n child(name: string, attributes?: Record<string, unknown>): CelerityLogger {\n return new CelerityLoggerImpl(this.pinoLogger.child({ name, ...attributes }));\n }\n\n withContext(attributes: Record<string, unknown>): CelerityLogger {\n return new CelerityLoggerImpl(this.pinoLogger.child(attributes));\n }\n\n /** Update the log level at runtime. Internal — used by TelemetryLayer for dynamic config. */\n setLevel(level: LogLevel): void {\n this.pinoLogger.level = level;\n }\n}\n\nexport async function createLogger(config: TelemetryConfig): Promise<CelerityLoggerImpl> {\n const streams: pino.StreamEntry[] = [];\n\n const isLocal = !process.env.CELERITY_PLATFORM || process.env.CELERITY_PLATFORM === \"local\";\n const useHumanFormat = config.logFormat === \"human\" || (config.logFormat === \"auto\" && isLocal);\n\n if (useHumanFormat) {\n // pino-pretty in main thread for consistent output ordering with core runtime logs\n const pinoPrettyPkg = \"pino-pretty\";\n const { default: pinoPretty } = (await import(pinoPrettyPkg)) as {\n default: (opts: Record<string, unknown>) => NodeJS.WritableStream;\n };\n streams.push({\n level: config.logLevel,\n stream: pinoPretty({ destination: 1, translateTime: \"SYS:standard\" }),\n });\n } else {\n // Raw JSON to stdout — synchronous, Lambda-safe\n streams.push({ level: config.logLevel, stream: pino.destination(1) });\n }\n\n // File stream — if configured (synchronous SonicBoom destination)\n if (config.logFilePath) {\n streams.push({\n level: config.logLevel,\n stream: pino.destination(config.logFilePath),\n });\n }\n\n // OTel log stream — main-thread writable (NOT worker-thread transport).\n // Runs in main thread so it can read active OTel context (traceId/spanId)\n // and is safe for Lambda (no worker thread flush issues).\n if (config.tracingEnabled) {\n streams.push({\n level: config.logLevel,\n stream: createOTelStream(),\n });\n }\n\n const redactPaths = resolveRedactPaths();\n\n const logger = pino(\n {\n level: config.logLevel,\n redact: redactPaths.length > 0 ? { paths: redactPaths, censor: \"[REDACTED]\" } : undefined,\n timestamp: pino.stdTimeFunctions.isoTime,\n },\n pino.multistream(streams),\n );\n\n return new CelerityLoggerImpl(logger);\n}\n\nfunction resolveRedactPaths(): string[] {\n const keys = process.env.CELERITY_LOG_REDACT_KEYS;\n if (!keys) return [];\n return keys.split(\",\").map((k) => k.trim());\n}\n","import { Writable } from \"node:stream\";\nimport { logs, SeverityNumber } from \"@opentelemetry/api-logs\";\n\nconst LEVEL_MAP: Record<number, SeverityNumber> = {\n 10: SeverityNumber.TRACE,\n 20: SeverityNumber.DEBUG,\n 30: SeverityNumber.INFO,\n 40: SeverityNumber.WARN,\n 50: SeverityNumber.ERROR,\n 60: SeverityNumber.FATAL,\n};\n\n/**\n * Creates a main-thread writable stream that bridges pino log records\n * to the OTel Logs API.\n *\n * Runs in the main thread (NOT a pino worker-thread transport) so it can:\n * 1. Read traceId/spanId from the active OTel context (trace correlation)\n * 2. Flush reliably in Lambda (no worker thread lifecycle issues)\n */\nexport function createOTelStream(): Writable {\n const otelLogger = logs.getLogger(\"celerity\");\n\n return new Writable({\n write(chunk: Buffer | string, _encoding, callback) {\n try {\n const obj = JSON.parse(typeof chunk === \"string\" ? chunk : chunk.toString()) as Record<\n string,\n unknown\n >;\n const { level, msg, name, ...rest } = obj;\n delete rest.time;\n const attributes: Record<string, string | number | boolean> = {};\n if (typeof name === \"string\") attributes[\"logger.name\"] = name;\n for (const [key, val] of Object.entries(rest)) {\n if (typeof val === \"string\" || typeof val === \"number\" || typeof val === \"boolean\") {\n attributes[key] = val;\n }\n }\n otelLogger.emit({\n severityNumber: LEVEL_MAP[level as number] ?? SeverityNumber.INFO,\n body: msg as string,\n attributes,\n });\n } catch {\n // Malformed JSON — skip\n }\n callback();\n },\n });\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { CelerityLogger } from \"@celerity-sdk/types\";\n\ntype RequestStore = {\n logger: CelerityLogger;\n};\n\nexport const requestStore = new AsyncLocalStorage<RequestStore>();\n\n/**\n * Get the request-scoped logger from the current async context.\n *\n * Works anywhere in the async call chain during request handling —\n * handlers, services, repositories, API clients.\n *\n * Returns `undefined` outside a request context (e.g., startup code, background tasks).\n */\nexport function getRequestLogger(): CelerityLogger | undefined {\n return requestStore.getStore()?.logger;\n}\n\n/**\n * Context-aware logger proxy registered under LOGGER_TOKEN.\n *\n * Delegates to the request-scoped logger (via AsyncLocalStorage) when inside\n * a request context, falls back to the root logger otherwise.\n *\n * This means `@Inject(LOGGER_TOKEN)` automatically resolves to the most\n * appropriate logger for the current context — no manual wiring needed.\n */\nexport class ContextAwareLogger implements CelerityLogger {\n constructor(private rootLogger: CelerityLogger) {}\n\n private get current(): CelerityLogger {\n return getRequestLogger() ?? this.rootLogger;\n }\n\n debug(message: string, attributes?: Record<string, unknown>): void {\n this.current.debug(message, attributes);\n }\n\n info(message: string, attributes?: Record<string, unknown>): void {\n this.current.info(message, attributes);\n }\n\n warn(message: string, attributes?: Record<string, unknown>): void {\n this.current.warn(message, attributes);\n }\n\n error(message: string, attributes?: Record<string, unknown>): void {\n this.current.error(message, attributes);\n }\n\n child(name: string, attributes?: Record<string, unknown>): CelerityLogger {\n return this.current.child(name, attributes);\n }\n\n withContext(attributes: Record<string, unknown>): CelerityLogger {\n return this.current.withContext(attributes);\n }\n}\n","import {\n trace,\n context as otelContext,\n SpanStatusCode,\n type Span,\n type Attributes,\n} from \"@opentelemetry/api\";\nimport type { CelerityTracer, CeleritySpan } from \"@celerity-sdk/types\";\n\nexport class OTelTracer implements CelerityTracer {\n private tracer = trace.getTracer(\"celerity\");\n\n startSpan(name: string, attributes?: Record<string, unknown>): CeleritySpan {\n const span = this.tracer.startSpan(name, {\n attributes: attributes as Attributes,\n });\n return new OTelSpan(span);\n }\n\n async withSpan<T>(\n name: string,\n fn: (span: CeleritySpan) => T | Promise<T>,\n attributes?: Record<string, unknown>,\n ): Promise<T> {\n const span = this.tracer.startSpan(name, {\n attributes: attributes as Attributes,\n });\n const ctx = trace.setSpan(otelContext.active(), span);\n\n return otelContext.with(ctx, async () => {\n const wrapped = new OTelSpan(span);\n try {\n const result = await fn(wrapped);\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) span.recordException(error);\n throw error;\n } finally {\n span.end();\n }\n });\n }\n}\n\nexport class OTelSpan implements CeleritySpan {\n constructor(private span: Span) {}\n\n setAttribute(key: string, value: string | number | boolean): void {\n this.span.setAttribute(key, value);\n }\n\n setAttributes(attributes: Record<string, string | number | boolean>): void {\n this.span.setAttributes(attributes);\n }\n\n recordError(error: Error): void {\n this.span.recordException(error);\n this.span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n }\n\n setOk(): void {\n this.span.setStatus({ code: SpanStatusCode.OK });\n }\n\n end(): void {\n this.span.end();\n }\n}\n","import type { CelerityTracer, CeleritySpan } from \"@celerity-sdk/types\";\n\nexport class NoopTracer implements CelerityTracer {\n startSpan(): CeleritySpan {\n return NOOP_SPAN;\n }\n\n async withSpan<T>(_name: string, fn: (span: CeleritySpan) => T | Promise<T>): Promise<T> {\n return fn(NOOP_SPAN);\n }\n}\n\nexport const NOOP_SPAN: CeleritySpan = {\n setAttribute() {},\n setAttributes() {},\n recordError() {},\n setOk() {},\n end() {},\n};\n","export { LOGGER_TOKEN, TRACER_TOKEN } from \"@celerity-sdk/common\";\n","export { TelemetryLayer } from \"./telemetry-layer\";\nexport { extractUserId } from \"@celerity-sdk/common\";\nexport { CelerityLoggerImpl, createLogger } from \"./logger\";\nexport { ContextAwareLogger, getRequestLogger } from \"./request-context\";\nexport { OTelTracer, OTelSpan } from \"./tracer\";\nexport { NoopTracer, NOOP_SPAN } from \"./noop\";\nexport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\nexport { extractTraceContext } from \"./context\";\nexport { getLogger, getTracer } from \"./helpers\";\nexport { readTelemetryEnv } from \"./env\";\nexport type { TelemetryConfig } from \"./env\";\n","import { propagation, ROOT_CONTEXT, type Context } from \"@opentelemetry/api\";\nimport type { HttpRequest } from \"@celerity-sdk/types\";\n\nexport function extractTraceContext(request: HttpRequest): Context {\n if (!request.traceContext) return ROOT_CONTEXT;\n\n // The traceContext map is used directly as a carrier.\n // The composite propagator (W3C + X-Ray) extracts the appropriate context.\n return propagation.extract(ROOT_CONTEXT, request.traceContext);\n}\n","import type { CelerityLogger, CelerityTracer, ServiceContainer } from \"@celerity-sdk/types\";\nimport { LOGGER_TOKEN, TRACER_TOKEN } from \"./tokens\";\n\nexport async function getLogger(container: ServiceContainer): Promise<CelerityLogger> {\n return container.resolve<CelerityLogger>(LOGGER_TOKEN);\n}\n\nexport async function getTracer(container: ServiceContainer): Promise<CelerityTracer> {\n return container.resolve<CelerityTracer>(TRACER_TOKEN);\n}\n"],"mappings":"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","names":["createDebug","context","otelContext","propagation","ROOT_CONTEXT","extractUserId","VALID_LOG_LEVELS","Set","VALID_LOG_FORMATS","readTelemetryEnv","rawLevel","process","env","CELERITY_LOG_LEVEL","rawFormat","CELERITY_LOG_FORMAT","tracingEnabled","CELERITY_TELEMETRY_ENABLED","otlpEndpoint","OTEL_EXPORTER_OTLP_ENDPOINT","CELERITY_TRACE_OTLP_COLLECTOR_ENDPOINT","serviceName","OTEL_SERVICE_NAME","serviceVersion","OTEL_SERVICE_VERSION","logLevel","has","logFormat","logFilePath","CELERITY_LOG_FILE_PATH","createDebug","NodeSDK","resourceFromAttributes","ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","OTLPTraceExporter","OTLPLogExporter","BatchLogRecordProcessor","CompositePropagator","W3CTraceContextPropagator","AWSXRayPropagator","AWSXRayIdGenerator","createDebug","HttpInstrumentation","UndiciInstrumentation","debug","createDebug","buildInstrumentations","instrumentations","HttpInstrumentation","UndiciInstrumentation","optionalPackages","name","pkg","mod","InstrumentationClass","findInstrumentationExport","push","err","code","value","Object","values","prototype","debug","createDebug","initialized","sdk","initTelemetry","initialized","debug","config","readTelemetryEnv","tracingEnabled","platform","process","env","CELERITY_PLATFORM","isAws","otlpEndpoint","serviceName","instrumentations","buildInstrumentations","sdk","NodeSDK","resource","resourceFromAttributes","ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","serviceVersion","traceExporter","OTLPTraceExporter","url","logRecordProcessors","BatchLogRecordProcessor","OTLPLogExporter","textMapPropagator","CompositePropagator","propagators","W3CTraceContextPropagator","AWSXRayPropagator","idGenerator","AWSXRayIdGenerator","start","shutdownTelemetry","shutdown","pino","Writable","logs","SeverityNumber","LEVEL_MAP","SeverityNumber","TRACE","DEBUG","INFO","WARN","ERROR","FATAL","createOTelStream","otelLogger","logs","getLogger","Writable","write","chunk","_encoding","callback","obj","JSON","parse","toString","level","msg","name","rest","time","attributes","key","val","Object","entries","emit","severityNumber","body","CelerityLoggerImpl","pinoLogger","debug","message","attributes","log","info","warn","error","level","fn","bind","child","name","withContext","setLevel","createLogger","config","streams","isLocal","process","env","CELERITY_PLATFORM","useHumanFormat","logFormat","pinoPrettyPkg","default","pinoPretty","push","logLevel","stream","destination","translateTime","pino","logFilePath","tracingEnabled","createOTelStream","redactPaths","resolveRedactPaths","logger","redact","length","paths","censor","undefined","timestamp","stdTimeFunctions","isoTime","multistream","keys","CELERITY_LOG_REDACT_KEYS","split","map","k","trim","AsyncLocalStorage","requestStore","AsyncLocalStorage","getRequestLogger","getStore","logger","ContextAwareLogger","rootLogger","current","debug","message","attributes","info","warn","error","child","name","withContext","trace","context","otelContext","SpanStatusCode","OTelTracer","tracer","trace","getTracer","startSpan","name","attributes","span","OTelSpan","withSpan","fn","ctx","setSpan","otelContext","active","with","wrapped","result","setStatus","code","SpanStatusCode","OK","error","ERROR","Error","recordException","end","setAttribute","key","value","setAttributes","recordError","message","setOk","NoopTracer","startSpan","NOOP_SPAN","withSpan","_name","fn","setAttribute","setAttributes","recordError","setOk","end","LOGGER_TOKEN","TRACER_TOKEN","debugLog","createDebug","isHttpContext","context","request","isConsumerContext","event","LOG_LEVEL_CONFIG_KEYS","VALID_LOG_LEVELS","Set","TelemetryLayer","config","rootLogger","currentLevel","initPromise","readTelemetryEnv","logLevel","tracingEnabled","initTelemetry","handle","next","logFormat","createLogger","container","register","LOGGER_TOKEN","useValue","ContextAwareLogger","TRACER_TOKEN","OTelTracer","NoopTracer","refreshLogLevelFromConfig","handlerName","metadata","get","handlerLogger","traceCarrier","userId","extractUserId","auth","child","requestId","method","path","matchedRoute","clientIp","userAgent","traceContext","undefined","messages","first","sourceMessageId","messageAttributes","stringValue","source","messageCount","length","logger","runWithLogger","requestStore","run","parentContext","propagation","extract","ROOT_CONTEXT","otelContext","with","dispose","shutdownTelemetry","has","configService","resolve","key","value","setLevel","extractUserId","propagation","ROOT_CONTEXT","extractTraceContext","request","traceContext","ROOT_CONTEXT","propagation","extract","getLogger","container","resolve","LOGGER_TOKEN","getTracer","TRACER_TOKEN"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@celerity-sdk/telemetry",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Observability layer for the Celerity Node SDK — pino-based logger and OTel-based tracing",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"@opentelemetry/instrumentation": "^0.200.0",
|
|
52
52
|
"@opentelemetry/instrumentation-http": "^0.200.0",
|
|
53
53
|
"@opentelemetry/instrumentation-undici": "^0.14.0",
|
|
54
|
-
"@celerity-sdk/common": "^0.
|
|
55
|
-
"@celerity-sdk/types": "^0.
|
|
54
|
+
"@celerity-sdk/common": "^0.5.0",
|
|
55
|
+
"@celerity-sdk/types": "^0.5.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"pino-pretty": "^13.0.0"
|