@foam-ai/node-cliengo 0.1.0-alpha.5 → 0.1.0-alpha.6

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.
@@ -21,8 +21,13 @@
21
21
  * 60→FATAL. Unknown numeric levels default to INFO.
22
22
  * - Pino uses `msg` for the message field (not `message` like Winston). We
23
23
  * check both for compatibility with custom Pino configs.
24
- * - Internal Pino fields (pid, hostname, time) are excluded from attributes
25
- * to avoid noise. All other fields are forwarded.
24
+ * - Trace context (traceId, spanId, traceparent) is read from the parsed
25
+ * JSON line, NOT from getTraceContext(). The pino mixin injects these at
26
+ * log-write time (when NR's transaction is still active). The stream write
27
+ * happens asynchronously — by then NR's transaction has ended, so calling
28
+ * getTraceContext() here would return empty strings.
29
+ * - Internal Pino fields (pid, hostname, time) and trace fields (traceId,
30
+ * spanId, traceparent) are excluded from forwarded attributes.
26
31
  * - Callback always called — never blocks the Pino stream pipeline.
27
32
  * - Buffer chunks: converted to string before parsing (handles both Buffer
28
33
  * and string inputs from Node streams).
@@ -22,8 +22,13 @@
22
22
  * 60→FATAL. Unknown numeric levels default to INFO.
23
23
  * - Pino uses `msg` for the message field (not `message` like Winston). We
24
24
  * check both for compatibility with custom Pino configs.
25
- * - Internal Pino fields (pid, hostname, time) are excluded from attributes
26
- * to avoid noise. All other fields are forwarded.
25
+ * - Trace context (traceId, spanId, traceparent) is read from the parsed
26
+ * JSON line, NOT from getTraceContext(). The pino mixin injects these at
27
+ * log-write time (when NR's transaction is still active). The stream write
28
+ * happens asynchronously — by then NR's transaction has ended, so calling
29
+ * getTraceContext() here would return empty strings.
30
+ * - Internal Pino fields (pid, hostname, time) and trace fields (traceId,
31
+ * spanId, traceparent) are excluded from forwarded attributes.
27
32
  * - Callback always called — never blocks the Pino stream pipeline.
28
33
  * - Buffer chunks: converted to string before parsing (handles both Buffer
29
34
  * and string inputs from Node streams).
@@ -32,7 +37,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
32
37
  exports.createPinoDestination = createPinoDestination;
33
38
  const api_logs_1 = require("@opentelemetry/api-logs");
34
39
  const node_stream_1 = require("node:stream");
35
- const trace_bridge_1 = require("../trace-bridge");
36
40
  const PINO_LEVEL_MAP = {
37
41
  10: api_logs_1.SeverityNumber.TRACE,
38
42
  20: api_logs_1.SeverityNumber.DEBUG,
@@ -66,16 +70,23 @@ function createPinoDestination(loggerProvider, serviceName) {
66
70
  const msg = parsed.msg ?? parsed.message ?? '';
67
71
  const severity = PINO_LEVEL_MAP[level] ?? api_logs_1.SeverityNumber.INFO;
68
72
  const severityText = PINO_LEVEL_TEXT[level] ?? 'INFO';
69
- const ctx = (0, trace_bridge_1.getTraceContext)();
73
+ // Read trace context from the parsed JSON line — the pino mixin already
74
+ // injected traceId/spanId/traceparent at log-write time (when the NR
75
+ // transaction was still active). Calling getTraceContext() here would be
76
+ // too late — the stream write happens asynchronously after NR's
77
+ // transaction has ended.
78
+ const traceId = parsed.traceId ?? '';
79
+ const spanId = parsed.spanId ?? '';
70
80
  const attributes = {};
71
- if (ctx.traceId) {
72
- attributes['trace.id'] = ctx.traceId;
81
+ if (traceId) {
82
+ attributes['trace.id'] = traceId;
73
83
  }
74
- if (ctx.spanId) {
75
- attributes['span.id'] = ctx.spanId;
84
+ if (spanId) {
85
+ attributes['span.id'] = spanId;
76
86
  }
87
+ const SKIP_KEYS = new Set(['level', 'msg', 'message', 'time', 'pid', 'hostname', 'traceId', 'spanId', 'traceparent']);
77
88
  for (const [key, val] of Object.entries(parsed)) {
78
- if (key !== 'level' && key !== 'msg' && key !== 'message' && key !== 'time' && key !== 'pid' && key !== 'hostname') {
89
+ if (!SKIP_KEYS.has(key)) {
79
90
  try {
80
91
  attributes[key] = typeof val === 'string' ? val : JSON.stringify(val);
81
92
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foam-ai/node-cliengo",
3
- "version": "0.1.0-alpha.5",
3
+ "version": "0.1.0-alpha.6",
4
4
  "description": "Unified observability (traces, logs, metrics) for Cliengo Node.js services, connecting New Relic APM with Foam's OTel collector.",
5
5
  "main": "dist/node-cliengo/src/index.js",
6
6
  "types": "dist/node-cliengo/src/index.d.ts",