From 77f728a242ba112b3bc70c12a8d9d91259192c86 Mon Sep 17 00:00:00 2001 From: Thomas Hoppe Date: Fri, 21 May 2021 17:09:28 +0200 Subject: [PATCH] feat(logger): Add possibility to log source code reference --- packages/logger/README.md | 2 + packages/logger/package-lock.json | 171 +++++++++++++-------------- packages/logger/package.json | 10 +- packages/logger/src/console.ts | 60 ++++++---- packages/logger/src/elasticsearch.ts | 70 +++++------ packages/logger/src/file.ts | 4 +- packages/logger/src/index.ts | 7 +- packages/logger/src/utils.ts | 23 ++-- packages/logger/tests/test.ts | 1 + 9 files changed, 185 insertions(+), 163 deletions(-) diff --git a/packages/logger/README.md b/packages/logger/README.md index 01c62e15..b20479e3 100644 --- a/packages/logger/README.md +++ b/packages/logger/README.md @@ -20,6 +20,8 @@ These transports can be added and configured with a corresponding property in the options hash: ```json + "loggerName": "somelogger", // Optional name + "sourcePointer": true, // Whether the source file and line where the log statement was issued should be logged [default: `false`] "console": { "handleExceptions": false, "level": "silly", diff --git a/packages/logger/package-lock.json b/packages/logger/package-lock.json index f0db6029..272bd4dc 100644 --- a/packages/logger/package-lock.json +++ b/packages/logger/package-lock.json @@ -12,20 +12,20 @@ "cls-hooked": "^4.2.2", "cls-rtracer": "^2.6.0", "winston": "^3.3.3", - "winston-elasticsearch": "^0.15.2" + "winston-elasticsearch": "^0.15.4" }, "devDependencies": { - "@types/jest": "^26.0.20", - "@types/node": "^14.14.31", + "@types/jest": "^26.0.23", + "@types/node": "^15.3.0", "@types/should": "^13.0.0", "coveralls": "^3.1.0", "jest": "^26.6.3", "npm-run-all": "^4.1.5", "nyc": "^15.1.0", "rimraf": "^3.0.2", - "ts-jest": "^26.5.2", + "ts-jest": "^26.5.6", "tslint": "^6.1.3", - "typescript": "^4.2.2" + "typescript": "^4.2.4" }, "engines": { "node": ">= 12.18.0" @@ -920,20 +920,25 @@ } }, "node_modules/@elastic/elasticsearch": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-7.11.0.tgz", - "integrity": "sha512-AFVVuANIdbV1qYjuOi4hnsX/DehWYG+bbhQO4amq9K4/NnzU7mpGWOPgVlRQTiX+vBfBkx7SL6h4QEjIlM3ztA==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-7.12.0.tgz", + "integrity": "sha512-GquUEytCijFRPEk3DKkkDdyhspB3qbucVQOwih9uNyz3iz804I+nGBUsFo2LwVvLQmQfEM0IY2+yoYfEz5wMug==", "dependencies": { - "debug": "^4.1.1", + "debug": "^4.3.1", "hpagent": "^0.1.1", - "ms": "^2.1.1", + "ms": "^2.1.3", "pump": "^3.0.0", - "secure-json-parse": "^2.1.0" + "secure-json-parse": "^2.3.1" }, "engines": { - "node": ">=8" + "node": ">=10" } }, + "node_modules/@elastic/elasticsearch/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1738,9 +1743,9 @@ } }, "node_modules/@types/jest": { - "version": "26.0.20", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.20.tgz", - "integrity": "sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA==", + "version": "26.0.23", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", + "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", "dev": true, "dependencies": { "jest-diff": "^26.0.0", @@ -1748,9 +1753,9 @@ } }, "node_modules/@types/node": { - "version": "14.14.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", - "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.0.tgz", + "integrity": "sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==", "dev": true }, "node_modules/@types/normalize-package-data": { @@ -2872,11 +2877,19 @@ "integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==" }, "node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dependencies": { - "ms": "^2.1.1" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/decamelize": { @@ -8542,9 +8555,9 @@ } }, "node_modules/secure-json-parse": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.3.0.tgz", - "integrity": "sha512-kEyTf2cpnuqp7Aiem+yz3QWgm58pYbLlYg4TnVWChZkUBQTcolYZIYRQXmXvEtGJGJ532LREyc8d7pbu9utu7A==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.4.0.tgz", + "integrity": "sha512-Q5Z/97nbON5t/L/sH6mY2EacfjVGwrCcSi5D3btRO2GZ8pf1K1UN7Z9H5J57hjVU2Qzxr1xO+FmBhOvEkzCMmg==" }, "node_modules/semver": { "version": "5.7.1", @@ -9473,12 +9486,11 @@ "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, "node_modules/ts-jest": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.2.tgz", - "integrity": "sha512-bwyJ2zJieSugf7RB+o8fgkMeoMVMM2KPDE0UklRLuACxjwJsOrZNo6chrcScmK33YavPSwhARffy8dZx5LJdUQ==", + "version": "26.5.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", + "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", "dev": true, "dependencies": { - "@types/jest": "26.x", "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", @@ -9634,9 +9646,9 @@ } }, "node_modules/typescript": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.2.tgz", - "integrity": "sha512-tbb+NVrLfnsJy3M59lsDgrzWIflR4d4TIUjz+heUnHZwdF7YsrMTKoRERiIvI2lvBG95dfpLxB21WZhys1bgaQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -9919,11 +9931,11 @@ } }, "node_modules/winston-elasticsearch": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/winston-elasticsearch/-/winston-elasticsearch-0.15.2.tgz", - "integrity": "sha512-7v1D94cv1e0bNSbMUS0sQBxw+esJZ3XQOMjrRSXgqLk6BMUIkTgQXwCoUlBIcF/tfwPi+zgZsL9RwDwzDM+tbA==", + "version": "0.15.4", + "resolved": "https://registry.npmjs.org/winston-elasticsearch/-/winston-elasticsearch-0.15.4.tgz", + "integrity": "sha512-MtGqVILFzj3P8hWTIQvoT6baeslRwi8/U8y5mr7BSOpRynYejILpFhcfuGsnAvgIKAKBRUzOsDHJMGakJlpsKA==", "dependencies": { - "@elastic/elasticsearch": "^7.11.0", + "@elastic/elasticsearch": "^7.12.0", "dayjs": "^1.10.4", "debug": "^4.3.1", "lodash.defaults": "^4.2.0", @@ -9940,17 +9952,6 @@ "elastic-apm-node": "^3.9.0" } }, - "node_modules/winston-elasticsearch/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - } - }, "node_modules/winston-transport": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", @@ -10994,15 +10995,22 @@ } }, "@elastic/elasticsearch": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-7.11.0.tgz", - "integrity": "sha512-AFVVuANIdbV1qYjuOi4hnsX/DehWYG+bbhQO4amq9K4/NnzU7mpGWOPgVlRQTiX+vBfBkx7SL6h4QEjIlM3ztA==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-7.12.0.tgz", + "integrity": "sha512-GquUEytCijFRPEk3DKkkDdyhspB3qbucVQOwih9uNyz3iz804I+nGBUsFo2LwVvLQmQfEM0IY2+yoYfEz5wMug==", "requires": { - "debug": "^4.1.1", + "debug": "^4.3.1", "hpagent": "^0.1.1", - "ms": "^2.1.1", + "ms": "^2.1.3", "pump": "^3.0.0", - "secure-json-parse": "^2.1.0" + "secure-json-parse": "^2.3.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } } }, "@istanbuljs/load-nyc-config": { @@ -11679,9 +11687,9 @@ } }, "@types/jest": { - "version": "26.0.20", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.20.tgz", - "integrity": "sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA==", + "version": "26.0.23", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", + "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", "dev": true, "requires": { "jest-diff": "^26.0.0", @@ -11689,9 +11697,9 @@ } }, "@types/node": { - "version": "14.14.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", - "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.0.tgz", + "integrity": "sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==", "dev": true }, "@types/normalize-package-data": { @@ -12639,11 +12647,11 @@ "integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==" }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "decamelize": { @@ -17243,9 +17251,9 @@ } }, "secure-json-parse": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.3.0.tgz", - "integrity": "sha512-kEyTf2cpnuqp7Aiem+yz3QWgm58pYbLlYg4TnVWChZkUBQTcolYZIYRQXmXvEtGJGJ532LREyc8d7pbu9utu7A==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.4.0.tgz", + "integrity": "sha512-Q5Z/97nbON5t/L/sH6mY2EacfjVGwrCcSi5D3btRO2GZ8pf1K1UN7Z9H5J57hjVU2Qzxr1xO+FmBhOvEkzCMmg==" }, "semver": { "version": "5.7.1", @@ -18039,12 +18047,11 @@ "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, "ts-jest": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.2.tgz", - "integrity": "sha512-bwyJ2zJieSugf7RB+o8fgkMeoMVMM2KPDE0UklRLuACxjwJsOrZNo6chrcScmK33YavPSwhARffy8dZx5LJdUQ==", + "version": "26.5.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", + "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", "dev": true, "requires": { - "@types/jest": "26.x", "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", @@ -18161,9 +18168,9 @@ } }, "typescript": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.2.tgz", - "integrity": "sha512-tbb+NVrLfnsJy3M59lsDgrzWIflR4d4TIUjz+heUnHZwdF7YsrMTKoRERiIvI2lvBG95dfpLxB21WZhys1bgaQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", "dev": true }, "unicode-byte-truncate": { @@ -18397,11 +18404,11 @@ } }, "winston-elasticsearch": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/winston-elasticsearch/-/winston-elasticsearch-0.15.2.tgz", - "integrity": "sha512-7v1D94cv1e0bNSbMUS0sQBxw+esJZ3XQOMjrRSXgqLk6BMUIkTgQXwCoUlBIcF/tfwPi+zgZsL9RwDwzDM+tbA==", + "version": "0.15.4", + "resolved": "https://registry.npmjs.org/winston-elasticsearch/-/winston-elasticsearch-0.15.4.tgz", + "integrity": "sha512-MtGqVILFzj3P8hWTIQvoT6baeslRwi8/U8y5mr7BSOpRynYejILpFhcfuGsnAvgIKAKBRUzOsDHJMGakJlpsKA==", "requires": { - "@elastic/elasticsearch": "^7.11.0", + "@elastic/elasticsearch": "^7.12.0", "dayjs": "^1.10.4", "debug": "^4.3.1", "elastic-apm-node": "^3.9.0", @@ -18411,16 +18418,6 @@ "retry": "^0.12.0", "winston": "^3.3.3", "winston-transport": "^4.4.0" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - } } }, "winston-transport": { diff --git a/packages/logger/package.json b/packages/logger/package.json index 706dce08..f5b63c5a 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -19,20 +19,20 @@ "cls-hooked": "^4.2.2", "cls-rtracer": "^2.6.0", "winston": "^3.3.3", - "winston-elasticsearch": "^0.15.2" + "winston-elasticsearch": "^0.15.4" }, "devDependencies": { - "@types/jest": "^26.0.20", - "@types/node": "^14.14.31", + "@types/jest": "^26.0.23", + "@types/node": "^15.3.0", "@types/should": "^13.0.0", "coveralls": "^3.1.0", "jest": "^26.6.3", "npm-run-all": "^4.1.5", "nyc": "^15.1.0", "rimraf": "^3.0.2", - "ts-jest": "^26.5.2", + "ts-jest": "^26.5.6", "tslint": "^6.1.3", - "typescript": "^4.2.2" + "typescript": "^4.2.4" }, "scripts": { "build": "npm-run-all build:clean build:compile", diff --git a/packages/logger/src/console.ts b/packages/logger/src/console.ts index a527d394..cfb019bf 100644 --- a/packages/logger/src/console.ts +++ b/packages/logger/src/console.ts @@ -5,36 +5,54 @@ import { traceFormatter } from "./utils"; export interface RestoreLoggerConsoleTransportOptions extends transports.ConsoleTransportOptions { prettyPrint?: boolean | any; colorize?: boolean | any; + sourcePointer?: boolean; } // a custom format that outputs request id -const rTracerFormat = format.printf((info) => { - const rid = rTracer.id(); - const time = info.timestamp; - const level = info.level; - let message = info.message; - const splatSym: any = Object.getOwnPropertySymbols(info).find((s) => { - return String(s) === 'Symbol(splat)'; +function createTracerFormat(opts: RestoreLoggerConsoleTransportOptions) { + return format.printf((info) => { + const rid = rTracer.id(); + const time = info.timestamp; + const level = info.level; + let message = info.message; + const splatSym: any = Object.getOwnPropertySymbols(info).find((s) => { + return String(s) === 'Symbol(splat)'; + }); + const splat = info[splatSym]; + const sourceSym: any = Object.getOwnPropertySymbols(info).find((s) => { + return String(s) === 'Symbol(source)'; + }); + const source = info[sourceSym]; + const sourceFile = source.sourceFile; + const sourceLine = source.sourceLine; + + delete info.timestamp; + let object = {}; + if (splat) { + object = JSON.stringify(splat); + } + if (Object.entries(message).length !== 0 && message.constructor === Object) { + message = JSON.stringify(message); + } + let ret: string[] = []; + ret.push(`${level}: ${time}`); + if (opts.sourcePointer) { + ret.push(` ${sourceFile}:${sourceLine}`); + } + if (rid) { + ret.push(`[rid:${rid}]`); + } + ret.push(`: ${message} ${((object))}`); + + return ret.join(''); }); - const splat = info[splatSym]; - delete info.timestamp; - let object = ''; - if (splat) { - object = JSON.stringify(splat); - } - if (Object.entries(message).length !== 0 && message.constructor === Object) { - message = JSON.stringify(message); - } - return rid - ? `${level}: ${time} [rid:${rid}]: ${message} ${((object))}` - : `${level}: ${time}: ${message} ${(object)}`; -}); +} export function createConsoleTransport(opts: RestoreLoggerConsoleTransportOptions = {}) { let formats: any[] = [ format.simple(), format.timestamp(), - rTracerFormat + createTracerFormat(opts), ] if (opts.prettyPrint !== false) { diff --git a/packages/logger/src/elasticsearch.ts b/packages/logger/src/elasticsearch.ts index 9f32b391..e7c434f6 100644 --- a/packages/logger/src/elasticsearch.ts +++ b/packages/logger/src/elasticsearch.ts @@ -5,46 +5,50 @@ import { getRealTrace } from "./utils"; export const indexTemplate = require('../elasticsearch-index-template.json'); -/** - Transformer function to transform logged data into a - the message structure used in restore for storage in ES. +function createTransformer(opts: RestoreLoggerElasticsearchTransportOptions) { + /** + Transformer function to transform logged data into a + the message structure used in restore for storage in ES. - @param {Object} logData - @param {Object} logData.message - the log message - @param {Object} logData.level - the log level - @param {Object} logData.meta - the log meta data - @returns {Object} transformed message - */ -const transformer: Transformer = (logData) => { - const transformed: any = {}; - // set rid if it exists - if (rTracer.id()) { - transformed.rid = rTracer.id(); - } + @param {Object} logData + @param {Object} logData.message - the log message + @param {Object} logData.level - the log level + @param {Object} logData.meta - the log meta data + @returns {Object} transformed message + */ + return (logData: any) => { + const source = opts.source; // will be read internally + const transformed: any = {}; + // set rid if it exists + if (rTracer.id()) { + transformed.rid = rTracer.id(); + } - if (logData.level === 'error') { - logData.meta.source = getRealTrace(); - } + if (opts.sourcePointer) { + logData.meta.source = getRealTrace(); + } - transformed['@timestamp'] = new Date().toISOString(); - transformed.source_host = os.hostname(); - transformed.message = logData.message; - if (typeof transformed.message === 'object') { - transformed.message = JSON.stringify(transformed.message); - } - transformed.severity = logData.level; - transformed.fields = logData.meta; - if (typeof transformed.fields !== 'object') { - transformed.fields = { 0: transformed.fields }; - } - return transformed; -}; + transformed['@timestamp'] = new Date().toISOString(); + transformed.source_host = os.hostname(); + transformed.message = logData.message; + if (typeof transformed.message === 'object') { + transformed.message = JSON.stringify(transformed.message); + } + transformed.severity = logData.level; + transformed.fields = logData.meta; + if (typeof transformed.fields !== 'object') { + transformed.fields = { 0: transformed.fields }; + } + return transformed; + }; +} export interface RestoreLoggerElasticsearchTransportOptions extends ElasticsearchTransportOptions { - source?: any; + sourcePointer?: any; } + export function createElasticSearchTransport(opts: RestoreLoggerElasticsearchTransportOptions) { - (transformer as any)['source'] = opts.source; + const transformer = createTransformer(opts); return new ElasticsearchTransport({ indexTemplate, transformer, diff --git a/packages/logger/src/file.ts b/packages/logger/src/file.ts index eff75de5..3f992674 100644 --- a/packages/logger/src/file.ts +++ b/packages/logger/src/file.ts @@ -1,6 +1,8 @@ import { transports } from "winston"; -export interface RestoreLoggerFileTransportOptions extends transports.FileTransportOptions { } +export interface RestoreLoggerFileTransportOptions extends transports.FileTransportOptions { + sourcePointer?: boolean; +} export function createFileTransport(opts: RestoreLoggerFileTransportOptions) { return new transports.File({ diff --git a/packages/logger/src/index.ts b/packages/logger/src/index.ts index 6e14d014..e1ec2d41 100644 --- a/packages/logger/src/index.ts +++ b/packages/logger/src/index.ts @@ -8,6 +8,7 @@ export interface RestoreLoggerOptions extends WinstonLoggerOptions { file?: RestoreLoggerFileTransportOptions; elasticsearch?: RestoreLoggerElasticsearchTransportOptions; loggerName?: string; + sourcePointer?: boolean; } export type TransportStreamArray = Logger['transports']; @@ -25,14 +26,14 @@ export function createLogger(opts: RestoreLoggerOptions = {}) { } if (opts.console) { - transports.push(createConsoleTransport(opts.console)); + transports.push(createConsoleTransport({ ...opts.console, sourcePointer: opts.sourcePointer })); } if (opts.file) { - transports.push(createFileTransport(opts.file)); + transports.push(createFileTransport({ ...opts.file, sourcePointer: opts.sourcePointer })); } if (opts.elasticsearch) { opts.elasticsearch.dataStream = true; - transports.push(createElasticSearchTransport(opts.elasticsearch)); + transports.push(createElasticSearchTransport({ ...opts.elasticsearch, sourcePointer: opts.sourcePointer })); } if (transports.length === 0) { transports.push(createConsoleTransport()); diff --git a/packages/logger/src/utils.ts b/packages/logger/src/utils.ts index 26c83c3d..c932d2b6 100644 --- a/packages/logger/src/utils.ts +++ b/packages/logger/src/utils.ts @@ -6,8 +6,8 @@ const parse = (stack: string): any[] => { .map((line: string) => { if (line.match(/^\s*[-]{4,}$/)) { return { - fileName: line, - lineNumber: null, + file: line, + line: null, functionName: null, typeName: null, methodName: null, @@ -58,8 +58,8 @@ const parse = (stack: string): any[] => { } return { - fileName: lineMatch[2] || null, - lineNumber: parseInt(lineMatch[3], 10) || null, + file: lineMatch[2] || null, + line: parseInt(lineMatch[3], 10) || null, functionName: functionName, typeName: typeName, methodName: methodName, @@ -85,13 +85,10 @@ export const getStackTrace = (obj?: any) => { } export const traceFormatter = format((info, opts) => { - if (info.level === 'error') { - if (!(info as any)[Symbol.for('splat')]) { - (info as any)[Symbol.for('splat')] = []; - } - (info as any)[Symbol.for('splat')].push(getRealTrace()); + if (!(info as any)[Symbol.for('source')]) { + (info as any)[Symbol.for('source')] = {}; } - + (info as any)[Symbol.for('source')] = getRealTrace(); return info; }); @@ -101,11 +98,11 @@ const ignoredList = ['node:events', 'events.js']; export const getRealTrace = (): any => { const stackTrace = parse(getStackTrace()); const sourceTrace = stackTrace.slice(4) - .find(t => !t['native'] && t.fileName.indexOf('/') >= 0 && !t.fileName.match(ignoredRegex) && ignoredList.indexOf(t.fileName) < 0); + .find(t => !t['native'] && t.file.indexOf('/') >= 0 && !t.file.match(ignoredRegex) && ignoredList.indexOf(t.file) < 0); const resultTrace: any = { - fileName: sourceTrace.fileName, - lineNumber: sourceTrace.lineNumber + file: sourceTrace.file, + line: sourceTrace.line } if (sourceTrace.functionName) { diff --git a/packages/logger/tests/test.ts b/packages/logger/tests/test.ts index 38b2784c..d977e67e 100644 --- a/packages/logger/tests/test.ts +++ b/packages/logger/tests/test.ts @@ -1,6 +1,7 @@ import { createLogger, RestoreLoggerOptions } from '../src/index'; const opts: RestoreLoggerOptions = { + sourcePointer: true, loggerName: 'test', console: { handleExceptions: false,