@eventuras/logger 0.8.1 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,25 @@
1
- import { t as Logger } from "./Logger-n-HsscG5.js";
1
+ import { i as setLogLineSink, r as PinoTransport, t as Logger } from "./Logger-B22dX10w.js";
2
+ import { logs } from "@opentelemetry/api-logs";
2
3
  //#region src/opentelemetry.ts
3
4
  /**
4
5
  * OpenTelemetry integration for @eventuras/logger
5
6
  *
6
- * This module provides integration between Pino and OpenTelemetry Logs API.
7
- * It allows sending logs to any OpenTelemetry-compatible backend (Sentry, Grafana, Jaeger, etc.)
8
- * without vendor lock-in.
7
+ * Sends logs to any OpenTelemetry-compatible backend (Sentry, Grafana, the
8
+ * Aspire dashboard, etc.) without vendor lock-in.
9
9
  *
10
- * NOTE: This module requires OpenTelemetry packages to be installed as peer dependencies.
11
- * If they are not available, the integration will gracefully disable itself.
10
+ * Every line the Pino transport writes after redaction, from every logger,
11
+ * including ones created before setup is also emitted as an OpenTelemetry
12
+ * log record. The logger bridges this itself rather than through
13
+ * `@opentelemetry/instrumentation-pino`, which only patches Pino when it is
14
+ * loaded through an import-in-the-middle loader hook, and so never saw this
15
+ * package's ESM import of Pino.
16
+ *
17
+ * `@opentelemetry/sdk-logs` is an optional peer dependency, needed only when
18
+ * passing `logRecordProcessor` — which comes from that package anyway, so the
19
+ * app already has it and the logger uses the app's copy.
20
+ *
21
+ * Setup never throws or rejects: if it can't start, it logs an error and
22
+ * leaves logging to stdout untouched.
12
23
  *
13
24
  * @example
14
25
  * // In your app's instrumentation.ts or main entry point
@@ -16,13 +27,10 @@ import { t as Logger } from "./Logger-n-HsscG5.js";
16
27
  * import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
17
28
  * import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
18
29
  *
19
- * setupOpenTelemetryLogger({
20
- * logRecordProcessor: new BatchLogRecordProcessor(
21
- * new OTLPLogExporter({
22
- * url: 'https://[org].ingest.sentry.io/api/[project]/integration/otlp/v1/logs',
23
- * headers: { 'x-sentry-auth': 'sentry sentry_key=...' }
24
- * })
25
- * )
30
+ * await setupOpenTelemetryLogger({
31
+ * logRecordProcessor: new BatchLogRecordProcessor({
32
+ * exporter: new OTLPLogExporter(), // reads OTEL_EXPORTER_OTLP_* env vars
33
+ * }),
26
34
  * });
27
35
  *
28
36
  * @example
@@ -32,100 +40,145 @@ import { t as Logger } from "./Logger-n-HsscG5.js";
32
40
  * const logger = Logger.create({ namespace: 'MyService' });
33
41
  * logger.error({ error: err }, 'Something failed'); // Sent to OpenTelemetry backend
34
42
  */
