@payloops/observability 0.0.8 → 0.0.11
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/dist/index.d.ts +20 -8
- package/dist/index.js +104 -87
- package/package.json +2 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
2
|
-
import pino from 'pino';
|
|
3
2
|
import * as _opentelemetry_api from '@opentelemetry/api';
|
|
4
3
|
|
|
5
4
|
interface TelemetryConfig {
|
|
@@ -16,24 +15,37 @@ interface TelemetryConfig {
|
|
|
16
15
|
declare function initTelemetry(config: TelemetryConfig | string, serviceVersion?: string): NodeSDK;
|
|
17
16
|
declare function shutdownTelemetry(): Promise<void>;
|
|
18
17
|
|
|
18
|
+
interface Logger {
|
|
19
|
+
trace(msg: string): void;
|
|
20
|
+
trace(data: Record<string, unknown>, msg: string): void;
|
|
21
|
+
debug(msg: string): void;
|
|
22
|
+
debug(data: Record<string, unknown>, msg: string): void;
|
|
23
|
+
info(msg: string): void;
|
|
24
|
+
info(data: Record<string, unknown>, msg: string): void;
|
|
25
|
+
warn(msg: string): void;
|
|
26
|
+
warn(data: Record<string, unknown>, msg: string): void;
|
|
27
|
+
error(msg: string): void;
|
|
28
|
+
error(data: Record<string, unknown>, msg: string): void;
|
|
29
|
+
fatal(msg: string): void;
|
|
30
|
+
fatal(data: Record<string, unknown>, msg: string): void;
|
|
31
|
+
child(bindings: Record<string, unknown>): Logger;
|
|
32
|
+
}
|
|
19
33
|
/**
|
|
20
|
-
* Base logger
|
|
21
|
-
* In development: pretty print to console + OTLP
|
|
22
|
-
* In production: JSON to stdout + OTLP
|
|
34
|
+
* Base logger instance
|
|
23
35
|
*/
|
|
24
|
-
declare const logger:
|
|
36
|
+
declare const logger: Logger;
|
|
25
37
|
/**
|
|
26
38
|
* Create a child logger for a specific activity
|
|
27
39
|
*/
|
|
28
|
-
declare function createActivityLogger(activityName: string, correlationId?: string):
|
|
40
|
+
declare function createActivityLogger(activityName: string, correlationId?: string): Logger;
|
|
29
41
|
/**
|
|
30
42
|
* Create a child logger for a specific workflow
|
|
31
43
|
*/
|
|
32
|
-
declare function createWorkflowLogger(workflowId: string, correlationId?: string):
|
|
44
|
+
declare function createWorkflowLogger(workflowId: string, correlationId?: string): Logger;
|
|
33
45
|
/**
|
|
34
46
|
* Create a child logger for HTTP requests
|
|
35
47
|
*/
|
|
36
|
-
declare function createRequestLogger(requestId: string, method: string, path: string):
|
|
48
|
+
declare function createRequestLogger(requestId: string, method: string, path: string): Logger;
|
|
37
49
|
|
|
38
50
|
/**
|
|
39
51
|
* Correlation context for tracking requests across services
|
package/dist/index.js
CHANGED
|
@@ -284,9 +284,8 @@ function shutdownTelemetry() {
|
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
// src/lib/logger.ts
|
|
287
|
-
import pino from "pino";
|
|
288
287
|
import { trace } from "@opentelemetry/api";
|
|
289
|
-
import { logs as logs2, SeverityNumber
|
|
288
|
+
import { logs as logs2, SeverityNumber } from "@opentelemetry/api-logs";
|
|
290
289
|
|
|
291
290
|
// src/lib/context.ts
|
|
292
291
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -333,54 +332,63 @@ function createContextFromMemo(memo) {
|
|
|
333
332
|
// src/lib/logger.ts
|
|
334
333
|
var NODE_ENV = process.env.NODE_ENV || "development";
|
|
335
334
|
var SERVICE_NAME = process.env.OTEL_SERVICE_NAME || "loop";
|
|
336
|
-
var
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
// error
|
|
347
|
-
60: SeverityNumber2.FATAL
|
|
348
|
-
// fatal
|
|
335
|
+
var LOG_LEVEL = process.env.LOG_LEVEL || (NODE_ENV === "production" ? "info" : "debug");
|
|
336
|
+
var colors = {
|
|
337
|
+
reset: "\x1B[0m",
|
|
338
|
+
dim: "\x1B[2m",
|
|
339
|
+
red: "\x1B[31m",
|
|
340
|
+
green: "\x1B[32m",
|
|
341
|
+
yellow: "\x1B[33m",
|
|
342
|
+
blue: "\x1B[34m",
|
|
343
|
+
magenta: "\x1B[35m",
|
|
344
|
+
cyan: "\x1B[36m"
|
|
349
345
|
};
|
|
350
|
-
var
|
|
351
|
-
|
|
346
|
+
var levelConfig = {
|
|
347
|
+
trace: { severity: SeverityNumber.TRACE, color: colors.dim, label: "TRACE", priority: 0 },
|
|
348
|
+
debug: { severity: SeverityNumber.DEBUG, color: colors.blue, label: "DEBUG", priority: 1 },
|
|
349
|
+
info: { severity: SeverityNumber.INFO, color: colors.green, label: "INFO", priority: 2 },
|
|
350
|
+
warn: { severity: SeverityNumber.WARN, color: colors.yellow, label: "WARN", priority: 3 },
|
|
351
|
+
error: { severity: SeverityNumber.ERROR, color: colors.red, label: "ERROR", priority: 4 },
|
|
352
|
+
fatal: { severity: SeverityNumber.FATAL, color: colors.magenta, label: "FATAL", priority: 5 }
|
|
353
|
+
};
|
|
354
|
+
var currentLevelPriority = levelConfig[LOG_LEVEL]?.priority ?? 2;
|
|
355
|
+
function getContext() {
|
|
356
|
+
const ctx = {};
|
|
352
357
|
const span = trace.getActiveSpan();
|
|
353
358
|
if (span) {
|
|
354
359
|
const spanContext = span.spanContext();
|
|
355
|
-
|
|
356
|
-
|
|
360
|
+
ctx.trace_id = spanContext.traceId;
|
|
361
|
+
ctx.span_id = spanContext.spanId;
|
|
357
362
|
}
|
|
358
363
|
const correlationCtx = getCorrelationContext();
|
|
359
364
|
if (correlationCtx) {
|
|
360
|
-
|
|
361
|
-
if (correlationCtx.merchantId)
|
|
362
|
-
if (correlationCtx.orderId)
|
|
363
|
-
if (correlationCtx.workflowId)
|
|
365
|
+
ctx.correlation_id = correlationCtx.correlationId;
|
|
366
|
+
if (correlationCtx.merchantId) ctx.merchant_id = correlationCtx.merchantId;
|
|
367
|
+
if (correlationCtx.orderId) ctx.order_id = correlationCtx.orderId;
|
|
368
|
+
if (correlationCtx.workflowId) ctx.workflow_id = correlationCtx.workflowId;
|
|
364
369
|
}
|
|
365
|
-
return
|
|
366
|
-
}
|
|
367
|
-
function emitToOtel(
|
|
370
|
+
return ctx;
|
|
371
|
+
}
|
|
372
|
+
function emitToOtel(level, message, attributes) {
|
|
368
373
|
try {
|
|
369
|
-
const
|
|
374
|
+
const provider = logs2.getLoggerProvider();
|
|
375
|
+
if (provider.constructor.name === "ProxyLoggerProvider") {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const otelLogger = provider.getLogger(SERVICE_NAME);
|
|
370
379
|
const span = trace.getActiveSpan();
|
|
371
380
|
const spanContext = span?.spanContext();
|
|
381
|
+
const config = levelConfig[level];
|
|
372
382
|
otelLogger.emit({
|
|
373
|
-
severityNumber:
|
|
374
|
-
severityText:
|
|
375
|
-
body:
|
|
383
|
+
severityNumber: config?.severity ?? SeverityNumber.INFO,
|
|
384
|
+
severityText: config?.label ?? "INFO",
|
|
385
|
+
body: message,
|
|
376
386
|
attributes: {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
level: void 0,
|
|
381
|
-
time: void 0
|
|
387
|
+
service: SERVICE_NAME,
|
|
388
|
+
env: NODE_ENV,
|
|
389
|
+
...attributes
|
|
382
390
|
},
|
|
383
|
-
timestamp:
|
|
391
|
+
timestamp: Date.now() * 1e6,
|
|
384
392
|
// nanoseconds
|
|
385
393
|
...spanContext && {
|
|
386
394
|
spanId: spanContext.spanId,
|
|
@@ -391,65 +399,74 @@ function emitToOtel(logRecord) {
|
|
|
391
399
|
} catch {
|
|
392
400
|
}
|
|
393
401
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
402
|
+
function formatConsole(level, message, data) {
|
|
403
|
+
const config = levelConfig[level];
|
|
404
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
405
|
+
const color = config?.color ?? colors.reset;
|
|
406
|
+
const label = config?.label ?? level.toUpperCase();
|
|
407
|
+
if (NODE_ENV === "production") {
|
|
408
|
+
return JSON.stringify({
|
|
409
|
+
time: timestamp,
|
|
410
|
+
level: label,
|
|
411
|
+
msg: message,
|
|
401
412
|
service: SERVICE_NAME,
|
|
402
|
-
env: NODE_ENV
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
Object.assign(logRecord, objOrMsg);
|
|
406
|
-
logRecord.msg = msgOrUndefined || "";
|
|
407
|
-
} else {
|
|
408
|
-
logRecord.msg = objOrMsg;
|
|
409
|
-
}
|
|
410
|
-
Object.assign(logRecord, traceMixin());
|
|
411
|
-
emitToOtel(logRecord);
|
|
413
|
+
env: NODE_ENV,
|
|
414
|
+
...data
|
|
415
|
+
});
|
|
412
416
|
}
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
{
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
417
|
+
const timeStr = `${colors.dim}[${timestamp.split("T")[1].slice(0, -1)}]${colors.reset}`;
|
|
418
|
+
const levelStr = `${color}${label.padEnd(5)}${colors.reset}`;
|
|
419
|
+
const msgStr = `${color}${message}${colors.reset}`;
|
|
420
|
+
const dataEntries = Object.entries(data).filter(([, v]) => v !== void 0);
|
|
421
|
+
const dataStr = dataEntries.length > 0 ? "\n" + dataEntries.map(([k, v]) => ` ${colors.magenta}${k}${colors.reset}: ${JSON.stringify(v)}`).join("\n") : "";
|
|
422
|
+
return `${timeStr} ${levelStr}: ${msgStr}${dataStr}`;
|
|
423
|
+
}
|
|
424
|
+
function log(level, msgOrData, msg) {
|
|
425
|
+
const config = levelConfig[level];
|
|
426
|
+
if (!config || config.priority < currentLevelPriority) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
let message;
|
|
430
|
+
let data;
|
|
431
|
+
if (typeof msgOrData === "string") {
|
|
432
|
+
message = msgOrData;
|
|
433
|
+
data = {};
|
|
434
|
+
} else {
|
|
435
|
+
message = msg ?? "";
|
|
436
|
+
data = msgOrData;
|
|
437
|
+
}
|
|
438
|
+
const context2 = getContext();
|
|
439
|
+
const enrichedData = { ...data, ...context2 };
|
|
440
|
+
console.log(formatConsole(level, message, enrichedData));
|
|
441
|
+
emitToOtel(level, message, enrichedData);
|
|
442
|
+
}
|
|
443
|
+
function createLogger(bindings = {}) {
|
|
444
|
+
const boundLog = (level, msgOrData, msg) => {
|
|
445
|
+
if (typeof msgOrData === "string") {
|
|
446
|
+
log(level, { ...bindings }, msgOrData);
|
|
447
|
+
} else {
|
|
448
|
+
log(level, { ...bindings, ...msgOrData }, msg);
|
|
430
449
|
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
)
|
|
450
|
+
};
|
|
451
|
+
return {
|
|
452
|
+
trace: (msgOrData, msg) => boundLog("trace", msgOrData, msg),
|
|
453
|
+
debug: (msgOrData, msg) => boundLog("debug", msgOrData, msg),
|
|
454
|
+
info: (msgOrData, msg) => boundLog("info", msgOrData, msg),
|
|
455
|
+
warn: (msgOrData, msg) => boundLog("warn", msgOrData, msg),
|
|
456
|
+
error: (msgOrData, msg) => boundLog("error", msgOrData, msg),
|
|
457
|
+
fatal: (msgOrData, msg) => boundLog("fatal", msgOrData, msg),
|
|
458
|
+
child: (childBindings) => createLogger({ ...bindings, ...childBindings })
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
var logger = createLogger({ service: SERVICE_NAME, env: NODE_ENV });
|
|
435
462
|
function createActivityLogger(activityName, correlationId) {
|
|
436
|
-
return logger.child({
|
|
437
|
-
activity: activityName,
|
|
438
|
-
correlationId
|
|
439
|
-
});
|
|
463
|
+
return logger.child({ activity: activityName, correlationId });
|
|
440
464
|
}
|
|
441
465
|
function createWorkflowLogger(workflowId, correlationId) {
|
|
442
|
-
return logger.child({
|
|
443
|
-
workflowId,
|
|
444
|
-
correlationId
|
|
445
|
-
});
|
|
466
|
+
return logger.child({ workflowId, correlationId });
|
|
446
467
|
}
|
|
447
468
|
function createRequestLogger(requestId, method, path) {
|
|
448
|
-
return logger.child({
|
|
449
|
-
requestId,
|
|
450
|
-
method,
|
|
451
|
-
path
|
|
452
|
-
});
|
|
469
|
+
return logger.child({ requestId, method, path });
|
|
453
470
|
}
|
|
454
471
|
|
|
455
472
|
// src/lib/metrics.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloops/observability",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -36,14 +36,12 @@
|
|
|
36
36
|
"@opentelemetry/sdk-metrics": "^1.30.1",
|
|
37
37
|
"@opentelemetry/sdk-node": "^0.57.0",
|
|
38
38
|
"@opentelemetry/semantic-conventions": "^1.28.0",
|
|
39
|
-
"nanoid": "^5.0.9"
|
|
40
|
-
"pino": "^9.6.0"
|
|
39
|
+
"nanoid": "^5.0.9"
|
|
41
40
|
},
|
|
42
41
|
"devDependencies": {
|
|
43
42
|
"@eslint/js": "^9.39.2",
|
|
44
43
|
"@types/node": "^22.0.0",
|
|
45
44
|
"eslint": "^9.0.0",
|
|
46
|
-
"pino-pretty": "^13.0.0",
|
|
47
45
|
"tsup": "^8.3.5",
|
|
48
46
|
"typescript": "^5.9.3",
|
|
49
47
|
"typescript-eslint": "^8.53.0"
|