@opentelemetry/winston-transport 0.27.0 → 0.29.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.
@@ -40,6 +40,120 @@ const cliLevels = {
40
40
  function getSeverityNumber(level) {
41
41
  return npmLevels[level] ?? sysLoglevels[level] ?? cliLevels[level];
42
42
  }
43
+ /**
44
+ * Mirrors the exception shapes handled by sdk-logs `LogRecordImpl._setException`.
45
+ * We cannot reuse that internal method directly from this package.
46
+ */
47
+ function isSdkLogsExceptionCandidate(value) {
48
+ if (typeof value === 'string' || typeof value === 'number') {
49
+ return true;
50
+ }
51
+ if (value == null || typeof value !== 'object') {
52
+ return false;
53
+ }
54
+ const exception = value;
55
+ return (exception.code != null ||
56
+ exception.name != null ||
57
+ exception.message != null ||
58
+ exception.stack != null);
59
+ }
60
+ function extractCauseAttributes(key, value) {
61
+ if (value == null || typeof value !== 'object' || !('cause' in value)) {
62
+ return {};
63
+ }
64
+ const cause = value.cause;
65
+ if (cause == null) {
66
+ return {};
67
+ }
68
+ const attributes = {};
69
+ if (typeof cause === 'string' || typeof cause === 'number') {
70
+ attributes[`${key}.cause`] = cause;
71
+ return attributes;
72
+ }
73
+ if (typeof cause !== 'object') {
74
+ attributes[`${key}.cause`] = String(cause);
75
+ return attributes;
76
+ }
77
+ const exceptionCause = cause;
78
+ if (typeof exceptionCause.code === 'string' ||
79
+ typeof exceptionCause.code === 'number') {
80
+ attributes[`${key}.cause.code`] = exceptionCause.code;
81
+ }
82
+ if (typeof exceptionCause.name === 'string') {
83
+ attributes[`${key}.cause.type`] = exceptionCause.name;
84
+ }
85
+ if (typeof exceptionCause.message === 'string') {
86
+ attributes[`${key}.cause.message`] = exceptionCause.message;
87
+ }
88
+ if (typeof exceptionCause.stack === 'string') {
89
+ attributes[`${key}.cause.stacktrace`] = exceptionCause.stack;
90
+ }
91
+ if (Object.keys(attributes).length === 0) {
92
+ attributes[`${key}.cause`] = String(cause);
93
+ }
94
+ return attributes;
95
+ }
96
+ /**
97
+ * Attempts to extract an exception/error from a Winston log record.
98
+ *
99
+ * Winston records can carry error information in several ways depending on
100
+ * how the user logged and which formats are configured. This function checks
101
+ * three sources in priority order:
102
+ *
103
+ * 1. Named fields ('err', 'error') used by user code and Winston internals.
104
+ * 2. Splat args (Symbol.for('splat')) used for extra positional log args.
105
+ * 3. Flattened stack fields produced by format.errors({ stack: true }).
106
+ *
107
+ * @returns The extracted exception, record keys that should be excluded from
108
+ * OTel attributes to avoid duplication, and optional extra attributes
109
+ * derived from the source error (for example `error.cause.*`).
110
+ * Returns null if no error was found.
111
+ */
112
+ function getExceptionPayload(record) {
113
+ for (const key of ['err', 'error']) {
114
+ const value = record[key];
115
+ if (isSdkLogsExceptionCandidate(value)) {
116
+ return {
117
+ exception: value,
118
+ excludedAttributes: [key],
119
+ additionalAttributes: extractCauseAttributes(key, value),
120
+ };
121
+ }
122
+ }
123
+ const splat = record[Symbol.for('splat')];
124
+ if (Array.isArray(splat)) {
125
+ const splatException = splat.find(isSdkLogsExceptionCandidate);
126
+ if (splatException !== undefined) {
127
+ return {
128
+ exception: splatException,
129
+ excludedAttributes: [],
130
+ };
131
+ }
132
+ }
133
+ if (typeof record.stack === 'string') {
134
+ const stackTypeMatch = /^([^:\n]+):/.exec(record.stack);
135
+ const exception = {
136
+ stack: record.stack,
137
+ };
138
+ if (typeof record.code === 'string' || typeof record.code === 'number') {
139
+ exception.code = record.code;
140
+ }
141
+ if (typeof record.name === 'string') {
142
+ exception.name = record.name;
143
+ }
144
+ else if (stackTypeMatch) {
145
+ exception.name = stackTypeMatch[1];
146
+ }
147
+ if (typeof record.message === 'string') {
148
+ exception.message = record.message;
149
+ }
150
+ return {
151
+ exception,
152
+ excludedAttributes: ['code', 'name', 'stack'],
153
+ };
154
+ }
155
+ return null;
156
+ }
43
157
  function emitLogRecord(record, logger) {
44
158
  const { message, level, ...splat } = record;
45
159
  const attributes = {};
@@ -47,16 +161,27 @@ function emitLogRecord(record, logger) {
47
161
  // accidental inclusion of ANSI color codes that may be present in the string
48
162
  // property.
49
163
  const levelSym = record[Symbol.for('level')];
164
+ const exceptionPayload = getExceptionPayload(record);
165
+ const excludedAttributes = new Set(exceptionPayload?.excludedAttributes ?? []);
50
166
  for (const key in splat) {
51
- if (Object.prototype.hasOwnProperty.call(splat, key)) {
167
+ if (Object.prototype.hasOwnProperty.call(splat, key) &&
168
+ !excludedAttributes.has(key)) {
52
169
  attributes[key] = splat[key];
53
170
  }
54
171
  }
172
+ if (exceptionPayload?.additionalAttributes) {
173
+ for (const key in exceptionPayload.additionalAttributes) {
174
+ if (Object.prototype.hasOwnProperty.call(exceptionPayload.additionalAttributes, key)) {
175
+ attributes[key] = exceptionPayload.additionalAttributes[key];
176
+ }
177
+ }
178
+ }
55
179
  const logRecord = {
56
180
  severityNumber: getSeverityNumber(levelSym),
57
181
  severityText: levelSym,
58
182
  body: message,
59
183
  attributes: attributes,
184
+ ...(exceptionPayload ? { exception: exceptionPayload.exception } : {}),
60
185
  };
61
186
  logger.emit(logRecord);
62
187
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,sDAKiC;AAEjC,MAAM,SAAS,GAA2B;IACxC,KAAK,EAAE,yBAAc,CAAC,KAAK;IAC3B,IAAI,EAAE,yBAAc,CAAC,IAAI;IACzB,IAAI,EAAE,yBAAc,CAAC,IAAI;IACzB,IAAI,EAAE,yBAAc,CAAC,MAAM;IAC3B,OAAO,EAAE,yBAAc,CAAC,MAAM;IAC9B,KAAK,EAAE,yBAAc,CAAC,KAAK;IAC3B,KAAK,EAAE,yBAAc,CAAC,KAAK;CAC5B,CAAC;AAEF,MAAM,YAAY,GAA2B;IAC3C,KAAK,EAAE,yBAAc,CAAC,MAAM;IAC5B,KAAK,EAAE,yBAAc,CAAC,MAAM;IAC5B,IAAI,EAAE,yBAAc,CAAC,KAAK;IAC1B,KAAK,EAAE,yBAAc,CAAC,KAAK;IAC3B,OAAO,EAAE,yBAAc,CAAC,IAAI;IAC5B,MAAM,EAAE,yBAAc,CAAC,KAAK;IAC5B,IAAI,EAAE,yBAAc,CAAC,IAAI;IACzB,KAAK,EAAE,yBAAc,CAAC,KAAK;CAC5B,CAAC;AAEF,MAAM,SAAS,GAA2B;IACxC,KAAK,EAAE,yBAAc,CAAC,KAAK;IAC3B,IAAI,EAAE,yBAAc,CAAC,IAAI;IACzB,IAAI,EAAE,yBAAc,CAAC,KAAK;IAC1B,IAAI,EAAE,yBAAc,CAAC,KAAK;IAC1B,IAAI,EAAE,yBAAc,CAAC,IAAI;IACzB,KAAK,EAAE,yBAAc,CAAC,KAAK;IAC3B,MAAM,EAAE,yBAAc,CAAC,MAAM;IAC7B,OAAO,EAAE,yBAAc,CAAC,MAAM;IAC9B,KAAK,EAAE,yBAAc,CAAC,MAAM;IAC5B,KAAK,EAAE,yBAAc,CAAC,KAAK;CAC5B,CAAC;AAEF,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,SAAS,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;AACrE,CAAC;AAED,SAAgB,aAAa,CAC3B,MAAoC,EACpC,MAAc;IAEd,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,MAAM,CAAC;IAC5C,MAAM,UAAU,GAAkB,EAAE,CAAC;IACrC,qEAAqE;IACrE,6EAA6E;IAC7E,YAAY;IACZ,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7C,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE;QACvB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;YACpD,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;SAC9B;KACF;IACD,MAAM,SAAS,GAAc;QAC3B,cAAc,EAAE,iBAAiB,CAAC,QAAQ,CAAC;QAC3C,YAAY,EAAE,QAAQ;QACtB,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,UAAU;KACvB,CAAC;IACF,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACzB,CAAC;AAtBD,sCAsBC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n LogAttributes,\n LogRecord,\n Logger,\n SeverityNumber,\n} from '@opentelemetry/api-logs';\n\nconst npmLevels: Record<string, number> = {\n error: SeverityNumber.ERROR,\n warn: SeverityNumber.WARN,\n info: SeverityNumber.INFO,\n http: SeverityNumber.DEBUG3,\n verbose: SeverityNumber.DEBUG2,\n debug: SeverityNumber.DEBUG,\n silly: SeverityNumber.TRACE,\n};\n\nconst sysLoglevels: Record<string, number> = {\n emerg: SeverityNumber.FATAL3,\n alert: SeverityNumber.FATAL2,\n crit: SeverityNumber.FATAL,\n error: SeverityNumber.ERROR,\n warning: SeverityNumber.WARN,\n notice: SeverityNumber.INFO2,\n info: SeverityNumber.INFO,\n debug: SeverityNumber.DEBUG,\n};\n\nconst cliLevels: Record<string, number> = {\n error: SeverityNumber.ERROR,\n warn: SeverityNumber.WARN,\n help: SeverityNumber.INFO3,\n data: SeverityNumber.INFO2,\n info: SeverityNumber.INFO,\n debug: SeverityNumber.DEBUG,\n prompt: SeverityNumber.TRACE4,\n verbose: SeverityNumber.TRACE3,\n input: SeverityNumber.TRACE2,\n silly: SeverityNumber.TRACE,\n};\n\nfunction getSeverityNumber(level: string): SeverityNumber | undefined {\n return npmLevels[level] ?? sysLoglevels[level] ?? cliLevels[level];\n}\n\nexport function emitLogRecord(\n record: Record<string | symbol, any>,\n logger: Logger\n): void {\n const { message, level, ...splat } = record;\n const attributes: LogAttributes = {};\n // Ensures the log level is read from a symbol property, avoiding any\n // accidental inclusion of ANSI color codes that may be present in the string\n // property.\n const levelSym = record[Symbol.for('level')];\n for (const key in splat) {\n if (Object.prototype.hasOwnProperty.call(splat, key)) {\n attributes[key] = splat[key];\n }\n }\n const logRecord: LogRecord = {\n severityNumber: getSeverityNumber(levelSym),\n severityText: levelSym,\n body: message,\n attributes: attributes,\n };\n logger.emit(logRecord);\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n AnyValue,\n LogAttributes,\n LogRecord,\n Logger,\n SeverityNumber,\n} from '@opentelemetry/api-logs';\n\nconst npmLevels: Record<string, number> = {\n error: SeverityNumber.ERROR,\n warn: SeverityNumber.WARN,\n info: SeverityNumber.INFO,\n http: SeverityNumber.DEBUG3,\n verbose: SeverityNumber.DEBUG2,\n debug: SeverityNumber.DEBUG,\n silly: SeverityNumber.TRACE,\n};\n\nconst sysLoglevels: Record<string, number> = {\n emerg: SeverityNumber.FATAL3,\n alert: SeverityNumber.FATAL2,\n crit: SeverityNumber.FATAL,\n error: SeverityNumber.ERROR,\n warning: SeverityNumber.WARN,\n notice: SeverityNumber.INFO2,\n info: SeverityNumber.INFO,\n debug: SeverityNumber.DEBUG,\n};\n\nconst cliLevels: Record<string, number> = {\n error: SeverityNumber.ERROR,\n warn: SeverityNumber.WARN,\n help: SeverityNumber.INFO3,\n data: SeverityNumber.INFO2,\n info: SeverityNumber.INFO,\n debug: SeverityNumber.DEBUG,\n prompt: SeverityNumber.TRACE4,\n verbose: SeverityNumber.TRACE3,\n input: SeverityNumber.TRACE2,\n silly: SeverityNumber.TRACE,\n};\n\nfunction getSeverityNumber(level: string): SeverityNumber | undefined {\n return npmLevels[level] ?? sysLoglevels[level] ?? cliLevels[level];\n}\n\n/**\n * Mirrors the exception shapes handled by sdk-logs `LogRecordImpl._setException`.\n * We cannot reuse that internal method directly from this package.\n */\nfunction isSdkLogsExceptionCandidate(value: unknown): boolean {\n if (typeof value === 'string' || typeof value === 'number') {\n return true;\n }\n\n if (value == null || typeof value !== 'object') {\n return false;\n }\n\n const exception = value as {\n code?: unknown;\n name?: unknown;\n message?: unknown;\n stack?: unknown;\n };\n\n return (\n exception.code != null ||\n exception.name != null ||\n exception.message != null ||\n exception.stack != null\n );\n}\n\nfunction extractCauseAttributes(\n key: 'err' | 'error',\n value: unknown\n): LogAttributes {\n if (value == null || typeof value !== 'object' || !('cause' in value)) {\n return {};\n }\n\n const cause = (value as { cause: unknown }).cause;\n if (cause == null) {\n return {};\n }\n\n const attributes: LogAttributes = {};\n if (typeof cause === 'string' || typeof cause === 'number') {\n attributes[`${key}.cause`] = cause as AnyValue;\n return attributes;\n }\n\n if (typeof cause !== 'object') {\n attributes[`${key}.cause`] = String(cause);\n return attributes;\n }\n\n const exceptionCause = cause as {\n code?: unknown;\n name?: unknown;\n message?: unknown;\n stack?: unknown;\n };\n if (\n typeof exceptionCause.code === 'string' ||\n typeof exceptionCause.code === 'number'\n ) {\n attributes[`${key}.cause.code`] = exceptionCause.code;\n }\n if (typeof exceptionCause.name === 'string') {\n attributes[`${key}.cause.type`] = exceptionCause.name;\n }\n if (typeof exceptionCause.message === 'string') {\n attributes[`${key}.cause.message`] = exceptionCause.message;\n }\n if (typeof exceptionCause.stack === 'string') {\n attributes[`${key}.cause.stacktrace`] = exceptionCause.stack;\n }\n\n if (Object.keys(attributes).length === 0) {\n attributes[`${key}.cause`] = String(cause);\n }\n return attributes;\n}\n\n/**\n * Attempts to extract an exception/error from a Winston log record.\n *\n * Winston records can carry error information in several ways depending on\n * how the user logged and which formats are configured. This function checks\n * three sources in priority order:\n *\n * 1. Named fields ('err', 'error') used by user code and Winston internals.\n * 2. Splat args (Symbol.for('splat')) used for extra positional log args.\n * 3. Flattened stack fields produced by format.errors({ stack: true }).\n *\n * @returns The extracted exception, record keys that should be excluded from\n * OTel attributes to avoid duplication, and optional extra attributes\n * derived from the source error (for example `error.cause.*`).\n * Returns null if no error was found.\n */\nfunction getExceptionPayload(record: Record<string | symbol, any>): {\n exception: unknown;\n excludedAttributes: string[];\n additionalAttributes?: LogAttributes;\n} | null {\n for (const key of ['err', 'error'] as const) {\n const value = record[key];\n if (isSdkLogsExceptionCandidate(value)) {\n return {\n exception: value,\n excludedAttributes: [key],\n additionalAttributes: extractCauseAttributes(key, value),\n };\n }\n }\n\n const splat = record[Symbol.for('splat')];\n if (Array.isArray(splat)) {\n const splatException = splat.find(isSdkLogsExceptionCandidate);\n if (splatException !== undefined) {\n return {\n exception: splatException,\n excludedAttributes: [],\n };\n }\n }\n\n if (typeof record.stack === 'string') {\n const stackTypeMatch = /^([^:\\n]+):/.exec(record.stack);\n const exception: {\n code?: string | number;\n name?: string;\n message?: string;\n stack: string;\n } = {\n stack: record.stack,\n };\n if (typeof record.code === 'string' || typeof record.code === 'number') {\n exception.code = record.code;\n }\n if (typeof record.name === 'string') {\n exception.name = record.name;\n } else if (stackTypeMatch) {\n exception.name = stackTypeMatch[1];\n }\n if (typeof record.message === 'string') {\n exception.message = record.message;\n }\n return {\n exception,\n excludedAttributes: ['code', 'name', 'stack'],\n };\n }\n\n return null;\n}\n\nexport function emitLogRecord(\n record: Record<string | symbol, any>,\n logger: Logger\n): void {\n const { message, level, ...splat } = record;\n const attributes: LogAttributes = {};\n // Ensures the log level is read from a symbol property, avoiding any\n // accidental inclusion of ANSI color codes that may be present in the string\n // property.\n const levelSym = record[Symbol.for('level')];\n const exceptionPayload = getExceptionPayload(record);\n const excludedAttributes = new Set(\n exceptionPayload?.excludedAttributes ?? []\n );\n for (const key in splat) {\n if (\n Object.prototype.hasOwnProperty.call(splat, key) &&\n !excludedAttributes.has(key)\n ) {\n attributes[key] = splat[key];\n }\n }\n if (exceptionPayload?.additionalAttributes) {\n for (const key in exceptionPayload.additionalAttributes) {\n if (\n Object.prototype.hasOwnProperty.call(\n exceptionPayload.additionalAttributes,\n key\n )\n ) {\n attributes[key] = exceptionPayload.additionalAttributes[key];\n }\n }\n }\n const logRecord: LogRecord = {\n severityNumber: getSeverityNumber(levelSym),\n severityText: levelSym,\n body: message,\n attributes: attributes,\n ...(exceptionPayload ? { exception: exceptionPayload.exception } : {}),\n };\n logger.emit(logRecord);\n}\n"]}
@@ -1,3 +1,3 @@
1
- export declare const PACKAGE_VERSION = "0.27.0";
1
+ export declare const PACKAGE_VERSION = "0.29.0";
2
2
  export declare const PACKAGE_NAME = "@opentelemetry/winston-transport";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -6,6 +6,6 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.PACKAGE_NAME = exports.PACKAGE_VERSION = void 0;
8
8
  // this is autogenerated file, see scripts/version-update.js
9
- exports.PACKAGE_VERSION = '0.27.0';
9
+ exports.PACKAGE_VERSION = '0.29.0';
10
10
  exports.PACKAGE_NAME = '@opentelemetry/winston-transport';
11
11
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,4DAA4D;AAC/C,QAAA,eAAe,GAAG,QAAQ,CAAC;AAC3B,QAAA,YAAY,GAAG,kCAAkC,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// this is autogenerated file, see scripts/version-update.js\nexport const PACKAGE_VERSION = '0.27.0';\nexport const PACKAGE_NAME = '@opentelemetry/winston-transport';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,4DAA4D;AAC/C,QAAA,eAAe,GAAG,QAAQ,CAAC;AAC3B,QAAA,YAAY,GAAG,kCAAkC,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// this is autogenerated file, see scripts/version-update.js\nexport const PACKAGE_VERSION = '0.29.0';\nexport const PACKAGE_NAME = '@opentelemetry/winston-transport';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentelemetry/winston-transport",
3
- "version": "0.27.0",
3
+ "version": "0.29.0",
4
4
  "description": "OpenTelemetry Transport for winston",
5
5
  "main": "build/src/index.js",
6
6
  "types": "build/src/index.d.ts",
@@ -39,13 +39,13 @@
39
39
  "access": "public"
40
40
  },
41
41
  "devDependencies": {
42
- "@opentelemetry/sdk-logs": "^0.217.0",
42
+ "@opentelemetry/sdk-logs": "^0.219.0",
43
43
  "@types/triple-beam": "1.3.5"
44
44
  },
45
45
  "dependencies": {
46
- "@opentelemetry/api-logs": "^0.217.0",
46
+ "@opentelemetry/api-logs": "^0.219.0",
47
47
  "winston-transport": "4.*"
48
48
  },
49
49
  "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/winston-transport#readme",
50
- "gitHead": "b68fb6dcc0649631ebecab7bde81879486f74f0b"
50
+ "gitHead": "4e52a9053029304f271b7dbe1b07e7fb2b987e30"
51
51
  }