35
- async function loadOpenTelemetry() {
43
+ var NAMESPACE = "logger:otel";
44
+ var INSTRUMENTATION_SCOPE = "@eventuras/logger";
45
+ /** OpenTelemetry severity numbers for each level (logs data model). */
46
+ var SEVERITY_NUMBERS = {
47
+ trace: 1,
48
+ debug: 5,
49
+ info: 9,
50
+ warn: 13,
51
+ error: 17,
52
+ fatal: 21
53
+ };
54
+ /** Pino's numeric levels, for when `formatters.level` has been overridden. */
55
+ var PINO_LEVEL_LABELS = {
56
+ 10: "trace",
57
+ 20: "debug",
58
+ 30: "info",
59
+ 40: "warn",
60
+ 50: "error",
61
+ 60: "fatal"
62
+ };
63
+ var loggerProvider = null;
64
+ /** Whether `loggerProvider` was created here — only then is it ours to shut down. */
65
+ var ownsLoggerProvider = false;
66
+ async function loadPeer(name, load) {
36
67
  try {
37
- const [pinoModule, logsModule] = await Promise.all([import("@opentelemetry/instrumentation-pino"), import("@opentelemetry/sdk-logs")]);
68
+ return await load();
69
+ } catch (cause) {
70
+ const reason = cause instanceof Error ? cause.message : String(cause);
71
+ throw new Error(`${name} could not be loaded (${reason}). Install it to export logs with OpenTelemetry.`, { cause });
72
+ }
73
+ }
74
+ async function resolveLoggerProvider(options) {
75
+ if (options.loggerProvider) return {
76
+ provider: options.loggerProvider,
77
+ owned: false
78
+ };
79
+ if (options.logRecordProcessor) {
80
+ const { LoggerProvider } = await loadPeer("@opentelemetry/sdk-logs", () => import("@opentelemetry/sdk-logs"));
38
81
  return {
39
- PinoInstrumentation: pinoModule.PinoInstrumentation,
40
- LoggerProvider: logsModule.LoggerProvider
82
+ provider: new LoggerProvider({ processors: [options.logRecordProcessor] }),
83
+ owned: true
41
84
  };
42
- } catch {
43
- return null;
44
85
  }
86
+ return {
87
+ provider: logs.getLoggerProvider(),
88
+ owned: false
89
+ };
90
+ }
91
+ function formatBody(msg) {
92
+ if (Array.isArray(msg)) return msg.map((part) => typeof part === "string" ? part : JSON.stringify(part)).join(" ");
93
+ return msg;
94
+ }
95
+ /** Map a serialized Pino line to an OpenTelemetry log record. */
96
+ function toLogRecord(line, serviceName) {
97
+ const { level, time, msg, ...attributes } = JSON.parse(line);
98
+ delete attributes.pid;
99
+ delete attributes.hostname;
100
+ const label = typeof level === "number" ? PINO_LEVEL_LABELS[level] : String(level);
101
+ const timestamp = new Date(typeof time === "string" || typeof time === "number" ? time : Date.now());
102
+ return {
103
+ timestamp: Number.isNaN(timestamp.getTime()) ? /* @__PURE__ */ new Date() : timestamp,
104
+ severityNumber: label ? SEVERITY_NUMBERS[label] : void 0,
105
+ severityText: label,
106
+ body: formatBody(msg),
107
+ attributes: {
108
+ ...attributes,
109
+ "service.name": serviceName
110
+ }
111
+ };
45
112
  }
46
- var pinoInstrumentation = null;
47
- var loggerProvider = null;
48
113
  /**
49
- * Set up OpenTelemetry integration for Pino logger.
50
- *
51
- * This function:
52
- * 1. Creates or uses provided LoggerProvider
53
- * 2. Registers the log record processor (for exporting logs)
54
- * 3. Enables Pino instrumentation to bridge Pino logs to OTel
114
+ * Set up OpenTelemetry integration for the logger.
55
115
  *
56
- * Call this function once at application startup, before creating any loggers.
116
+ * Call once at application startup. Loggers created before the call are
117
+ * exported too. Calling again replaces the previous setup.
57
118
  *
58
119
  * @param options - Configuration options
59
120
  *
60
121
  * @example
61
122
  * // Send to Sentry via OTLP
62
- * import { setupOpenTelemetryLogger } from '@eventuras/logger';
123
+ * import { setupOpenTelemetryLogger } from '@eventuras/logger/opentelemetry';
63
124
  * import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
64
125
  * import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
65
126
  *
66
- * setupOpenTelemetryLogger({
67
- * logRecordProcessor: new BatchLogRecordProcessor(
68
- * new OTLPLogExporter({
127
+ * await setupOpenTelemetryLogger({
128
+ * logRecordProcessor: new BatchLogRecordProcessor({
129
+ * exporter: new OTLPLogExporter({
69
130
  * url: process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
70
131
  * headers: {
71
132
  * 'x-sentry-auth': `sentry sentry_key=${process.env.SENTRY_KEY}`
72
133
  * }
73
134
  * })
74
- * )
135
+ * })
75
136
  * });
76
137
  *
77
138
  * @example
78
- * // Use environment variables (recommended)
79
- * // Set these in your environment:
80
- * // OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://[org].ingest.sentry.io/api/[project]/integration/otlp/v1/logs
81
- * // OTEL_EXPORTER_OTLP_LOGS_HEADERS=x-sentry-auth=sentry sentry_key=...
82
- *
83
- * import { setupOpenTelemetryLogger } from '@eventuras/logger';
84
- * import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
85
- * import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
86
- *
87
- * await setupOpenTelemetryLogger({
88
- * logRecordProcessor: new BatchLogRecordProcessor(
89
- * new OTLPLogExporter() // Reads from env vars
90
- * )
91
- * });
139
+ * // Use a provider your app already registered globally (e.g. via NodeSDK)
140
+ * await setupOpenTelemetryLogger();
92
141
  */
93
142
  async function setupOpenTelemetryLogger(options = {}) {
94
143
  if (typeof window !== "undefined") {
95
- Logger.warn({ namespace: "logger:otel" }, "OpenTelemetry integration is server-side only, skipping");
144
+ Logger.warn({ namespace: NAMESPACE }, "OpenTelemetry integration is server-side only, skipping");
96
145
  return;
97
146
  }
98
- const { logRecordProcessor, loggerProvider: providedLoggerProvider, serviceName, enabled = true } = options;
147
+ const { serviceName, enabled = true } = options;
99
148
  if (!enabled) {
100
- Logger.debug({ namespace: "logger:otel" }, "OpenTelemetry integration disabled");
101
- return;
102
- }
103
- const otel = await loadOpenTelemetry();
104
- if (!otel) {
105
- Logger.warn({ namespace: "logger:otel" }, "OpenTelemetry packages not available — integration disabled. Install @opentelemetry/api, @opentelemetry/api-logs, @opentelemetry/instrumentation-pino, and @opentelemetry/sdk-logs to enable.");
149
+ Logger.debug({ namespace: NAMESPACE }, "OpenTelemetry integration disabled");
106
150
  return;
107
151
  }
108
- const { PinoInstrumentation, LoggerProvider } = otel;
109
- if (pinoInstrumentation) {
110
- pinoInstrumentation.disable();
111
- pinoInstrumentation = null;
152
+ try {
153
+ const { provider, owned } = await resolveLoggerProvider(options);
154
+ const otelLogger = provider.getLogger(INSTRUMENTATION_SCOPE);
155
+ setLogLineSink(void 0);
156
+ if (loggerProvider && ownsLoggerProvider && loggerProvider !== provider) await loggerProvider.shutdown?.();
157
+ loggerProvider = provider;
158
+ ownsLoggerProvider = owned;
159
+ const resolvedServiceName = serviceName ?? (typeof process !== "undefined" ? process.env?.OTEL_SERVICE_NAME : void 0) ?? "unknown-service";
160
+ setLogLineSink((line) => otelLogger.emit(toLogRecord(line, resolvedServiceName)));
161
+ if (!(Logger.getTransport() instanceof PinoTransport)) Logger.warn({ namespace: NAMESPACE }, "The active transport is not PinoTransport — only PinoTransport output is exported to OpenTelemetry");
162
+ const source = options.loggerProvider ? "loggerProvider" : options.logRecordProcessor ? "logRecordProcessor" : "global";
163
+ Logger.info({
164
+ namespace: NAMESPACE,
165
+ context: { source }
166
+ }, "OpenTelemetry integration enabled");
167
+ } catch (error) {
168
+ Logger.error({
169
+ namespace: NAMESPACE,
170
+ error
171
+ }, "OpenTelemetry integration failed to start — logs are not exported");
112
172
  }
113
- loggerProvider = providedLoggerProvider ?? new LoggerProvider();
114
- if (logRecordProcessor && loggerProvider) loggerProvider.addLogRecordProcessor(logRecordProcessor);
115
- const resolvedServiceName = serviceName ?? (typeof process !== "undefined" ? process.env?.OTEL_SERVICE_NAME : void 0) ?? "unknown-service";
116
- pinoInstrumentation = new PinoInstrumentation({ logHook: (_span, record) => {
117
- record["service.name"] = resolvedServiceName;
118
- } });
119
- pinoInstrumentation.enable();
120
- Logger.info({
121
- namespace: "logger:otel",
122
- context: { hasProcessor: Boolean(logRecordProcessor) }
123
- }, "OpenTelemetry integration enabled");
124
173
  }
125
174
  /**
126
175
  * Shut down the OpenTelemetry logger integration.
127
176
  * Call this when your application is shutting down to flush any pending logs.
128
177
  *
178
+ * A provider created from `logRecordProcessor` is shut down. One passed as
179
+ * `loggerProvider`, or the global one, belongs to your app — it is flushed,
180
+ * not shut down.
181
+ *
129
182
  * @example
130
183
  * process.on('SIGTERM', async () => {
131
184
  * await shutdownOpenTelemetryLogger();
@@ -134,15 +187,13 @@ async function setupOpenTelemetryLogger(options = {}) {
134
187
  */
135
188
  async function shutdownOpenTelemetryLogger() {
136
189
  if (typeof window !== "undefined") return;
137
- if (pinoInstrumentation) {
138
- pinoInstrumentation.disable();
139
- pinoInstrumentation = null;
140
- }
190
+ setLogLineSink(void 0);
141
191
  if (loggerProvider) {
142
- await loggerProvider.shutdown();
192
+ const provider = loggerProvider;
143
193
  loggerProvider = null;
194
+ await (ownsLoggerProvider ? provider.shutdown?.() : provider.forceFlush?.());
144
195
  }
145
- Logger.info({ namespace: "logger:otel" }, "OpenTelemetry integration shut down");
196
+ Logger.info({ namespace: NAMESPACE }, "OpenTelemetry integration shut down");
146
197
  }
147
198
  /**
148
199
  * Get the active LoggerProvider instance, if any.
@@ -1 +1 @@
1
- {"version":3,"file":"opentelemetry.js","names":[],"sources":["../src/opentelemetry.ts"],"sourcesContent":["/**\n * OpenTelemetry integration for @eventuras/logger\n *\n * This module provides integration between Pino and OpenTelemetry Logs API.\n * It allows sending logs to any OpenTelemetry-compatible backend (Sentry, Grafana, Jaeger, etc.)\n * without vendor lock-in.\n *\n * NOTE: This module requires OpenTelemetry packages to be installed as peer dependencies.\n * If they are not available, the integration will gracefully disable itself.\n *\n * @example\n * // In your app's instrumentation.ts or main entry point\n * import { setupOpenTelemetryLogger } from '@eventuras/logger/opentelemetry';\n * import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\n * import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';\n *\n * setupOpenTelemetryLogger({\n * logRecordProcessor: new BatchLogRecordProcessor(\n * new OTLPLogExporter({\n * url: 'https://[org].ingest.sentry.io/api/[project]/integration/otlp/v1/logs',\n * headers: { 'x-sentry-auth': 'sentry sentry_key=...' }\n * })\n * )\n * });\n *\n * @example\n * // Then use logger as normal\n * import { Logger } from '@eventuras/logger';\n *\n * const logger = Logger.create({ namespace: 'MyService' });\n * logger.error({ error: err }, 'Something failed'); // Sent to OpenTelemetry backend\n */\n\nimport { Logger } from './Logger';\n\n/**\n * Minimal interface for an OpenTelemetry LogRecordProcessor.\n * Compatible with `@opentelemetry/sdk-logs` `LogRecordProcessor`.\n * Defined locally to avoid requiring OTel types at compile time.\n */\nexport interface LogRecordProcessor {\n shutdown(): Promise<void>;\n forceFlush(): Promise<void>;\n}\n\n/**\n * Minimal interface for an OpenTelemetry LoggerProvider.\n * Compatible with `@opentelemetry/sdk-logs` `LoggerProvider`.\n */\nexport interface OTelLoggerProvider {\n addLogRecordProcessor(processor: LogRecordProcessor): void;\n shutdown(): Promise<void>;\n forceFlush?(): Promise<void>;\n}\n\n/** Internal interface for Pino instrumentation */\ninterface PinoInstrumentationInstance {\n enable(): void;\n disable(): void;\n}\n\n// Lazy load OpenTelemetry packages to handle optional peer dependencies\nasync function loadOpenTelemetry() {\n try {\n const [pinoModule, logsModule] = await Promise.all([\n import('@opentelemetry/instrumentation-pino'),\n import('@opentelemetry/sdk-logs'),\n ]);\n return {\n PinoInstrumentation: pinoModule.PinoInstrumentation,\n LoggerProvider: logsModule.LoggerProvider\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Options for OpenTelemetry logger integration\n */\nexport type OpenTelemetryLoggerOptions = {\n /**\n * Log record processor (e.g., BatchLogRecordProcessor with an exporter).\n * If not provided, logs will only be instrumented but not exported.\n */\n logRecordProcessor?: LogRecordProcessor;\n\n /**\n * Logger provider instance. If not provided, a new one will be created.\n */\n loggerProvider?: OTelLoggerProvider;\n\n /**\n * Service name to attach to log records.\n * Defaults to the `OTEL_SERVICE_NAME` environment variable, or `'unknown-service'`.\n */\n serviceName?: string;\n\n /**\n * Whether to enable the integration. Default: true\n */\n enabled?: boolean;\n};\n\nlet pinoInstrumentation: PinoInstrumentationInstance | null = null;\nlet loggerProvider: OTelLoggerProvider | null = null;\n\n/**\n * Set up OpenTelemetry integration for Pino logger.\n *\n * This function:\n * 1. Creates or uses provided LoggerProvider\n * 2. Registers the log record processor (for exporting logs)\n * 3. Enables Pino instrumentation to bridge Pino logs to OTel\n *\n * Call this function once at application startup, before creating any loggers.\n *\n * @param options - Configuration options\n *\n * @example\n * // Send to Sentry via OTLP\n * import { setupOpenTelemetryLogger } from '@eventuras/logger';\n * import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\n * import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';\n *\n * setupOpenTelemetryLogger({\n * logRecordProcessor: new BatchLogRecordProcessor(\n * new OTLPLogExporter({\n * url: process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,\n * headers: {\n * 'x-sentry-auth': `sentry sentry_key=${process.env.SENTRY_KEY}`\n * }\n * })\n * )\n * });\n *\n * @example\n * // Use environment variables (recommended)\n * // Set these in your environment:\n * // OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://[org].ingest.sentry.io/api/[project]/integration/otlp/v1/logs\n * // OTEL_EXPORTER_OTLP_LOGS_HEADERS=x-sentry-auth=sentry sentry_key=...\n *\n * import { setupOpenTelemetryLogger } from '@eventuras/logger';\n * import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\n * import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';\n *\n * await setupOpenTelemetryLogger({\n * logRecordProcessor: new BatchLogRecordProcessor(\n * new OTLPLogExporter() // Reads from env vars\n * )\n * });\n */\nexport async function setupOpenTelemetryLogger(\n options: OpenTelemetryLoggerOptions = {}\n): Promise<void> {\n // Check if we're running in a browser environment\n if (typeof window !== 'undefined') {\n Logger.warn({ namespace: 'logger:otel' }, 'OpenTelemetry integration is server-side only, skipping');\n return;\n }\n\n const {\n logRecordProcessor,\n loggerProvider: providedLoggerProvider,\n serviceName,\n enabled = true,\n } = options;\n\n if (!enabled) {\n Logger.debug({ namespace: 'logger:otel' }, 'OpenTelemetry integration disabled');\n return;\n }\n\n // Lazy load OpenTelemetry packages\n const otel = await loadOpenTelemetry();\n\n if (!otel) {\n Logger.warn(\n { namespace: 'logger:otel' },\n 'OpenTelemetry packages not available — integration disabled. Install @opentelemetry/api, @opentelemetry/api-logs, @opentelemetry/instrumentation-pino, and @opentelemetry/sdk-logs to enable.',\n );\n return;\n }\n\n const { PinoInstrumentation, LoggerProvider } = otel;\n\n // Clean up existing instrumentation if re-initializing\n if (pinoInstrumentation) {\n pinoInstrumentation.disable();\n pinoInstrumentation = null;\n }\n\n // Create or use provided logger provider\n loggerProvider = (providedLoggerProvider ?? new LoggerProvider()) as OTelLoggerProvider;\n\n // Register log record processor if provided\n if (logRecordProcessor && loggerProvider) {\n loggerProvider.addLogRecordProcessor(logRecordProcessor);\n }\n\n // Resolve service name from option, env var, or fallback\n const resolvedServiceName =\n serviceName ??\n (typeof process !== 'undefined' ? process.env?.OTEL_SERVICE_NAME : undefined) ??\n 'unknown-service';\n\n // Enable Pino instrumentation to bridge Pino logs to OpenTelemetry\n pinoInstrumentation = new PinoInstrumentation({\n logHook: (_span: unknown, record: Record<string, unknown>) => {\n record['service.name'] = resolvedServiceName;\n },\n }) as PinoInstrumentationInstance;\n\n pinoInstrumentation.enable();\n\n Logger.info(\n { namespace: 'logger:otel', context: { hasProcessor: Boolean(logRecordProcessor) } },\n 'OpenTelemetry integration enabled',\n );\n}\n\n/**\n * Shut down the OpenTelemetry logger integration.\n * Call this when your application is shutting down to flush any pending logs.\n *\n * @example\n * process.on('SIGTERM', async () => {\n * await shutdownOpenTelemetryLogger();\n * process.exit(0);\n * });\n */\nexport async function shutdownOpenTelemetryLogger(): Promise<void> {\n // Check if we're running in a browser environment\n if (typeof window !== 'undefined') {\n return;\n }\n\n if (pinoInstrumentation) {\n pinoInstrumentation.disable();\n pinoInstrumentation = null;\n }\n\n if (loggerProvider) {\n await loggerProvider.shutdown();\n loggerProvider = null;\n }\n\n Logger.info({ namespace: 'logger:otel' }, 'OpenTelemetry integration shut down');\n}\n\n/**\n * Get the active LoggerProvider instance, if any.\n * Useful for advanced use cases or debugging.\n */\nexport function getLoggerProvider(): OTelLoggerProvider | null {\n // Return null if in browser environment\n if (typeof window !== 'undefined') {\n return null;\n }\n\n return loggerProvider;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,eAAe,oBAAoB;AACjC,KAAI;EACF,MAAM,CAAC,YAAY,cAAc,MAAM,QAAQ,IAAI,CACjD,OAAO,wCACP,OAAO,2BACR,CAAC;AACF,SAAO;GACL,qBAAqB,WAAW;GAChC,gBAAgB,WAAW;GAC5B;SACK;AACN,SAAO;;;AA+BX,IAAI,sBAA0D;AAC9D,IAAI,iBAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+ChD,eAAsB,yBACpB,UAAsC,EAAE,EACzB;AAEf,KAAI,OAAO,WAAW,aAAa;AACjC,SAAO,KAAK,EAAE,WAAW,eAAe,EAAE,0DAA0D;AACpG;;CAGF,MAAM,EACJ,oBACA,gBAAgB,wBAChB,aACA,UAAU,SACR;AAEJ,KAAI,CAAC,SAAS;AACZ,SAAO,MAAM,EAAE,WAAW,eAAe,EAAE,qCAAqC;AAChF;;CAIF,MAAM,OAAO,MAAM,mBAAmB;AAEtC,KAAI,CAAC,MAAM;AACT,SAAO,KACL,EAAE,WAAW,eAAe,EAC5B,gMACD;AACD;;CAGF,MAAM,EAAE,qBAAqB,mBAAmB;AAGhD,KAAI,qBAAqB;AACvB,sBAAoB,SAAS;AAC7B,wBAAsB;;AAIxB,kBAAkB,0BAA0B,IAAI,gBAAgB;AAGhE,KAAI,sBAAsB,eACxB,gBAAe,sBAAsB,mBAAmB;CAI1D,MAAM,sBACJ,gBACC,OAAO,YAAY,cAAc,QAAQ,KAAK,oBAAoB,KAAA,MACnE;AAGF,uBAAsB,IAAI,oBAAoB,EAC5C,UAAU,OAAgB,WAAoC;AAC5D,SAAO,kBAAkB;IAE5B,CAAC;AAEF,qBAAoB,QAAQ;AAE5B,QAAO,KACL;EAAE,WAAW;EAAe,SAAS,EAAE,cAAc,QAAQ,mBAAmB,EAAE;EAAE,EACpF,oCACD;;;;;;;;;;;;AAaH,eAAsB,8BAA6C;AAEjE,KAAI,OAAO,WAAW,YACpB;AAGF,KAAI,qBAAqB;AACvB,sBAAoB,SAAS;AAC7B,wBAAsB;;AAGxB,KAAI,gBAAgB;AAClB,QAAM,eAAe,UAAU;AAC/B,mBAAiB;;AAGnB,QAAO,KAAK,EAAE,WAAW,eAAe,EAAE,sCAAsC;;;;;;AAOlF,SAAgB,oBAA+C;AAE7D,KAAI,OAAO,WAAW,YACpB,QAAO;AAGT,QAAO"}
1
+ {"version":3,"file":"opentelemetry.js","names":[],"sources":["../src/opentelemetry.ts"],"sourcesContent":["/**\n * OpenTelemetry integration for @eventuras/logger\n *\n * Sends logs to any OpenTelemetry-compatible backend (Sentry, Grafana, the\n * Aspire dashboard, etc.) without vendor lock-in.\n *\n * Every line the Pino transport writes — after redaction, from every logger,\n * including ones created before setup — is also emitted as an OpenTelemetry\n * log record. The logger bridges this itself rather than through\n * `@opentelemetry/instrumentation-pino`, which only patches Pino when it is\n * loaded through an import-in-the-middle loader hook, and so never saw this\n * package's ESM import of Pino.\n *\n * `@opentelemetry/sdk-logs` is an optional peer dependency, needed only when\n * passing `logRecordProcessor` — which comes from that package anyway, so the\n * app already has it and the logger uses the app's copy.\n *\n * Setup never throws or rejects: if it can't start, it logs an error and\n * leaves logging to stdout untouched.\n *\n * @example\n * // In your app's instrumentation.ts or main entry point\n * import { setupOpenTelemetryLogger } from '@eventuras/logger/opentelemetry';\n * import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\n * import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';\n *\n * await setupOpenTelemetryLogger({\n * logRecordProcessor: new BatchLogRecordProcessor({\n * exporter: new OTLPLogExporter(), // reads OTEL_EXPORTER_OTLP_* env vars\n * }),\n * });\n *\n * @example\n * // Then use logger as normal\n * import { Logger } from '@eventuras/logger';\n *\n * const logger = Logger.create({ namespace: 'MyService' });\n * logger.error({ error: err }, 'Something failed'); // Sent to OpenTelemetry backend\n */\n\nimport { logs } from '@opentelemetry/api-logs';\nimport { Logger } from './Logger';\nimport { setLogLineSink } from './sink';\nimport { PinoTransport } from './transports/pino';\n\n/**\n * Minimal interface for an OpenTelemetry LogRecordProcessor.\n * Compatible with `@opentelemetry/sdk-logs` `LogRecordProcessor`.\n * Defined locally to avoid requiring OTel types at compile time.\n */\nexport interface LogRecordProcessor {\n onEmit(logRecord: unknown, context?: unknown): void;\n shutdown(): Promise<void>;\n forceFlush(): Promise<void>;\n}\n\n/**\n * Minimal shape of an OpenTelemetry log record, as emitted by this package.\n * Loosely typed so the SDK's own `LogRecord` type is assignable to it.\n */\nexport type OTelLogRecord = {\n timestamp?: unknown;\n severityNumber?: number;\n severityText?: string;\n body?: unknown;\n attributes?: Record<string, unknown>;\n};\n\n/**\n * Minimal interface for an OpenTelemetry Logger.\n * Compatible with `@opentelemetry/api-logs` `Logger`.\n */\nexport interface OTelLogger {\n emit(record: OTelLogRecord): void;\n}\n\n/**\n * Minimal interface for an OpenTelemetry LoggerProvider.\n * Compatible with `@opentelemetry/sdk-logs` `LoggerProvider` and the global\n * provider from `@opentelemetry/api-logs`.\n */\nexport interface OTelLoggerProvider {\n getLogger(name: string, version?: string): OTelLogger;\n shutdown?(): Promise<void>;\n forceFlush?(): Promise<void>;\n}\n\n/**\n * Options for OpenTelemetry logger integration\n */\nexport type OpenTelemetryLoggerOptions = {\n /**\n * Log record processor (e.g., BatchLogRecordProcessor with an exporter).\n * A LoggerProvider is created for it. Requires `@opentelemetry/sdk-logs`.\n */\n logRecordProcessor?: LogRecordProcessor;\n\n /**\n * Logger provider to emit to, e.g. one your app already configured with a\n * resource and processors. Takes precedence over `logRecordProcessor`.\n *\n * With neither option, the globally registered provider is used (as set up\n * by `@opentelemetry/sdk-node`, for instance).\n */\n loggerProvider?: OTelLoggerProvider;\n\n /**\n * Service name attached to every log record as the `service.name` attribute.\n * Defaults to the `OTEL_SERVICE_NAME` environment variable, or `'unknown-service'`.\n */\n serviceName?: string;\n\n /**\n * Whether to enable the integration. Default: true\n */\n enabled?: boolean;\n};\n\nconst NAMESPACE = 'logger:otel';\nconst INSTRUMENTATION_SCOPE = '@eventuras/logger';\n\n/** OpenTelemetry severity numbers for each level (logs data model). */\nconst SEVERITY_NUMBERS: Record<string, number> = {\n trace: 1,\n debug: 5,\n info: 9,\n warn: 13,\n error: 17,\n fatal: 21,\n};\n\n/** Pino's numeric levels, for when `formatters.level` has been overridden. */\nconst PINO_LEVEL_LABELS: Record<number, string> = {\n 10: 'trace',\n 20: 'debug',\n 30: 'info',\n 40: 'warn',\n 50: 'error',\n 60: 'fatal',\n};\n\nlet loggerProvider: OTelLoggerProvider | null = null;\n/** Whether `loggerProvider` was created here — only then is it ours to shut down. */\nlet ownsLoggerProvider = false;\n\nasync function loadPeer<T>(name: string, load: () => Promise<T>): Promise<T> {\n try {\n return await load();\n } catch (cause) {\n const reason = cause instanceof Error ? cause.message : String(cause);\n throw new Error(`${name} could not be loaded (${reason}). Install it to export logs with OpenTelemetry.`, {\n cause,\n });\n }\n}\n\nasync function resolveLoggerProvider(\n options: OpenTelemetryLoggerOptions,\n): Promise<{ provider: OTelLoggerProvider; owned: boolean }> {\n if (options.loggerProvider) {\n return { provider: options.loggerProvider, owned: false };\n }\n\n if (options.logRecordProcessor) {\n const { LoggerProvider } = await loadPeer('@opentelemetry/sdk-logs', () => import('@opentelemetry/sdk-logs'));\n return { provider: new LoggerProvider({ processors: [options.logRecordProcessor] }), owned: true };\n }\n\n return { provider: logs.getLoggerProvider(), owned: false };\n}\n\nfunction formatBody(msg: unknown): unknown {\n // Static methods (`Logger.info(options, 'a', 'b')`) log `msg` as an array.\n if (Array.isArray(msg)) {\n return msg.map((part) => (typeof part === 'string' ? part : JSON.stringify(part))).join(' ');\n }\n return msg;\n}\n\n/** Map a serialized Pino line to an OpenTelemetry log record. */\nfunction toLogRecord(line: string, serviceName: string): OTelLogRecord {\n const { level, time, msg, ...attributes } = JSON.parse(line) as Record<string, unknown>;\n\n // Redundant with the `host.name` and `process.pid` resource attributes.\n delete attributes.pid;\n delete attributes.hostname;\n\n const label = typeof level === 'number' ? PINO_LEVEL_LABELS[level] : String(level);\n const timestamp = new Date(typeof time === 'string' || typeof time === 'number' ? time : Date.now());\n\n return {\n timestamp: Number.isNaN(timestamp.getTime()) ? new Date() : timestamp,\n severityNumber: label ? SEVERITY_NUMBERS[label] : undefined,\n severityText: label,\n body: formatBody(msg),\n attributes: { ...attributes, 'service.name': serviceName },\n };\n}\n\n/**\n * Set up OpenTelemetry integration for the logger.\n *\n * Call once at application startup. Loggers created before the call are\n * exported too. Calling again replaces the previous setup.\n *\n * @param options - Configuration options\n *\n * @example\n * // Send to Sentry via OTLP\n * import { setupOpenTelemetryLogger } from '@eventuras/logger/opentelemetry';\n * import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\n * import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';\n *\n * await setupOpenTelemetryLogger({\n * logRecordProcessor: new BatchLogRecordProcessor({\n * exporter: new OTLPLogExporter({\n * url: process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,\n * headers: {\n * 'x-sentry-auth': `sentry sentry_key=${process.env.SENTRY_KEY}`\n * }\n * })\n * })\n * });\n *\n * @example\n * // Use a provider your app already registered globally (e.g. via NodeSDK)\n * await setupOpenTelemetryLogger();\n */\nexport async function setupOpenTelemetryLogger(\n options: OpenTelemetryLoggerOptions = {}\n): Promise<void> {\n // Check if we're running in a browser environment\n if (typeof window !== 'undefined') {\n Logger.warn({ namespace: NAMESPACE }, 'OpenTelemetry integration is server-side only, skipping');\n return;\n }\n\n const { serviceName, enabled = true } = options;\n\n if (!enabled) {\n Logger.debug({ namespace: NAMESPACE }, 'OpenTelemetry integration disabled');\n return;\n }\n\n try {\n const { provider, owned } = await resolveLoggerProvider(options);\n const otelLogger = provider.getLogger(INSTRUMENTATION_SCOPE);\n\n // Replace any previous setup, releasing a provider created here.\n setLogLineSink(undefined);\n if (loggerProvider && ownsLoggerProvider && loggerProvider !== provider) {\n await loggerProvider.shutdown?.();\n }\n loggerProvider = provider;\n ownsLoggerProvider = owned;\n\n const resolvedServiceName =\n serviceName ??\n (typeof process !== 'undefined' ? process.env?.OTEL_SERVICE_NAME : undefined) ??\n 'unknown-service';\n\n setLogLineSink((line) => otelLogger.emit(toLogRecord(line, resolvedServiceName)));\n\n if (!(Logger.getTransport() instanceof PinoTransport)) {\n Logger.warn(\n { namespace: NAMESPACE },\n 'The active transport is not PinoTransport — only PinoTransport output is exported to OpenTelemetry',\n );\n }\n\n const source = options.loggerProvider\n ? 'loggerProvider'\n : options.logRecordProcessor\n ? 'logRecordProcessor'\n : 'global';\n Logger.info({ namespace: NAMESPACE, context: { source } }, 'OpenTelemetry integration enabled');\n } catch (error) {\n Logger.error(\n { namespace: NAMESPACE, error },\n 'OpenTelemetry integration failed to start — logs are not exported',\n );\n }\n}\n\n/**\n * Shut down the OpenTelemetry logger integration.\n * Call this when your application is shutting down to flush any pending logs.\n *\n * A provider created from `logRecordProcessor` is shut down. One passed as\n * `loggerProvider`, or the global one, belongs to your app — it is flushed,\n * not shut down.\n *\n * @example\n * process.on('SIGTERM', async () => {\n * await shutdownOpenTelemetryLogger();\n * process.exit(0);\n * });\n */\nexport async function shutdownOpenTelemetryLogger(): Promise<void> {\n // Check if we're running in a browser environment\n if (typeof window !== 'undefined') {\n return;\n }\n\n setLogLineSink(undefined);\n\n if (loggerProvider) {\n const provider = loggerProvider;\n loggerProvider = null;\n await (ownsLoggerProvider ? provider.shutdown?.() : provider.forceFlush?.());\n }\n\n Logger.info({ namespace: NAMESPACE }, 'OpenTelemetry integration shut down');\n}\n\n/**\n * Get the active LoggerProvider instance, if any.\n * Useful for advanced use cases or debugging.\n */\nexport function getLoggerProvider(): OTelLoggerProvider | null {\n // Return null if in browser environment\n if (typeof window !== 'undefined') {\n return null;\n }\n\n return loggerProvider;\n}\n"],"mappings":"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"}
package/dist/sink.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Process-wide hook for the serialized log lines Pino writes.
3
+ *
4
+ * `PinoTransport` hands every line (after redaction) to the sink, and
5
+ * `@eventuras/logger/opentelemetry` sets the sink to forward lines as
6
+ * OpenTelemetry log records.
7
+ *
8
+ * The sink lives on `globalThis` rather than in module state because a
9
+ * bundler can load this package more than once in one process — Next.js
10
+ * compiles `instrumentation.ts` into its own layer — and the copy that sets
11
+ * the sink up is not necessarily the one whose loggers write the lines.
12
+ */
13
+ export type LogLineSink = (line: string) => void;
14
+ export declare function setLogLineSink(sink: LogLineSink | undefined): void;
15
+ /** Forward a line to the sink, if any. Never throws — telemetry must not break logging. */
16
+ export declare function forwardLogLine(line: string): void;
17
+ //# sourceMappingURL=sink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../src/sink.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAMjD,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAElE;AAED,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CASjD"}
@@ -1,4 +1,10 @@
1
- import { LogLevel, LogTransport } from '../types';
1
+ /**
2
+ * Console-based transport for browser environments and testing.
3
+ *
4
+ * Uses `console.log/warn/error` — no dependencies, works everywhere.
5
+ * Useful as a lightweight fallback when Pino is not available or desired.
6
+ */
7
+ import type { LogLevel, LogTransport } from '../types';
2
8
  export declare class ConsoleTransport implements LogTransport {
3
9
  private readonly bindings;
4
10
  /** Create a ConsoleTransport with optional pre-bound context fields. */
@@ -1,5 +1,15 @@
1
- import { Logger as PinoLogger, LoggerOptions as PinoLoggerOptions } from 'pino';
2
- import { LogLevel, LogTransport } from '../types';
1
+ /**
2
+ * Pino-based transport the default production backend.
3
+ *
4
+ * Wraps a Pino logger instance to satisfy the `LogTransport` interface,
5
+ * keeping Pino as an implementation detail that consumers never interact with directly.
6
+ *
7
+ * For pretty-printed dev output, see `configureNodeLogger` in
8
+ * `@eventuras/logger/node` — this module intentionally stays free of
9
+ * `node:stream` imports so the main entry stays browser/edge-safe.
10
+ */
11
+ import { type Logger as PinoLogger, type LoggerOptions as PinoLoggerOptions } from 'pino';
12
+ import type { LogLevel, LogTransport } from '../types';
3
13
  /**
4
14
  * Minimal structural type for a Pino destination stream — accepts anything
5
15
  * with a `write` method. Defined locally so this file (re-exported from the
@@ -1 +1 @@
1
- {"version":3,"file":"pino.d.ts","sourceRoot":"","sources":["../../src/transports/pino.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAa,EAAE,KAAK,MAAM,IAAI,UAAU,EAAE,KAAK,aAAa,IAAI,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAChG,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;CAC5C;AAED,4CAA4C;AAC5C,MAAM,MAAM,oBAAoB,GAAG;IACjC,+CAA+C;IAC/C,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,qBAAqB,CAAC;IAC1C,6EAA6E;IAC7E,WAAW,CAAC,EAAE,iBAAiB,CAAC;CACjC,CAAC;AAEF,qBAAa,aAAc,YAAW,YAAY;IAChD,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;gBAEd,OAAO,GAAE,oBAAyB;IA2B9C,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAQvE,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY;IAKhD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
1
+ {"version":3,"file":"pino.d.ts","sourceRoot":"","sources":["../../src/transports/pino.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAa,EAAE,KAAK,MAAM,IAAI,UAAU,EAAE,KAAK,aAAa,IAAI,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAEhG,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;CAC5C;AAED,4CAA4C;AAC5C,MAAM,MAAM,oBAAoB,GAAG;IACjC,+CAA+C;IAC/C,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,qBAAqB,CAAC;IAC1C,6EAA6E;IAC7E,WAAW,CAAC,EAAE,iBAAiB,CAAC;CACjC,CAAC;AAEF,qBAAa,aAAc,YAAW,YAAY;IAChD,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;gBAEd,OAAO,GAAE,oBAAyB;IAwC9C,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAQvE,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY;IAKhD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventuras/logger",
3
- "version": "0.8.1",
3
+ "version": "0.9.1",
4
4
  "description": "Structured logging with Pino and optional OpenTelemetry integration",
5
5
  "keywords": [
6
6
  "logger",
@@ -10,14 +10,14 @@
10
10
  "opentelemetry",
11
11
  "otel"
12
12
  ],
13
- "homepage": "https://github.com/losol/eventuras/tree/main/libs/logger#readme",
13
+ "homepage": "https://github.com/losol/origo/tree/main/packages/logger#readme",
14
14
  "bugs": {
15
- "url": "https://github.com/losol/eventuras/issues"
15
+ "url": "https://github.com/losol/origo/issues"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",
19
- "url": "https://github.com/losol/eventuras.git",
20
- "directory": "libs/logger"
19
+ "url": "https://github.com/losol/origo.git",
20
+ "directory": "packages/logger"
21
21
  },
22
22
  "license": "Apache-2.0",
23
23
  "type": "module",
@@ -41,33 +41,23 @@
41
41
  "dist"
42
42
  ],
43
43
  "dependencies": {
44
+ "@opentelemetry/api-logs": ">=0.200.0 <1.0.0",
44
45
  "pino": "^10.3.1"
45
46
  },
46
47
  "devDependencies": {
47
48
  "@opentelemetry/api": "^1.9.1",
48
- "@opentelemetry/api-logs": "^0.215.0",
49
- "@opentelemetry/instrumentation-pino": "^0.61.0",
50
- "@opentelemetry/sdk-logs": "^0.215.0",
51
- "vite": "^8.0.8",
52
- "vitest": "^4.1.4",
53
- "@eventuras/vite-config": "0.2.2"
49
+ "@opentelemetry/sdk-logs": "^0.222.0",
50
+ "typescript": "^6.0.2",
51
+ "vite": "^8.1.0",
52
+ "vitest": "^5.0.0",
53
+ "@eventuras/eslint-config": "1.0.5",
54
+ "@eventuras/typescript-config": "1.1.0",
55
+ "@eventuras/vite-config": "0.4.0"
54
56
  },
55
57
  "peerDependencies": {
56
- "@opentelemetry/api": "^1.9.0",
57
- "@opentelemetry/api-logs": ">=0.200.0 <1.0.0",
58
- "@opentelemetry/instrumentation-pino": ">=0.50.0 <1.0.0",
59
58
  "@opentelemetry/sdk-logs": ">=0.200.0 <1.0.0"
60
59
  },
61
60
  "peerDependenciesMeta": {
62
- "@opentelemetry/api": {
63
- "optional": true
64
- },
65
- "@opentelemetry/api-logs": {
66
- "optional": true
67
- },
68
- "@opentelemetry/instrumentation-pino": {
69
- "optional": true
70
- },
71
61
  "@opentelemetry/sdk-logs": {
72
62
  "optional": true
73
63
  }
@@ -76,7 +66,7 @@
76
66
  "node": ">=20"
77
67
  },
78
68
  "scripts": {
79
- "build": "vite build",
69
+ "build": "vite build && tsc -p tsconfig.build.json --emitDeclarationOnly",
80
70
  "dev": "vite build --watch",
81
71
  "test": "vitest run",
82
72
  "test:watch": "vitest"