From 240484751abc835f90ad08a40f280a03705a86ae Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Fri, 12 May 2023 17:22:43 +0800 Subject: [PATCH 01/15] feat(logging): add `getLogger` and remove sentry transports --- package-lock.json | 215 ++++++------------- package.json | 3 +- src/common/logger.ts | 110 ++++------ src/common/utils/exportSchema.ts | 3 +- src/common/utils/generateTypes.ts | 3 +- src/common/utils/getLanguage.ts | 3 +- src/common/utils/getViewer.ts | 3 +- src/common/utils/updateWordCount.ts | 3 +- src/connectors/baseService.ts | 4 +- src/connectors/exchangeRate/index.ts | 3 +- src/connectors/gcp/index.ts | 3 +- src/connectors/likecoin/index.ts | 3 +- src/connectors/medium/index.ts | 3 +- src/connectors/notificationService/index.ts | 3 +- src/connectors/notificationService/notice.ts | 12 +- src/connectors/oauthService.ts | 3 +- src/connectors/opensea/index.ts | 3 +- src/connectors/paymentService.ts | 3 +- src/connectors/queue/appreciation.ts | 3 +- src/connectors/queue/asset.ts | 3 +- src/connectors/queue/baseQueue.ts | 3 +- src/connectors/queue/ipfs.ts | 3 +- src/connectors/queue/migration.ts | 3 +- src/connectors/queue/payTo/matters.ts | 3 +- src/connectors/queue/payout.ts | 3 +- src/connectors/queue/publication.ts | 3 +- src/connectors/queue/user.ts | 3 +- src/connectors/queue/utils.ts | 3 +- src/connectors/slack/index.ts | 3 +- src/connectors/stripe/index.ts | 3 +- src/connectors/systemService.ts | 7 +- src/connectors/tagService.ts | 1 + src/connectors/userService.ts | 3 +- src/middlewares/sentry.ts | 3 +- src/mutations/article/readArticle.ts | 51 +---- src/mutations/oauthClient/putOAuthClient.ts | 3 +- src/mutations/user/sendVerificationCode.ts | 3 +- src/mutations/user/updateUserInfo.ts | 3 +- src/mutations/user/updateUserRole.ts | 3 +- src/queries/article/canSuperLike.ts | 3 +- src/queries/article/index.ts | 3 +- src/queries/article/translation.ts | 3 +- src/queries/user/appreciation.ts | 3 +- src/queries/user/liker/rateUSD.ts | 3 +- src/routes/graphql.ts | 3 +- src/routes/oauth/index.ts | 3 +- src/routes/oauth/strategies.ts | 3 +- src/routes/pay/likecoin.ts | 3 +- src/routes/pay/stripe/circle.ts | 3 +- src/routes/pay/stripe/connect/index.ts | 3 +- src/routes/pay/stripe/index.ts | 4 +- 51 files changed, 214 insertions(+), 319 deletions(-) diff --git a/package-lock.json b/package-lock.json index 510248dc9..6732bbabf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "matters-server", - "version": "4.18.0", + "version": "4.19.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "matters-server", - "version": "4.18.0", + "version": "4.19.0", "license": "Apache-2.0", "dependencies": { "@ethersproject/abstract-provider": "^5.7.0", @@ -19,7 +19,7 @@ "@matters/passport-likecoin": "^1.0.0", "@matters/slugify": "^0.7.3", "@sendgrid/mail": "^7.4.5", - "@sentry/node": "^6.16.1", + "@sentry/node": "^7.51.2", "@slack/web-api": "^6.5.1", "apollo-cache-control": "^0.11.1", "apollo-datasource": "^3.0.2", @@ -81,7 +81,6 @@ "uuid": "^8.3.2", "validator": "^13.7.0", "winston": "^3.3.3", - "winston-transport": "^4.4.0", "xss": "^1.0.9" }, "devDependencies": { @@ -3558,79 +3557,59 @@ "node": "6.* || 8.* || >=10.*" } }, - "node_modules/@sentry/core": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.16.1.tgz", - "integrity": "sha512-UFI0264CPUc5cR1zJH+S2UPOANpm6dLJOnsvnIGTjsrwzR0h8Hdl6rC2R/GPq+WNbnipo9hkiIwDlqbqvIU5vw==", - "dependencies": { - "@sentry/hub": "6.16.1", - "@sentry/minimal": "6.16.1", - "@sentry/types": "6.16.1", - "@sentry/utils": "6.16.1", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/core/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/hub": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.16.1.tgz", - "integrity": "sha512-4PGtg6AfpqMkreTpL7ymDeQ/U1uXv03bKUuFdtsSTn/FRf9TLS4JB0KuTZCxfp1IRgAA+iFg6B784dDkT8R9eg==", + "node_modules/@sentry-internal/tracing": { + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.51.2.tgz", + "integrity": "sha512-OBNZn7C4CyocmlSMUPfkY9ORgab346vTHu5kX35PgW5XR51VD2nO5iJCFbyFcsmmRWyCJcZzwMNARouc2V4V8A==", "dependencies": { - "@sentry/types": "6.16.1", - "@sentry/utils": "6.16.1", + "@sentry/core": "7.51.2", + "@sentry/types": "7.51.2", + "@sentry/utils": "7.51.2", "tslib": "^1.9.3" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/@sentry/hub/node_modules/tslib": { + "node_modules/@sentry-internal/tracing/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/@sentry/minimal": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.16.1.tgz", - "integrity": "sha512-dq+mI1EQIvUM+zJtGCVgH3/B3Sbx4hKlGf2Usovm9KoqWYA+QpfVBholYDe/H2RXgO7LFEefDLvOdHDkqeJoyA==", + "node_modules/@sentry/core": { + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.51.2.tgz", + "integrity": "sha512-p8ZiSBxpKe+rkXDMEcgmdoyIHM/1bhpINLZUFPiFH8vzomEr7sgnwRhyrU8y/ADnkPeNg/2YF3QpDpk0OgZJUA==", "dependencies": { - "@sentry/hub": "6.16.1", - "@sentry/types": "6.16.1", + "@sentry/types": "7.51.2", + "@sentry/utils": "7.51.2", "tslib": "^1.9.3" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/@sentry/minimal/node_modules/tslib": { + "node_modules/@sentry/core/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/node": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.16.1.tgz", - "integrity": "sha512-SeDDoug2kUxeF1D7JGPa3h5EXxKtmA01mITBPYx5xbJ0sMksnv5I5bC1SJ8arRRzq6+W1C4IEeDBQtrVCk6ixA==", - "dependencies": { - "@sentry/core": "6.16.1", - "@sentry/hub": "6.16.1", - "@sentry/tracing": "6.16.1", - "@sentry/types": "6.16.1", - "@sentry/utils": "6.16.1", + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.51.2.tgz", + "integrity": "sha512-qtZ2xNVR0ZW+OZWb0Xw0Cdh2QJXOJkXjK84CGC2P4Y6jWrt+GVvwMANPItLT6mAh+ITszTJ5Gk5HHFRpYme5EA==", + "dependencies": { + "@sentry-internal/tracing": "7.51.2", + "@sentry/core": "7.51.2", + "@sentry/types": "7.51.2", + "@sentry/utils": "7.51.2", "cookie": "^0.4.1", "https-proxy-agent": "^5.0.0", "lru_map": "^0.3.3", "tslib": "^1.9.3" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/@sentry/node/node_modules/tslib": { @@ -3638,44 +3617,24 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/@sentry/tracing": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.16.1.tgz", - "integrity": "sha512-MPSbqXX59P+OEeST+U2V/8Hu/8QjpTUxTNeNyTHWIbbchdcMMjDbXTS3etCgajZR6Ro+DHElOz5cdSxH6IBGlA==", - "dependencies": { - "@sentry/hub": "6.16.1", - "@sentry/minimal": "6.16.1", - "@sentry/types": "6.16.1", - "@sentry/utils": "6.16.1", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/tracing/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/@sentry/types": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.16.1.tgz", - "integrity": "sha512-Wh354g30UsJ5kYJbercektGX4ZMc9MHU++1NjeN2bTMnbofEcpUDWIiKeulZEY65IC1iU+1zRQQgtYO+/hgCUQ==", + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.51.2.tgz", + "integrity": "sha512-/hLnZVrcK7G5BQoD/60u9Qak8c9AvwV8za8TtYPJDUeW59GrqnqOkFji7RVhI7oH1OX4iBxV+9pAKzfYE6A6SA==", "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/@sentry/utils": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.16.1.tgz", - "integrity": "sha512-7ngq/i4R8JZitJo9Sl8PDnjSbDehOxgr1vsoMmerIsyRZ651C/8B+jVkMhaAPgSdyJ0AlE3O7DKKTP1FXFw9qw==", + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.51.2.tgz", + "integrity": "sha512-EcjBU7qG4IG+DpIPvdgIBcdIofROMawKoRUNKraeKzH/waEYH9DzCaqp/mzc5/rPBhpDB4BShX9xDDSeH+8c0A==", "dependencies": { - "@sentry/types": "6.16.1", + "@sentry/types": "7.51.2", "tslib": "^1.9.3" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/@sentry/utils/node_modules/tslib": { @@ -13392,7 +13351,7 @@ "node_modules/lru_map": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" }, "node_modules/lru-cache": { "version": "6.0.0", @@ -21472,32 +21431,14 @@ "@sendgrid/helpers": "^7.4.3" } }, - "@sentry/core": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.16.1.tgz", - "integrity": "sha512-UFI0264CPUc5cR1zJH+S2UPOANpm6dLJOnsvnIGTjsrwzR0h8Hdl6rC2R/GPq+WNbnipo9hkiIwDlqbqvIU5vw==", - "requires": { - "@sentry/hub": "6.16.1", - "@sentry/minimal": "6.16.1", - "@sentry/types": "6.16.1", - "@sentry/utils": "6.16.1", - "tslib": "^1.9.3" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@sentry/hub": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.16.1.tgz", - "integrity": "sha512-4PGtg6AfpqMkreTpL7ymDeQ/U1uXv03bKUuFdtsSTn/FRf9TLS4JB0KuTZCxfp1IRgAA+iFg6B784dDkT8R9eg==", + "@sentry-internal/tracing": { + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.51.2.tgz", + "integrity": "sha512-OBNZn7C4CyocmlSMUPfkY9ORgab346vTHu5kX35PgW5XR51VD2nO5iJCFbyFcsmmRWyCJcZzwMNARouc2V4V8A==", "requires": { - "@sentry/types": "6.16.1", - "@sentry/utils": "6.16.1", + "@sentry/core": "7.51.2", + "@sentry/types": "7.51.2", + "@sentry/utils": "7.51.2", "tslib": "^1.9.3" }, "dependencies": { @@ -21508,13 +21449,13 @@ } } }, - "@sentry/minimal": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.16.1.tgz", - "integrity": "sha512-dq+mI1EQIvUM+zJtGCVgH3/B3Sbx4hKlGf2Usovm9KoqWYA+QpfVBholYDe/H2RXgO7LFEefDLvOdHDkqeJoyA==", + "@sentry/core": { + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.51.2.tgz", + "integrity": "sha512-p8ZiSBxpKe+rkXDMEcgmdoyIHM/1bhpINLZUFPiFH8vzomEr7sgnwRhyrU8y/ADnkPeNg/2YF3QpDpk0OgZJUA==", "requires": { - "@sentry/hub": "6.16.1", - "@sentry/types": "6.16.1", + "@sentry/types": "7.51.2", + "@sentry/utils": "7.51.2", "tslib": "^1.9.3" }, "dependencies": { @@ -21526,15 +21467,14 @@ } }, "@sentry/node": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.16.1.tgz", - "integrity": "sha512-SeDDoug2kUxeF1D7JGPa3h5EXxKtmA01mITBPYx5xbJ0sMksnv5I5bC1SJ8arRRzq6+W1C4IEeDBQtrVCk6ixA==", - "requires": { - "@sentry/core": "6.16.1", - "@sentry/hub": "6.16.1", - "@sentry/tracing": "6.16.1", - "@sentry/types": "6.16.1", - "@sentry/utils": "6.16.1", + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.51.2.tgz", + "integrity": "sha512-qtZ2xNVR0ZW+OZWb0Xw0Cdh2QJXOJkXjK84CGC2P4Y6jWrt+GVvwMANPItLT6mAh+ITszTJ5Gk5HHFRpYme5EA==", + "requires": { + "@sentry-internal/tracing": "7.51.2", + "@sentry/core": "7.51.2", + "@sentry/types": "7.51.2", + "@sentry/utils": "7.51.2", "cookie": "^0.4.1", "https-proxy-agent": "^5.0.0", "lru_map": "^0.3.3", @@ -21548,36 +21488,17 @@ } } }, - "@sentry/tracing": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.16.1.tgz", - "integrity": "sha512-MPSbqXX59P+OEeST+U2V/8Hu/8QjpTUxTNeNyTHWIbbchdcMMjDbXTS3etCgajZR6Ro+DHElOz5cdSxH6IBGlA==", - "requires": { - "@sentry/hub": "6.16.1", - "@sentry/minimal": "6.16.1", - "@sentry/types": "6.16.1", - "@sentry/utils": "6.16.1", - "tslib": "^1.9.3" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, "@sentry/types": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.16.1.tgz", - "integrity": "sha512-Wh354g30UsJ5kYJbercektGX4ZMc9MHU++1NjeN2bTMnbofEcpUDWIiKeulZEY65IC1iU+1zRQQgtYO+/hgCUQ==" + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.51.2.tgz", + "integrity": "sha512-/hLnZVrcK7G5BQoD/60u9Qak8c9AvwV8za8TtYPJDUeW59GrqnqOkFji7RVhI7oH1OX4iBxV+9pAKzfYE6A6SA==" }, "@sentry/utils": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.16.1.tgz", - "integrity": "sha512-7ngq/i4R8JZitJo9Sl8PDnjSbDehOxgr1vsoMmerIsyRZ651C/8B+jVkMhaAPgSdyJ0AlE3O7DKKTP1FXFw9qw==", + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.51.2.tgz", + "integrity": "sha512-EcjBU7qG4IG+DpIPvdgIBcdIofROMawKoRUNKraeKzH/waEYH9DzCaqp/mzc5/rPBhpDB4BShX9xDDSeH+8c0A==", "requires": { - "@sentry/types": "6.16.1", + "@sentry/types": "7.51.2", "tslib": "^1.9.3" }, "dependencies": { @@ -29017,7 +28938,7 @@ "lru_map": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" }, "lru-cache": { "version": "6.0.0", diff --git a/package.json b/package.json index 0ce5c9d4f..8e17702a7 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@matters/passport-likecoin": "^1.0.0", "@matters/slugify": "^0.7.3", "@sendgrid/mail": "^7.4.5", - "@sentry/node": "^6.16.1", + "@sentry/node": "^7.51.2", "@slack/web-api": "^6.5.1", "apollo-cache-control": "^0.11.1", "apollo-datasource": "^3.0.2", @@ -109,7 +109,6 @@ "uuid": "^8.3.2", "validator": "^13.7.0", "winston": "^3.3.3", - "winston-transport": "^4.4.0", "xss": "^1.0.9" }, "devDependencies": { diff --git a/src/common/logger.ts b/src/common/logger.ts index bd04122e6..1957fd04f 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -1,52 +1,7 @@ -import * as Sentry from '@sentry/node' -import * as fs from 'fs' import _get from 'lodash/get' -import * as path from 'path' import { createLogger, format, transports } from 'winston' -import Transport from 'winston-transport' -import { isProd, isTest } from 'common/environment' - -const logPath = 'logs' - -// create logs dir if it does not exist -if (!fs.existsSync(logPath)) { - fs.mkdirSync(logPath) -} - -/** - * Custom winston transport for Sentry. - * - */ -class SentryTransport extends Transport { - constructor(opts?: Transport.TransportStreamOptions) { - super(opts) - } - - log(info: any, next: () => void) { - if (info.level === 'error') { - const code = _get(info, 'extensions.code') - - switch (code) { - case 'CODE_EXPIRED': - case 'UNAUTHENTICATED': - case 'USER_EMAIL_NOT_FOUND': - case 'USER_USERNAME_EXISTS': - case 'USER_PASSWORD_INVALID': { - // Ingore errors - break - } - default: { - const sentryError = new Error(info.message) - sentryError.stack = info.stack - Sentry.captureException(sentryError) - break - } - } - } - next() - } -} +// import { isProd } from 'common/environment' /** * Simple format outputs: @@ -54,34 +9,41 @@ class SentryTransport extends Transport { * YYYY-MM-DD HH:mm:ss `${level}: ${message} ${[object]}` * */ -const logger = createLogger({ - level: 'info', - format: format.combine( - format.errors({ stack: true }), - format.timestamp({ - format: 'YYYY-MM-DD HH:mm:ss', - }), - format.printf( - (info) => - `${info.timestamp} ${info.level}: ${JSON.stringify(info.message)}` - ) - ), - transports: [ - new transports.File({ - filename: path.join(logPath, 'error.log'), - level: 'error', - }), - new transports.File({ filename: path.join(logPath, 'combined.log') }), - new SentryTransport({ level: 'error' }), - ], + +const getContext = format((info, _) => { + info.context = { requestId: 'test-request-id' } + return info }) -if (!isProd) { - logger.add( - new transports.Console({ - level: isTest ? 'warn' : 'info', - }) - ) +const createWinstonLogger = (name: string) => + createLogger({ + level: 'info', + format: format.combine( + format.splat(), + getContext(), + format.label({ label: name }), + format.errors({ stack: true }), + format.timestamp({ + format: 'YYYY-MM-DD HH:mm:ss', + }), + format.printf( + (info) => + `${info.timestamp} ${info.label} ${info.context.requestId} ${ + info.level + }: ${JSON.stringify(info.message)}` + ) + ), + transports: [new transports.Console({ level: 'info' })], + }) + +const loggers = new Map() + +export const getLogger = (name: string) => { + const logger = loggers.get(name) + if (logger) { + return logger + } + const newLogger = createWinstonLogger(name) + loggers.set(name, newLogger) + return newLogger } - -export default logger diff --git a/src/common/utils/exportSchema.ts b/src/common/utils/exportSchema.ts index b24fead41..0f77b65e6 100644 --- a/src/common/utils/exportSchema.ts +++ b/src/common/utils/exportSchema.ts @@ -3,8 +3,9 @@ import fs from 'fs' import { printSchema } from 'graphql' import 'module-alias/register' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import typeDefs from 'types' +const logger = getLogger('default') const schemaObj = makeExecutableSchema({ typeDefs, diff --git a/src/common/utils/generateTypes.ts b/src/common/utils/generateTypes.ts index a900c8bfd..971c428b2 100644 --- a/src/common/utils/generateTypes.ts +++ b/src/common/utils/generateTypes.ts @@ -2,7 +2,8 @@ import fs from 'fs' import { generateTypeScriptTypes } from 'graphql-schema-typescript' import 'module-alias/register' -import logger from 'common/logger' +import { getLogger } from 'common/logger' +const logger = getLogger('default') const schema = fs.readFileSync('schema.graphql', { encoding: 'utf8' }) diff --git a/src/common/utils/getLanguage.ts b/src/common/utils/getLanguage.ts index f5326c6ac..ac7800a3b 100644 --- a/src/common/utils/getLanguage.ts +++ b/src/common/utils/getLanguage.ts @@ -1,7 +1,8 @@ import _ from 'lodash' import { LANGUAGE } from 'common/enums' -import logger from 'common/logger' +import { getLogger } from 'common/logger' +const logger = getLogger('default') // map supported language to header language export const langMap = { diff --git a/src/common/utils/getViewer.ts b/src/common/utils/getViewer.ts index 61e486411..79f278612 100644 --- a/src/common/utils/getViewer.ts +++ b/src/common/utils/getViewer.ts @@ -11,10 +11,11 @@ import { } from 'common/enums' import { environment } from 'common/environment' import { ForbiddenByStateError, TokenInvalidError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { clearCookie, getLanguage } from 'common/utils' import { OAuthService, SystemService, UserService } from 'connectors' import { Viewer } from 'definitions' +const logger = getLogger('default') export const roleAccess = [USER_ROLE.visitor, USER_ROLE.user, USER_ROLE.admin] export const authModes = [ diff --git a/src/common/utils/updateWordCount.ts b/src/common/utils/updateWordCount.ts index b8c744122..1d2d164a6 100644 --- a/src/common/utils/updateWordCount.ts +++ b/src/common/utils/updateWordCount.ts @@ -1,9 +1,10 @@ import 'module-alias/register' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { ArticleService, DraftService } from 'connectors' import { countWords } from './content' +const logger = getLogger('default') async function main() { const articleIds = process.argv.slice(2) diff --git a/src/connectors/baseService.ts b/src/connectors/baseService.ts index cb4109fdf..f78b51393 100644 --- a/src/connectors/baseService.ts +++ b/src/connectors/baseService.ts @@ -3,10 +3,12 @@ import DataLoader from 'dataloader' import { Knex } from 'knex' import _ from 'lodash' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { aws, cfsvc, knex, readonlyKnex, searchKnexDB } from 'connectors' import { Item, ItemData, TableName } from 'definitions' +const logger = getLogger('default') + export class BaseService extends DataSource { aws: typeof aws cfsvc: typeof cfsvc diff --git a/src/connectors/exchangeRate/index.ts b/src/connectors/exchangeRate/index.ts index 2d04c0ae8..23a0eac6c 100644 --- a/src/connectors/exchangeRate/index.ts +++ b/src/connectors/exchangeRate/index.ts @@ -3,8 +3,9 @@ import axios from 'axios' import { CACHE_TTL } from 'common/enums' import { environment } from 'common/environment' import { NetworkError, UnknownError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { CacheService } from 'connectors' +const logger = getLogger('default') // TYPES diff --git a/src/connectors/gcp/index.ts b/src/connectors/gcp/index.ts index 469ef744a..b8bfc043b 100644 --- a/src/connectors/gcp/index.ts +++ b/src/connectors/gcp/index.ts @@ -4,7 +4,8 @@ import axios from 'axios' import { LANGUAGE } from 'common/enums' import { environment, isTest } from 'common/environment' import { ActionFailedError, UserInputError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' +const logger = getLogger('default') const { zh_hans, zh_hant, en } = LANGUAGE diff --git a/src/connectors/likecoin/index.ts b/src/connectors/likecoin/index.ts index 847e1e208..393b0afd4 100644 --- a/src/connectors/likecoin/index.ts +++ b/src/connectors/likecoin/index.ts @@ -11,9 +11,10 @@ import { LikerUserIdExistsError, OAuthTokenInvalidError, } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { aws, CacheService, knex } from 'connectors' import { UserOAuthLikeCoin } from 'definitions' +const logger = getLogger('default') interface LikeData { likerId: string diff --git a/src/connectors/medium/index.ts b/src/connectors/medium/index.ts index f2c15aa91..cec63f724 100644 --- a/src/connectors/medium/index.ts +++ b/src/connectors/medium/index.ts @@ -8,11 +8,12 @@ import { ACCEPTED_UPLOAD_IMAGE_TYPES, UPLOAD_FILE_SIZE_LIMIT, } from 'common/enums' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { getFileName } from 'common/utils' import { aws, cfsvc, knex } from 'connectors' import { AWSService } from 'connectors/aws' import { GQLAssetType } from 'definitions' +const logger = getLogger('default') const throttle = pThrottle({ limit: 2, diff --git a/src/connectors/notificationService/index.ts b/src/connectors/notificationService/index.ts index 71a01ca18..8f1705ef6 100644 --- a/src/connectors/notificationService/index.ts +++ b/src/connectors/notificationService/index.ts @@ -3,7 +3,7 @@ import { DB_NOTICE_TYPE, OFFICIAL_NOTICE_EXTEND_TYPE, } from 'common/enums' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { BaseService, UserService } from 'connectors' import { LANGUAGES, @@ -15,6 +15,7 @@ import { import { mail } from './mail' import { notice } from './notice' import trans from './translations' +const logger = getLogger('default') export class NotificationService extends BaseService { mail: typeof mail diff --git a/src/connectors/notificationService/notice.ts b/src/connectors/notificationService/notice.ts index f2b5097ce..70aede866 100644 --- a/src/connectors/notificationService/notice.ts +++ b/src/connectors/notificationService/notice.ts @@ -3,7 +3,7 @@ import { isArray, isEqual, mergeWith, uniq } from 'lodash' import { v4 } from 'uuid' import { DB_NOTICE_TYPE } from 'common/enums' -// import logger from 'common/logger' +import { getLogger } from 'common/logger' import { BaseService } from 'connectors' import { GQLNotificationSettingType, @@ -19,6 +19,8 @@ import { User, } from 'definitions' +const logger = getLogger('service:notice') + export type DBNotificationSettingType = keyof typeof GQLNotificationSettingType const mergeDataCustomizer = (objValue: any, srcValue: any) => { @@ -58,7 +60,6 @@ class Notice extends BaseService { }) .into('notice_detail') .returning('*') - // logger.info(`Inserted id ${noticeDetailId} to notice_detail`) // create notice const [{ id: noticeId }] = await trx @@ -69,7 +70,6 @@ class Notice extends BaseService { }) .into('notice') .returning('*') - // logger.info(`Inserted id ${noticeId} to notice`) // create notice actorId if (actorId) { @@ -81,7 +81,6 @@ class Notice extends BaseService { }) .into('notice_actor') .returning('*') - // logger.info(`Inserted id ${noticeActorId} to notice_actor`) } // craete notice entities @@ -98,7 +97,6 @@ class Notice extends BaseService { .from('entity_type') .where({ table: entityTable }) .first() - // const [{ id: noticeEntityId }] = await trx .insert({ type: entityType, @@ -108,7 +106,6 @@ class Notice extends BaseService { }) .into('notice_entity') .returning('*') - // logger.info(`Inserted id ${noticeEntityId} to notice_entity`) } ) ) @@ -137,13 +134,12 @@ class Notice extends BaseService { .returning('*') .onConflict(['actor_id', 'notice_id']) .ignore() // .merge({ updatedAt: this.knex.fn.now(), }) - // logger.info(`[addNoticeActor] Inserted id ${noticeActorId} to notice_actor`) // update notice await trx('notice') .where({ id: noticeId }) .update({ unread: true, updatedAt: this.knex.fn.now() }) - // logger.info(`[addNoticeActor] Updated id ${noticeId} in notice`) + logger.info(`updated id %s in notice`, noticeId) }) } diff --git a/src/connectors/oauthService.ts b/src/connectors/oauthService.ts index 2c67ce0df..e2eecfee1 100644 --- a/src/connectors/oauthService.ts +++ b/src/connectors/oauthService.ts @@ -7,7 +7,7 @@ import { OAUTH_REFRESH_TOKEN_EXPIRES_IN_MS, } from 'common/enums' import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { isScopeAllowed, toGlobalId } from 'common/utils' import { BaseService, UserService } from 'connectors' import { @@ -18,6 +18,7 @@ import { OAuthToken, User, } from 'definitions' +const logger = getLogger('default') export class OAuthService extends BaseService { constructor() { diff --git a/src/connectors/opensea/index.ts b/src/connectors/opensea/index.ts index ad6eff267..4c0a117b7 100644 --- a/src/connectors/opensea/index.ts +++ b/src/connectors/opensea/index.ts @@ -2,7 +2,8 @@ import { RequestOptions, RESTDataSource } from 'apollo-datasource-rest' import { CACHE_TTL } from 'common/enums' import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' +const logger = getLogger('default') export class OpenSeaService extends RESTDataSource { apiKey?: string | undefined diff --git a/src/connectors/paymentService.ts b/src/connectors/paymentService.ts index 4f94b2579..2df410da0 100644 --- a/src/connectors/paymentService.ts +++ b/src/connectors/paymentService.ts @@ -19,12 +19,13 @@ import { } from 'common/enums' import { isProd } from 'common/environment' import { ServerError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { getUTC8Midnight, numRound } from 'common/utils' import { AtomService, BaseService, NotificationService } from 'connectors' import { CirclePrice, GQLChain, Transaction, User } from 'definitions' import { stripe } from './stripe' +const logger = getLogger('default') export class PaymentService extends BaseService { stripe: typeof stripe diff --git a/src/connectors/queue/appreciation.ts b/src/connectors/queue/appreciation.ts index da8126ad1..152e291ef 100644 --- a/src/connectors/queue/appreciation.ts +++ b/src/connectors/queue/appreciation.ts @@ -17,10 +17,11 @@ import { ForbiddenError, UserNotFoundError, } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { likecoin } from 'connectors' import { BaseQueue } from './baseQueue' +const logger = getLogger('default') interface AppreciationParams { amount: number diff --git a/src/connectors/queue/asset.ts b/src/connectors/queue/asset.ts index dada7574a..55da57f7b 100644 --- a/src/connectors/queue/asset.ts +++ b/src/connectors/queue/asset.ts @@ -2,7 +2,8 @@ import Queue from 'bull' import { QUEUE_JOB, QUEUE_NAME, QUEUE_PRIORITY } from 'common/enums' import { isTest } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' +const logger = getLogger('default') import { BaseQueue } from './baseQueue' diff --git a/src/connectors/queue/baseQueue.ts b/src/connectors/queue/baseQueue.ts index 95931c172..0b46f7cba 100644 --- a/src/connectors/queue/baseQueue.ts +++ b/src/connectors/queue/baseQueue.ts @@ -1,7 +1,7 @@ import Queue from 'bull' import { Knex } from 'knex' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { ArticleService, AtomService, @@ -15,6 +15,7 @@ import { import { knex } from 'connectors/db' import { createQueue, CustomQueueOpts } from './utils' +const logger = getLogger('default') export class BaseQueue { q: InstanceType diff --git a/src/connectors/queue/ipfs.ts b/src/connectors/queue/ipfs.ts index 0475985e4..2d7624765 100644 --- a/src/connectors/queue/ipfs.ts +++ b/src/connectors/queue/ipfs.ts @@ -10,12 +10,13 @@ import { QUEUE_PRIORITY, SLACK_MESSAGE_STATE, } from 'common/enums' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { timeout } from 'common/utils' import { ipfsServers } from 'connectors' import SlackService from 'connectors/slack' import { BaseQueue } from './baseQueue' +const logger = getLogger('default') class IPFSQueue extends BaseQueue { slackService: InstanceType diff --git a/src/connectors/queue/migration.ts b/src/connectors/queue/migration.ts index 90ec7c78d..d0d51241e 100644 --- a/src/connectors/queue/migration.ts +++ b/src/connectors/queue/migration.ts @@ -15,7 +15,8 @@ import { QUEUE_PRIORITY, } from 'common/enums' import { isTest } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' +const logger = getLogger('default') import { BaseQueue } from './baseQueue' diff --git a/src/connectors/queue/payTo/matters.ts b/src/connectors/queue/payTo/matters.ts index e1071932e..0c97b41fc 100644 --- a/src/connectors/queue/payTo/matters.ts +++ b/src/connectors/queue/payTo/matters.ts @@ -11,10 +11,11 @@ import { TRANSACTION_STATE, } from 'common/enums' import { PaymentQueueJobDataError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { PaymentService } from 'connectors' import { BaseQueue } from '../baseQueue' +const logger = getLogger('default') interface PaymentParams { txId: string diff --git a/src/connectors/queue/payout.ts b/src/connectors/queue/payout.ts index e80166c5e..23ccbc713 100644 --- a/src/connectors/queue/payout.ts +++ b/src/connectors/queue/payout.ts @@ -9,12 +9,13 @@ import { TRANSACTION_STATE, } from 'common/enums' import { PaymentQueueJobDataError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { numMinus, numRound, numTimes } from 'common/utils' import { AtomService, ExchangeRate, PaymentService } from 'connectors' import SlackService from 'connectors/slack' import { BaseQueue } from './baseQueue' +const logger = getLogger('default') interface PaymentParams { txId: string diff --git a/src/connectors/queue/publication.ts b/src/connectors/queue/publication.ts index e776371a8..1a4e056b4 100644 --- a/src/connectors/queue/publication.ts +++ b/src/connectors/queue/publication.ts @@ -17,7 +17,7 @@ import { QUEUE_PRIORITY, } from 'common/enums' import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { countWords, extractAssetDataFromHtml, @@ -27,6 +27,7 @@ import { } from 'common/utils' import { BaseQueue } from './baseQueue' +const logger = getLogger('default') export class PublicationQueue extends BaseQueue { constructor() { diff --git a/src/connectors/queue/user.ts b/src/connectors/queue/user.ts index 79d5b2d2d..c49adec2f 100644 --- a/src/connectors/queue/user.ts +++ b/src/connectors/queue/user.ts @@ -9,10 +9,11 @@ import { QUEUE_URL, USER_STATE, } from 'common/enums' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { aws } from 'connectors' import { BaseQueue } from './baseQueue' +const logger = getLogger('default') interface ArchiveUserData { userId: string diff --git a/src/connectors/queue/utils.ts b/src/connectors/queue/utils.ts index 8facff410..b2ed898e8 100644 --- a/src/connectors/queue/utils.ts +++ b/src/connectors/queue/utils.ts @@ -3,7 +3,8 @@ import Redis from 'ioredis' import { QUEUE_COMPLETED_LIST_SIZE } from 'common/enums' import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' +const logger = getLogger('default') export interface CustomQueueOpts { limiter?: RateLimiter diff --git a/src/connectors/slack/index.ts b/src/connectors/slack/index.ts index 1d6840e52..c8da6be87 100644 --- a/src/connectors/slack/index.ts +++ b/src/connectors/slack/index.ts @@ -2,7 +2,8 @@ import { WebClient } from '@slack/web-api' import { PAYMENT_CURRENCY, SLACK_MESSAGE_STATE } from 'common/enums' import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' +const logger = getLogger('default') class SlackService { client: WebClient diff --git a/src/connectors/stripe/index.ts b/src/connectors/stripe/index.ts index 14ac6f9c9..8a4054416 100644 --- a/src/connectors/stripe/index.ts +++ b/src/connectors/stripe/index.ts @@ -10,7 +10,7 @@ import { } from 'common/enums' import { environment, isProd, isTest } from 'common/environment' import { PaymentAmountInvalidError, ServerError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { getUTCNextMonday, getUTCNextMonthDayOne, @@ -18,6 +18,7 @@ import { } from 'common/utils' import SlackService from 'connectors/slack' import { User } from 'definitions' +const logger = getLogger('default') /** * Interact with Stripe diff --git a/src/connectors/systemService.ts b/src/connectors/systemService.ts index 67dfbbeb9..41d86d56c 100644 --- a/src/connectors/systemService.ts +++ b/src/connectors/systemService.ts @@ -7,7 +7,7 @@ import { SKIPPED_LIST_ITEM_TYPES, USER_ROLE, } from 'common/enums' -// import logger from 'common/logger' +import { getLogger } from 'common/logger' import { BaseService } from 'connectors' import { GQLFeatureFlag, @@ -17,6 +17,8 @@ import { Viewer, } from 'definitions' +const logger = getLogger('systemService') + export class SystemService extends BaseService { featureFlagTable: string @@ -305,8 +307,7 @@ export class SystemService extends BaseService { }) const logError = (err: Error) => { - // logger.error(err) - console.error('delete assets ERROR:', err) + logger.error(err) } await Promise.allSettled( diff --git a/src/connectors/tagService.ts b/src/connectors/tagService.ts index a5a879e07..e47aaa061 100644 --- a/src/connectors/tagService.ts +++ b/src/connectors/tagService.ts @@ -11,6 +11,7 @@ import { import { environment } from 'common/environment' import { BaseService } from 'connectors' import { Item, ItemData } from 'definitions' +// import _ from 'lodash' const debugLog = createDebug('tag-service') diff --git a/src/connectors/userService.ts b/src/connectors/userService.ts index ab1b9de37..8296cae92 100644 --- a/src/connectors/userService.ts +++ b/src/connectors/userService.ts @@ -36,7 +36,7 @@ import { PasswordNotAvailableError, UserInputError, } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { generatePasswordhash, isValidUserName, @@ -64,6 +64,7 @@ import { import { likecoin } from './likecoin' import { medium } from './medium' +const logger = getLogger('default') const debugLog = createDebug('user-service') diff --git a/src/middlewares/sentry.ts b/src/middlewares/sentry.ts index 43fc1c7a8..0ccb34f41 100644 --- a/src/middlewares/sentry.ts +++ b/src/middlewares/sentry.ts @@ -1,4 +1,5 @@ -import logger from 'common/logger' +import { getLogger } from 'common/logger' +const logger = getLogger('default') export const sentryMiddleware = async ( resolve: any, diff --git a/src/mutations/article/readArticle.ts b/src/mutations/article/readArticle.ts index 565f124df..b30a148ae 100644 --- a/src/mutations/article/readArticle.ts +++ b/src/mutations/article/readArticle.ts @@ -1,20 +1,15 @@ -// import slugify from '@matters/slugify' - import { ARTICLE_STATE } from 'common/enums' -// import { environment } from 'common/environment' import { ArticleNotFoundError } from 'common/errors' -// import logger from 'common/logger' +import { getLogger } from 'common/logger' import { fromGlobalId } from 'common/utils' -// import { likecoin } from 'connectors' import { MutationToReadArticleResolver } from 'definitions' +const logger = getLogger('mutation:readArticle') + const resolver: MutationToReadArticleResolver = async ( - root, + _, { input: { id } }, - { - viewer, - dataSources: { atomService, articleService, draftService, userService }, - } + { viewer, dataSources: { atomService, articleService, draftService } } ) => { const { id: dbId } = fromGlobalId(id) @@ -23,11 +18,17 @@ const resolver: MutationToReadArticleResolver = async ( where: { id: dbId, state: ARTICLE_STATE.active }, }) if (!article) { + logger.warn('target article %s does not exists', article.id) throw new ArticleNotFoundError('target article does not exists') } const node = await draftService.baseFindById(article.draftId) if (!node) { + logger.warn( + 'target article %s linked draft %s does not exists', + article.id, + article.draftId + ) throw new ArticleNotFoundError( 'target article linked draft does not exists' ) @@ -40,36 +41,6 @@ const resolver: MutationToReadArticleResolver = async ( userId: viewer.id || null, ip: viewer.ip, }) - - // const { newRead } = await articleService.read({ - // articleId: article.id, - // userId: viewer.id || null, - // ip: viewer.ip, - // }) - - // // if it's a new read - // // call like.co count api for like.co analytic pageview - // if (newRead) { - // try { - // let liker - // if (viewer.id) { - // liker = await userService.findLiker({ userId: viewer.id }) - // } - - // const author = await userService.dataloader.load(article.authorId) - // // const slug = slugify(node.title) - - // likecoin.sendPV({ - // likerId: liker ? liker.likerId : undefined, - // likerIp: viewer.ip, - // userAgent: viewer.userAgent, - // authorLikerId: author.likerId, - // url: `https://${environment.siteDomain}/@${author.userName}/${article.id}`, - // }) - // } catch (error) { - // logger.error(error) - // } - // } } return node diff --git a/src/mutations/oauthClient/putOAuthClient.ts b/src/mutations/oauthClient/putOAuthClient.ts index 6f8f0cfeb..0b53c7e96 100644 --- a/src/mutations/oauthClient/putOAuthClient.ts +++ b/src/mutations/oauthClient/putOAuthClient.ts @@ -7,9 +7,10 @@ import { AuthenticationError, UserInputError, } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { fromGlobalId } from 'common/utils' import { MutationToPutOAuthClientResolver } from 'definitions' +const logger = getLogger('default') const resolver: MutationToPutOAuthClientResolver = async ( root, diff --git a/src/mutations/user/sendVerificationCode.ts b/src/mutations/user/sendVerificationCode.ts index adad73eb0..5404350ec 100644 --- a/src/mutations/user/sendVerificationCode.ts +++ b/src/mutations/user/sendVerificationCode.ts @@ -11,13 +11,14 @@ import { // ForbiddenError, UserInputError, } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { extractRootDomain } from 'common/utils' // import { gcp } from 'connectors' import { GQLVerificationCodeType, MutationToSendVerificationCodeResolver, } from 'definitions' +const logger = getLogger('default') const resolver: MutationToSendVerificationCodeResolver = async ( _, diff --git a/src/mutations/user/updateUserInfo.ts b/src/mutations/user/updateUserInfo.ts index 8c6321876..87d0ca247 100644 --- a/src/mutations/user/updateUserInfo.ts +++ b/src/mutations/user/updateUserInfo.ts @@ -13,7 +13,7 @@ import { PasswordInvalidError, UserInputError, } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { generatePasswordhash, isValidDisplayName, @@ -27,6 +27,7 @@ import { ItemData, MutationToUpdateUserInfoResolver, } from 'definitions' +const logger = getLogger('default') const resolver: MutationToUpdateUserInfoResolver = async ( _, diff --git a/src/mutations/user/updateUserRole.ts b/src/mutations/user/updateUserRole.ts index 8fcd08253..d703eb033 100644 --- a/src/mutations/user/updateUserRole.ts +++ b/src/mutations/user/updateUserRole.ts @@ -1,11 +1,10 @@ -// import logger from 'common/logger' import { fromGlobalId } from 'common/utils' import { MutationToUpdateUserRoleResolver } from 'definitions' const resolver: MutationToUpdateUserRoleResolver = async ( _, { input: { id, role } }, - { viewer, dataSources: { atomService } } + { dataSources: { atomService } } ) => { const { id: dbId } = fromGlobalId(id) diff --git a/src/queries/article/canSuperLike.ts b/src/queries/article/canSuperLike.ts index d6247ef56..16074efc9 100644 --- a/src/queries/article/canSuperLike.ts +++ b/src/queries/article/canSuperLike.ts @@ -1,6 +1,7 @@ import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { ArticleToCanSuperLikeResolver } from 'definitions' +const logger = getLogger('default') const resolver: ArticleToCanSuperLikeResolver = async ( { articleId }, diff --git a/src/queries/article/index.ts b/src/queries/article/index.ts index dbecedf6e..2760c650e 100644 --- a/src/queries/article/index.ts +++ b/src/queries/article/index.ts @@ -5,7 +5,7 @@ import { ARTICLE_LICENSE_TYPE, NODE_TYPES, } from 'common/enums' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { toGlobalId } from 'common/utils' import { GQLArticleLicenseType } from 'definitions' @@ -71,6 +71,7 @@ import translation from './translation' import userArticles from './user/articles' // import userTags from './user/tags' import userTopics from './user/topics' +const logger = getLogger('default') export default { Query: { diff --git a/src/queries/article/translation.ts b/src/queries/article/translation.ts index 95277d963..35226562a 100644 --- a/src/queries/article/translation.ts +++ b/src/queries/article/translation.ts @@ -2,9 +2,10 @@ import { invalidateFQC } from '@matters/apollo-response-cache' import { makeSummary } from '@matters/ipns-site-generator' import { ARTICLE_ACCESS_TYPE, NODE_TYPES } from 'common/enums' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { CacheService, gcp } from 'connectors' import { ArticleToTranslationResolver } from 'definitions' +const logger = getLogger('default') const resolver: ArticleToTranslationResolver = async ( { diff --git a/src/queries/user/appreciation.ts b/src/queries/user/appreciation.ts index 1ac5ee501..8d1812fcd 100644 --- a/src/queries/user/appreciation.ts +++ b/src/queries/user/appreciation.ts @@ -2,9 +2,10 @@ import { camelCase } from 'lodash' import { APPRECIATION_PURPOSE } from 'common/enums' import { ArticleNotFoundError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { i18n } from 'common/utils/i18n' import { GQLAppreciationTypeResolver } from 'definitions' +const logger = getLogger('default') const trans = { appreciateSubsidy: i18n({ diff --git a/src/queries/user/liker/rateUSD.ts b/src/queries/user/liker/rateUSD.ts index 9704808aa..bc7ba9730 100644 --- a/src/queries/user/liker/rateUSD.ts +++ b/src/queries/user/liker/rateUSD.ts @@ -1,7 +1,8 @@ import _ from 'lodash' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { LikerToRateUSDResolver } from 'definitions' +const logger = getLogger('default') const resolver: LikerToRateUSDResolver = async ( { id }, diff --git a/src/routes/graphql.ts b/src/routes/graphql.ts index 1cbbaff8b..dcbe6383a 100644 --- a/src/routes/graphql.ts +++ b/src/routes/graphql.ts @@ -25,7 +25,7 @@ import { } from 'common/enums' import { environment, isProd } from 'common/environment' import { ActionLimitExceededError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { makeContext } from 'common/utils' import { ArticleService, @@ -43,6 +43,7 @@ import { import { sentryMiddleware } from 'middlewares/sentry' import schema from '../schema' +const logger = getLogger('default') const API_ENDPOINT = '/graphql' const PLAYGROUND_ENDPOINT = '/playground' diff --git a/src/routes/oauth/index.ts b/src/routes/oauth/index.ts index 7ca1a8950..6cd34f7da 100644 --- a/src/routes/oauth/index.ts +++ b/src/routes/oauth/index.ts @@ -9,12 +9,13 @@ import { OAUTH_REFRESH_TOKEN_EXPIRES_IN_MS, } from 'common/enums' import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { getViewerFromReq } from 'common/utils/getViewer' import { OAuthService } from 'connectors' import OAuthServer from './express-oauth-server' import initPassportStrategies from './strategies' +const logger = getLogger('default') const oAuthRouter = Router() const oAuthService = new OAuthService() diff --git a/src/routes/oauth/strategies.ts b/src/routes/oauth/strategies.ts index 7d6cc2d43..b5ff3f17f 100644 --- a/src/routes/oauth/strategies.ts +++ b/src/routes/oauth/strategies.ts @@ -5,8 +5,9 @@ import passport from 'passport' import { NODE_TYPES, OAUTH_CALLBACK_ERROR_CODE } from 'common/enums' import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { CacheService, UserService } from 'connectors' +const logger = getLogger('default') export default () => { passport.use( diff --git a/src/routes/pay/likecoin.ts b/src/routes/pay/likecoin.ts index f7b6bf773..31a218553 100644 --- a/src/routes/pay/likecoin.ts +++ b/src/routes/pay/likecoin.ts @@ -12,13 +12,14 @@ import { } from 'common/enums' import { environment } from 'common/environment' import { LikeCoinWebhookError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { AtomService, CacheService, PaymentService, UserService, } from 'connectors' +const logger = getLogger('default') const likecoinRouter = Router() diff --git a/src/routes/pay/stripe/circle.ts b/src/routes/pay/stripe/circle.ts index 490d11754..0aba9e5ff 100644 --- a/src/routes/pay/stripe/circle.ts +++ b/src/routes/pay/stripe/circle.ts @@ -15,7 +15,7 @@ import { } from 'common/enums' import { environment } from 'common/environment' import { ServerError } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { toDBAmount } from 'common/utils' import { AtomService, @@ -25,6 +25,7 @@ import { } from 'connectors' import SlackService from 'connectors/slack' import { CirclePrice, CircleSubscription, Customer } from 'definitions' +const logger = getLogger('default') const stripe = new Stripe(environment.stripeSecret, { apiVersion: '2020-08-27', diff --git a/src/routes/pay/stripe/connect/index.ts b/src/routes/pay/stripe/connect/index.ts index 1bf4c6c12..bc2c828a7 100644 --- a/src/routes/pay/stripe/connect/index.ts +++ b/src/routes/pay/stripe/connect/index.ts @@ -3,10 +3,11 @@ import { RequestHandler, Router } from 'express' import Stripe from 'stripe' import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import SlackService from 'connectors/slack' import { updateAccount } from './account' +const logger = getLogger('default') const stripe = new Stripe(environment.stripeSecret, { apiVersion: '2020-08-27', diff --git a/src/routes/pay/stripe/index.ts b/src/routes/pay/stripe/index.ts index ac75e6c0f..272cebde5 100644 --- a/src/routes/pay/stripe/index.ts +++ b/src/routes/pay/stripe/index.ts @@ -4,7 +4,7 @@ import _ from 'lodash' import Stripe from 'stripe' import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { PaymentService } from 'connectors' import SlackService from 'connectors/slack' @@ -16,6 +16,8 @@ import { import { updateCustomerCard } from './customer' import { createRefundTxs, updateTxState } from './transaction' +const logger = getLogger('route:stripe') + const stripe = new Stripe(environment.stripeSecret, { apiVersion: '2020-08-27', }) From 1d1f954f5802ed10207fae16aa5654f006e589ec Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Fri, 12 May 2023 14:39:41 +0800 Subject: [PATCH 02/15] feat(logging): implement `setRequestId` --- src/common/logger.ts | 24 ++++++++++-------------- src/index.ts | 10 ++++++++++ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/common/logger.ts b/src/common/logger.ts index 1957fd04f..d6610b9dd 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -1,17 +1,13 @@ -import _get from 'lodash/get' +import { AsyncLocalStorage } from 'async_hooks' import { createLogger, format, transports } from 'winston' -// import { isProd } from 'common/environment' +export const contextStorage = new AsyncLocalStorage>() -/** - * Simple format outputs: - * - * YYYY-MM-DD HH:mm:ss `${level}: ${message} ${[object]}` - * - */ - -const getContext = format((info, _) => { - info.context = { requestId: 'test-request-id' } +const setRequestId = format((info, _) => { + const context = contextStorage.getStore() + if (context) { + info.requestId = context!.get('requestId') + } return info }) @@ -20,7 +16,7 @@ const createWinstonLogger = (name: string) => level: 'info', format: format.combine( format.splat(), - getContext(), + setRequestId(), format.label({ label: name }), format.errors({ stack: true }), format.timestamp({ @@ -28,9 +24,9 @@ const createWinstonLogger = (name: string) => }), format.printf( (info) => - `${info.timestamp} ${info.label} ${info.context.requestId} ${ + `${info.timestamp} ${info.requestId ?? '-'} ${info.label} ${ info.level - }: ${JSON.stringify(info.message)}` + }: ${info.message}` ) ), transports: [new transports.Console({ level: 'info' })], diff --git a/src/index.ts b/src/index.ts index 930a928f2..f037e8ae4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,9 +4,11 @@ import express, { RequestHandler } from 'express' import helmet from 'helmet' import 'module-alias/register' import requestIp from 'request-ip' +import { v4 } from 'uuid' import { CORS_OPTIONS, IMG_CACHE_PATH } from 'common/enums' import { environment } from 'common/environment' +import { contextStorage } from 'common/logger' import * as routes from './routes' ;(async () => { @@ -34,6 +36,14 @@ import * as routes from './routes' /** * Middlewares */ + // store request-id in AsyncLocalStorage + app.use((req, _, next) => { + const traceId = req.header('x-trace-id') + const context = new Map() + context.set('requestId', traceId ?? v4()) + contextStorage.enterWith(context) + next() + }) app.use(helmet({ contentSecurityPolicy: false }) as RequestHandler) app.use(requestIp.mw()) app.use(cors(CORS_OPTIONS)) From a38b109547d78a705d895adb6c8c7deab5d66dc3 Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Fri, 12 May 2023 15:16:40 +0800 Subject: [PATCH 03/15] feat(logging): logger accept `util.debuglog` NODE_DEBUG like envs to enable a part of debug logging --- .env.example | 2 ++ src/common/environment.ts | 2 ++ src/common/logger.ts | 15 +++++++++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index f03f0fe4f..ca2eeb7ac 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,6 @@ MATTERS_ENV=local +MATTERS_LOGGING_LEVEL=info +MATTERS_DEBUG=queue,resolver MATTERS_SERVER_DOMAIN=localhost:4000 MATTERS_SITE_DOMAIN=localhost:3000 MATTERS_OAUTH_SITE_DOMAIN=localhost:3000 diff --git a/src/common/environment.ts b/src/common/environment.ts index 78cf60626..2867e3d5c 100644 --- a/src/common/environment.ts +++ b/src/common/environment.ts @@ -33,6 +33,8 @@ export const isProd = process.env.MATTERS_ENV === 'production' export const environment = { env: process.env.MATTERS_ENV, + loggingLevel: process.env.MATTERS_LOGGING_LEVEL || 'info', + debug: process.env.MATTERS_DEBUG || '', serverDomain: process.env.MATTERS_SERVER_DOMAIN || '', siteDomain: (process.env.MATTERS_SITE_DOMAIN || 'matters.town') as string, oauthSiteDomain: process.env.MATTERS_OAUTH_SITE_DOMAIN as string, diff --git a/src/common/logger.ts b/src/common/logger.ts index d6610b9dd..3b891da6a 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -1,6 +1,8 @@ import { AsyncLocalStorage } from 'async_hooks' import { createLogger, format, transports } from 'winston' +import { environment } from 'common/environment' + export const contextStorage = new AsyncLocalStorage>() const setRequestId = format((info, _) => { @@ -11,9 +13,11 @@ const setRequestId = format((info, _) => { return info }) -const createWinstonLogger = (name: string) => +const console = new transports.Console({ level: 'debug' }) + +const createWinstonLogger = (name: string, level: string) => createLogger({ - level: 'info', + level, format: format.combine( format.splat(), setRequestId(), @@ -29,7 +33,7 @@ const createWinstonLogger = (name: string) => }: ${info.message}` ) ), - transports: [new transports.Console({ level: 'info' })], + transports: [console], }) const loggers = new Map() @@ -39,7 +43,10 @@ export const getLogger = (name: string) => { if (logger) { return logger } - const newLogger = createWinstonLogger(name) + const level = environment.debug.includes(name) + ? 'debug' + : environment.loggingLevel + const newLogger = createWinstonLogger(name, level) loggers.set(name, newLogger) return newLogger } From 0542e99d1dc6589a22241be31593d6d13b38d503 Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Fri, 12 May 2023 18:32:31 +0800 Subject: [PATCH 04/15] refactor(middleware): rename `SentryMiddleware` to `loggerMiddleware` as logger dont use Sentry now --- src/middlewares/{sentry.ts => logger.ts} | 6 +++--- src/routes/graphql.ts | 11 +++++------ 2 files changed, 8 insertions(+), 9 deletions(-) rename src/middlewares/{sentry.ts => logger.ts} (71%) diff --git a/src/middlewares/sentry.ts b/src/middlewares/logger.ts similarity index 71% rename from src/middlewares/sentry.ts rename to src/middlewares/logger.ts index 0ccb34f41..6ab79e6b6 100644 --- a/src/middlewares/sentry.ts +++ b/src/middlewares/logger.ts @@ -1,7 +1,8 @@ import { getLogger } from 'common/logger' -const logger = getLogger('default') -export const sentryMiddleware = async ( +const logger = getLogger('resolver') + +export const loggerMiddleware = async ( resolve: any, root: { [key: string]: any }, args: any, @@ -12,7 +13,6 @@ export const sentryMiddleware = async ( const result = await resolve(root, args, context, info) return result } catch (error) { - // pass error to Sentry via logger logger.error(error) throw error } diff --git a/src/routes/graphql.ts b/src/routes/graphql.ts index dcbe6383a..1c7b9e2b6 100644 --- a/src/routes/graphql.ts +++ b/src/routes/graphql.ts @@ -40,10 +40,11 @@ import { TagService, UserService, } from 'connectors' -import { sentryMiddleware } from 'middlewares/sentry' +import { loggerMiddleware } from 'middlewares/logger' import schema from '../schema' -const logger = getLogger('default') + +const logger = getLogger('graphql-cost-analysis') const API_ENDPOINT = '/graphql' const PLAYGROUND_ENDPOINT = '/playground' @@ -75,9 +76,7 @@ class ProtectedApolloServer extends ApolloServer { return err }, onComplete: (costs: number) => - logger.info( - `[graphql-cost-analysis] costs: ${costs} (max: ${maximumCost})` - ), + logger.debug('costs: %d (max: %d)', costs, maximumCost), }), ], } @@ -89,7 +88,7 @@ const cache = new RedisCache({ port: environment.cachePort, }) -const composedSchema = applyMiddleware(schema, sentryMiddleware) +const composedSchema = applyMiddleware(schema, loggerMiddleware) const exceptVariableNames = [ 'email', From bf7d35ca3a403b1b1f10e4ea3b0675b383e0c23c Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Fri, 12 May 2023 18:36:23 +0800 Subject: [PATCH 05/15] refactor(logging): rename loggers --- src/common/logger.ts | 5 +-- src/common/utils/exportSchema.ts | 3 +- src/common/utils/generateTypes.ts | 3 +- src/common/utils/getLanguage.ts | 6 ++-- src/common/utils/getViewer.ts | 5 +-- src/common/utils/updateWordCount.ts | 4 +-- src/connectors/baseService.ts | 8 ++--- src/connectors/exchangeRate/index.ts | 3 +- src/connectors/gcp/index.ts | 3 +- src/connectors/likecoin/index.ts | 3 +- src/connectors/medium/index.ts | 3 +- src/connectors/notificationService/index.ts | 5 +-- src/connectors/oauthService.ts | 3 +- src/connectors/opensea/index.ts | 3 +- src/connectors/paymentService.ts | 3 +- src/connectors/queue/appreciation.ts | 3 +- src/connectors/queue/asset.ts | 3 +- src/connectors/queue/baseQueue.ts | 3 +- src/connectors/queue/ipfs.ts | 3 +- src/connectors/queue/migration.ts | 3 +- src/connectors/queue/payTo/matters.ts | 3 +- src/connectors/queue/payout.ts | 3 +- src/connectors/queue/publication.ts | 3 +- src/connectors/queue/user.ts | 3 +- src/connectors/queue/utils.ts | 40 +++++++++++---------- src/connectors/slack/index.ts | 3 +- src/connectors/stripe/index.ts | 3 +- src/connectors/systemService.ts | 2 +- src/connectors/userService.ts | 3 +- src/middlewares/logger.ts | 2 +- src/mutations/article/readArticle.ts | 2 +- src/mutations/oauthClient/putOAuthClient.ts | 6 ++-- src/mutations/user/sendVerificationCode.ts | 13 ++----- src/mutations/user/updateUserInfo.ts | 3 +- src/queries/article/canSuperLike.ts | 3 +- src/queries/article/index.ts | 3 +- src/queries/article/translation.ts | 3 +- src/queries/user/appreciation.ts | 3 +- src/queries/user/index.ts | 2 +- src/queries/user/liker/rateUSD.ts | 7 ++-- src/routes/oauth/index.ts | 3 +- src/routes/oauth/strategies.ts | 11 +++--- src/routes/pay/likecoin.ts | 3 +- src/routes/pay/stripe/circle.ts | 3 +- src/routes/pay/stripe/connect/index.ts | 3 +- src/routes/pay/stripe/index.ts | 2 +- 46 files changed, 117 insertions(+), 93 deletions(-) diff --git a/src/common/logger.ts b/src/common/logger.ts index 3b891da6a..0fa78bb60 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -5,10 +5,11 @@ import { environment } from 'common/environment' export const contextStorage = new AsyncLocalStorage>() -const setRequestId = format((info, _) => { +const setContext = format((info, _) => { const context = contextStorage.getStore() if (context) { info.requestId = context!.get('requestId') + // info.jobId = context!.get('jobId') } return info }) @@ -20,7 +21,7 @@ const createWinstonLogger = (name: string, level: string) => level, format: format.combine( format.splat(), - setRequestId(), + setContext(), format.label({ label: name }), format.errors({ stack: true }), format.timestamp({ diff --git a/src/common/utils/exportSchema.ts b/src/common/utils/exportSchema.ts index 0f77b65e6..baadc2449 100644 --- a/src/common/utils/exportSchema.ts +++ b/src/common/utils/exportSchema.ts @@ -5,7 +5,8 @@ import 'module-alias/register' import { getLogger } from 'common/logger' import typeDefs from 'types' -const logger = getLogger('default') + +const logger = getLogger('utils') const schemaObj = makeExecutableSchema({ typeDefs, diff --git a/src/common/utils/generateTypes.ts b/src/common/utils/generateTypes.ts index 971c428b2..d40c00cee 100644 --- a/src/common/utils/generateTypes.ts +++ b/src/common/utils/generateTypes.ts @@ -3,7 +3,8 @@ import { generateTypeScriptTypes } from 'graphql-schema-typescript' import 'module-alias/register' import { getLogger } from 'common/logger' -const logger = getLogger('default') + +const logger = getLogger('utils') const schema = fs.readFileSync('schema.graphql', { encoding: 'utf8' }) diff --git a/src/common/utils/getLanguage.ts b/src/common/utils/getLanguage.ts index ac7800a3b..050511d35 100644 --- a/src/common/utils/getLanguage.ts +++ b/src/common/utils/getLanguage.ts @@ -2,7 +2,8 @@ import _ from 'lodash' import { LANGUAGE } from 'common/enums' import { getLogger } from 'common/logger' -const logger = getLogger('default') + +const logger = getLogger('utils-language') // map supported language to header language export const langMap = { @@ -45,8 +46,7 @@ export const getLanguage = (acceptLanguage?: string) => { return reverseMap[requestList[supportIndex]] } } catch (err) { - logger.error(err) - console.error(new Date(), 'ERROR:', err, { acceptLanguage }) + logger.error({ acceptLanguage }, err) } return LANGUAGE.zh_hant diff --git a/src/common/utils/getViewer.ts b/src/common/utils/getViewer.ts index 79f278612..aac05e42e 100644 --- a/src/common/utils/getViewer.ts +++ b/src/common/utils/getViewer.ts @@ -15,7 +15,8 @@ import { getLogger } from 'common/logger' import { clearCookie, getLanguage } from 'common/utils' import { OAuthService, SystemService, UserService } from 'connectors' import { Viewer } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('utils-auth') export const roleAccess = [USER_ROLE.visitor, USER_ROLE.user, USER_ROLE.admin] export const authModes = [ @@ -45,7 +46,7 @@ export const getUserGroup = ({ num = parseInt(last, 10) || 0 } } catch (error) { - // logger.error('ERROR:', error, { id, ip }) + logger.warn('ERROR:', error, { id, ip }) } return num % 2 === 0 ? 'a' : 'b' } diff --git a/src/common/utils/updateWordCount.ts b/src/common/utils/updateWordCount.ts index 1d2d164a6..8e375a824 100644 --- a/src/common/utils/updateWordCount.ts +++ b/src/common/utils/updateWordCount.ts @@ -1,10 +1,8 @@ import 'module-alias/register' -import { getLogger } from 'common/logger' import { ArticleService, DraftService } from 'connectors' import { countWords } from './content' -const logger = getLogger('default') async function main() { const articleIds = process.argv.slice(2) @@ -34,7 +32,7 @@ async function main() { }) ) - logger.info('done.') + console.info('done.') process.exit() } diff --git a/src/connectors/baseService.ts b/src/connectors/baseService.ts index f78b51393..7dc003277 100644 --- a/src/connectors/baseService.ts +++ b/src/connectors/baseService.ts @@ -7,7 +7,7 @@ import { getLogger } from 'common/logger' import { aws, cfsvc, knex, readonlyKnex, searchKnexDB } from 'connectors' import { Item, ItemData, TableName } from 'definitions' -const logger = getLogger('default') +const logger = getLogger('service-base') export class BaseService extends DataSource { aws: typeof aws @@ -159,7 +159,6 @@ export class BaseService extends DataSource { query.transacting(trx) } const [result] = await query - // logger.info(`Inserted id ${result.id} to ${table || this.table}`) return result } catch (err) { @@ -223,8 +222,7 @@ export class BaseService extends DataSource { ...(updateUpdatedAt ? { updatedAt: knex.fn.now() } : null), }) .returning('*') - // logger.info(`Updated id ${updatedItem.id} in ${tableName}`) - // + if (trx) { query.transacting(trx) } @@ -286,7 +284,7 @@ export class BaseService extends DataSource { } const [updatedItem] = await query - // logger.info(`Updated id ${id} in ${table || this.table}`) + logger.debug('Updated id %s in %s', id, table ?? this.table) return updatedItem } /** diff --git a/src/connectors/exchangeRate/index.ts b/src/connectors/exchangeRate/index.ts index 23a0eac6c..c59d43125 100644 --- a/src/connectors/exchangeRate/index.ts +++ b/src/connectors/exchangeRate/index.ts @@ -5,7 +5,8 @@ import { environment } from 'common/environment' import { NetworkError, UnknownError } from 'common/errors' import { getLogger } from 'common/logger' import { CacheService } from 'connectors' -const logger = getLogger('default') + +const logger = getLogger('service-exchange-rate') // TYPES diff --git a/src/connectors/gcp/index.ts b/src/connectors/gcp/index.ts index b8bfc043b..1c571b18d 100644 --- a/src/connectors/gcp/index.ts +++ b/src/connectors/gcp/index.ts @@ -5,7 +5,8 @@ import { LANGUAGE } from 'common/enums' import { environment, isTest } from 'common/environment' import { ActionFailedError, UserInputError } from 'common/errors' import { getLogger } from 'common/logger' -const logger = getLogger('default') + +const logger = getLogger('service-gcp') const { zh_hans, zh_hant, en } = LANGUAGE diff --git a/src/connectors/likecoin/index.ts b/src/connectors/likecoin/index.ts index 393b0afd4..9127e0a50 100644 --- a/src/connectors/likecoin/index.ts +++ b/src/connectors/likecoin/index.ts @@ -14,7 +14,8 @@ import { import { getLogger } from 'common/logger' import { aws, CacheService, knex } from 'connectors' import { UserOAuthLikeCoin } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('service-likecoin') interface LikeData { likerId: string diff --git a/src/connectors/medium/index.ts b/src/connectors/medium/index.ts index cec63f724..aa0693d14 100644 --- a/src/connectors/medium/index.ts +++ b/src/connectors/medium/index.ts @@ -13,7 +13,8 @@ import { getFileName } from 'common/utils' import { aws, cfsvc, knex } from 'connectors' import { AWSService } from 'connectors/aws' import { GQLAssetType } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('service-medium') const throttle = pThrottle({ limit: 2, diff --git a/src/connectors/notificationService/index.ts b/src/connectors/notificationService/index.ts index 8f1705ef6..6314a13ed 100644 --- a/src/connectors/notificationService/index.ts +++ b/src/connectors/notificationService/index.ts @@ -15,7 +15,8 @@ import { import { mail } from './mail' import { notice } from './notice' import trans from './translations' -const logger = getLogger('default') + +const logger = getLogger('service-notification') export class NotificationService extends BaseService { mail: typeof mail @@ -31,7 +32,7 @@ export class NotificationService extends BaseService { try { await this.__trigger(params) } catch (e) { - logger.error('[Notification:trigger]', e) + logger.error(e) } } diff --git a/src/connectors/oauthService.ts b/src/connectors/oauthService.ts index e2eecfee1..e65ddd27f 100644 --- a/src/connectors/oauthService.ts +++ b/src/connectors/oauthService.ts @@ -18,7 +18,8 @@ import { OAuthToken, User, } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('service-oauth') export class OAuthService extends BaseService { constructor() { diff --git a/src/connectors/opensea/index.ts b/src/connectors/opensea/index.ts index 4c0a117b7..80f319aa8 100644 --- a/src/connectors/opensea/index.ts +++ b/src/connectors/opensea/index.ts @@ -3,7 +3,8 @@ import { RequestOptions, RESTDataSource } from 'apollo-datasource-rest' import { CACHE_TTL } from 'common/enums' import { environment } from 'common/environment' import { getLogger } from 'common/logger' -const logger = getLogger('default') + +const logger = getLogger('service-opensea') export class OpenSeaService extends RESTDataSource { apiKey?: string | undefined diff --git a/src/connectors/paymentService.ts b/src/connectors/paymentService.ts index 2df410da0..fc251f15f 100644 --- a/src/connectors/paymentService.ts +++ b/src/connectors/paymentService.ts @@ -25,7 +25,8 @@ import { AtomService, BaseService, NotificationService } from 'connectors' import { CirclePrice, GQLChain, Transaction, User } from 'definitions' import { stripe } from './stripe' -const logger = getLogger('default') + +const logger = getLogger('service-payment') export class PaymentService extends BaseService { stripe: typeof stripe diff --git a/src/connectors/queue/appreciation.ts b/src/connectors/queue/appreciation.ts index 152e291ef..40faf3295 100644 --- a/src/connectors/queue/appreciation.ts +++ b/src/connectors/queue/appreciation.ts @@ -21,7 +21,8 @@ import { getLogger } from 'common/logger' import { likecoin } from 'connectors' import { BaseQueue } from './baseQueue' -const logger = getLogger('default') + +const logger = getLogger('queue-appreciation') interface AppreciationParams { amount: number diff --git a/src/connectors/queue/asset.ts b/src/connectors/queue/asset.ts index 55da57f7b..6a195532f 100644 --- a/src/connectors/queue/asset.ts +++ b/src/connectors/queue/asset.ts @@ -3,10 +3,11 @@ import Queue from 'bull' import { QUEUE_JOB, QUEUE_NAME, QUEUE_PRIORITY } from 'common/enums' import { isTest } from 'common/environment' import { getLogger } from 'common/logger' -const logger = getLogger('default') import { BaseQueue } from './baseQueue' +const logger = getLogger('queue-asset') + interface AssetParams { ids: string[] } diff --git a/src/connectors/queue/baseQueue.ts b/src/connectors/queue/baseQueue.ts index 0b46f7cba..d0b004d48 100644 --- a/src/connectors/queue/baseQueue.ts +++ b/src/connectors/queue/baseQueue.ts @@ -15,7 +15,8 @@ import { import { knex } from 'connectors/db' import { createQueue, CustomQueueOpts } from './utils' -const logger = getLogger('default') + +const logger = getLogger('queue-base') export class BaseQueue { q: InstanceType diff --git a/src/connectors/queue/ipfs.ts b/src/connectors/queue/ipfs.ts index 2d7624765..d3ae70b8f 100644 --- a/src/connectors/queue/ipfs.ts +++ b/src/connectors/queue/ipfs.ts @@ -16,7 +16,8 @@ import { ipfsServers } from 'connectors' import SlackService from 'connectors/slack' import { BaseQueue } from './baseQueue' -const logger = getLogger('default') + +const logger = getLogger('queue-ipfs') class IPFSQueue extends BaseQueue { slackService: InstanceType diff --git a/src/connectors/queue/migration.ts b/src/connectors/queue/migration.ts index d0d51241e..8fd58bf6f 100644 --- a/src/connectors/queue/migration.ts +++ b/src/connectors/queue/migration.ts @@ -16,7 +16,8 @@ import { } from 'common/enums' import { isTest } from 'common/environment' import { getLogger } from 'common/logger' -const logger = getLogger('default') + +const logger = getLogger('queue-migration') import { BaseQueue } from './baseQueue' diff --git a/src/connectors/queue/payTo/matters.ts b/src/connectors/queue/payTo/matters.ts index 0c97b41fc..9da1c438b 100644 --- a/src/connectors/queue/payTo/matters.ts +++ b/src/connectors/queue/payTo/matters.ts @@ -15,7 +15,8 @@ import { getLogger } from 'common/logger' import { PaymentService } from 'connectors' import { BaseQueue } from '../baseQueue' -const logger = getLogger('default') + +const logger = getLogger('queue-payto-by-matters') interface PaymentParams { txId: string diff --git a/src/connectors/queue/payout.ts b/src/connectors/queue/payout.ts index 23ccbc713..503041104 100644 --- a/src/connectors/queue/payout.ts +++ b/src/connectors/queue/payout.ts @@ -15,7 +15,8 @@ import { AtomService, ExchangeRate, PaymentService } from 'connectors' import SlackService from 'connectors/slack' import { BaseQueue } from './baseQueue' -const logger = getLogger('default') + +const logger = getLogger('queue-payout') interface PaymentParams { txId: string diff --git a/src/connectors/queue/publication.ts b/src/connectors/queue/publication.ts index 1a4e056b4..b991c99f2 100644 --- a/src/connectors/queue/publication.ts +++ b/src/connectors/queue/publication.ts @@ -27,7 +27,8 @@ import { } from 'common/utils' import { BaseQueue } from './baseQueue' -const logger = getLogger('default') + +const logger = getLogger('queue-publication') export class PublicationQueue extends BaseQueue { constructor() { diff --git a/src/connectors/queue/user.ts b/src/connectors/queue/user.ts index c49adec2f..8d141713a 100644 --- a/src/connectors/queue/user.ts +++ b/src/connectors/queue/user.ts @@ -13,7 +13,8 @@ import { getLogger } from 'common/logger' import { aws } from 'connectors' import { BaseQueue } from './baseQueue' -const logger = getLogger('default') + +const logger = getLogger('queue-user') interface ArchiveUserData { userId: string diff --git a/src/connectors/queue/utils.ts b/src/connectors/queue/utils.ts index b2ed898e8..97f54d627 100644 --- a/src/connectors/queue/utils.ts +++ b/src/connectors/queue/utils.ts @@ -4,7 +4,8 @@ import Redis from 'ioredis' import { QUEUE_COMPLETED_LIST_SIZE } from 'common/enums' import { environment } from 'common/environment' import { getLogger } from 'common/logger' -const logger = getLogger('default') + +const logger = getLogger('queue-base') export interface CustomQueueOpts { limiter?: RateLimiter @@ -34,61 +35,62 @@ export const createQueue = ( queue.on('error', (error) => { // An error occured. - logger.error(`Job errored.`) - logger.info(error) + logger.error(`Job errored:`, error) }) queue.on('waiting', (jobId) => { // A Job is waiting to be processed as soon as a worker is idling. - // logger.info(`Job#${jobId} is waiting.`) + logger.debug(`Job#%s is waiting.`, jobId) }) - queue.on('active', (job, jobPromise) => { + queue.on('active', (job, _) => { // A job has started. You can use `jobPromise.cancel()`` to abort it. - // logger.info(`Job#${job.id} has started.`) + logger.debug(`Job#%s has started.`, job.id) }) queue.on('stalled', (job) => { // A job has been marked as stalled. This is useful for debugging job // workers that crash or pause the event loop. logger.error(`Job#${job.id} stalled, processing again.`) - logger.error({ job }) }) queue.on('progress', (job, progress) => { // A job's progress was updated! - logger.info(`Job#${job.id}/${job.name} progress was updated: ${progress}.`) + logger.debug( + 'Job#%s/%s progress was updated: %d.', + job.id, + job.name, + progress + ) }) queue.on('completed', (job, result) => { // A job successfully completed with a `result`. - logger.info( - `Job#${job.id}/${job.name} has been completed: ${JSON.stringify({ - result, - })}.` - ) + logger.debug('Job#%s/%s has been completed: %o.', job.id, job.name, result) }) queue.on('failed', (job, err) => { // A job failed with reason `err`! - logger.error(`Job#${job.id} failed, with following reason.`) - logger.error({ job, err }) + logger.error('Job#%s failed:', job.id, { job, err }) }) queue.on('paused', () => { // The queue has been paused. - // logger.info('The queue has been paused.') + logger.info('The queue has been paused.') }) queue.on('resumed', () => { // The queue has been resumed. - // logger.info('The queue has been resumed.') + logger.info('The queue has been resumed.') }) queue.on('cleaned', (jobs, type) => { // Old jobs have been cleaned from the queue. `jobs` is an array of cleaned // jobs, and `type` is the type of jobs cleaned. - // logger.info(`Jobs (${jobs.map((job) => `#${job.id}`)} have been cleaned.`) + logger.info( + `Jobs (%s) have been cleaned.`, + jobs.map((job) => `#${job.id}`) + ) }) queue.on('drained', () => { @@ -98,7 +100,7 @@ export const createQueue = ( queue.on('removed', (job) => { // A job successfully removed. - // logger.info(`Job#${job.id} has been removed.`) + logger.info('Job#%s has been removed.', job.id) }) return queue diff --git a/src/connectors/slack/index.ts b/src/connectors/slack/index.ts index c8da6be87..5ddc9d46f 100644 --- a/src/connectors/slack/index.ts +++ b/src/connectors/slack/index.ts @@ -3,7 +3,8 @@ import { WebClient } from '@slack/web-api' import { PAYMENT_CURRENCY, SLACK_MESSAGE_STATE } from 'common/enums' import { environment } from 'common/environment' import { getLogger } from 'common/logger' -const logger = getLogger('default') + +const logger = getLogger('service-slack') class SlackService { client: WebClient diff --git a/src/connectors/stripe/index.ts b/src/connectors/stripe/index.ts index 8a4054416..ccbd69668 100644 --- a/src/connectors/stripe/index.ts +++ b/src/connectors/stripe/index.ts @@ -18,7 +18,8 @@ import { } from 'common/utils' import SlackService from 'connectors/slack' import { User } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('service-stripe') /** * Interact with Stripe diff --git a/src/connectors/systemService.ts b/src/connectors/systemService.ts index 41d86d56c..bebb55470 100644 --- a/src/connectors/systemService.ts +++ b/src/connectors/systemService.ts @@ -17,7 +17,7 @@ import { Viewer, } from 'definitions' -const logger = getLogger('systemService') +const logger = getLogger('service-system') export class SystemService extends BaseService { featureFlagTable: string diff --git a/src/connectors/userService.ts b/src/connectors/userService.ts index 8296cae92..e8a14b631 100644 --- a/src/connectors/userService.ts +++ b/src/connectors/userService.ts @@ -64,7 +64,8 @@ import { import { likecoin } from './likecoin' import { medium } from './medium' -const logger = getLogger('default') + +const logger = getLogger('service-user') const debugLog = createDebug('user-service') diff --git a/src/middlewares/logger.ts b/src/middlewares/logger.ts index 6ab79e6b6..f77e98e37 100644 --- a/src/middlewares/logger.ts +++ b/src/middlewares/logger.ts @@ -1,6 +1,6 @@ import { getLogger } from 'common/logger' -const logger = getLogger('resolver') +const logger = getLogger('middleware-logger') export const loggerMiddleware = async ( resolve: any, diff --git a/src/mutations/article/readArticle.ts b/src/mutations/article/readArticle.ts index b30a148ae..27bf72aca 100644 --- a/src/mutations/article/readArticle.ts +++ b/src/mutations/article/readArticle.ts @@ -4,7 +4,7 @@ import { getLogger } from 'common/logger' import { fromGlobalId } from 'common/utils' import { MutationToReadArticleResolver } from 'definitions' -const logger = getLogger('mutation:readArticle') +const logger = getLogger('mutation-read-article') const resolver: MutationToReadArticleResolver = async ( _, diff --git a/src/mutations/oauthClient/putOAuthClient.ts b/src/mutations/oauthClient/putOAuthClient.ts index 0b53c7e96..0c0ae1589 100644 --- a/src/mutations/oauthClient/putOAuthClient.ts +++ b/src/mutations/oauthClient/putOAuthClient.ts @@ -1,4 +1,3 @@ -import _ from 'lodash' import { nanoid } from 'nanoid' import { ASSET_TYPE } from 'common/enums' @@ -10,10 +9,11 @@ import { import { getLogger } from 'common/logger' import { fromGlobalId } from 'common/utils' import { MutationToPutOAuthClientResolver } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('mutation-put-oauth-client') const resolver: MutationToPutOAuthClientResolver = async ( - root, + _, { input: { id, diff --git a/src/mutations/user/sendVerificationCode.ts b/src/mutations/user/sendVerificationCode.ts index 5404350ec..748a7dc2f 100644 --- a/src/mutations/user/sendVerificationCode.ts +++ b/src/mutations/user/sendVerificationCode.ts @@ -8,21 +8,20 @@ import { AuthenticationError, EmailExistsError, EmailNotFoundError, - // ForbiddenError, UserInputError, } from 'common/errors' import { getLogger } from 'common/logger' import { extractRootDomain } from 'common/utils' -// import { gcp } from 'connectors' import { GQLVerificationCodeType, MutationToSendVerificationCodeResolver, } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('mutation-send-verificaiton-code') const resolver: MutationToSendVerificationCodeResolver = async ( _, - { input: { email: rawEmail, type, token, redirectUrl } }, + { input: { email: rawEmail, type, redirectUrl } }, { viewer, dataSources: { @@ -50,12 +49,6 @@ const resolver: MutationToSendVerificationCodeResolver = async ( if (user) { throw new EmailExistsError('email has been registered') } - - // // check token for Turing test - // const isHuman = await gcp.recaptcha({ token, ip: viewer.ip }) - // if (!isHuman) { - // throw new ForbiddenError('registration via scripting is not allowed') - // } } if ( diff --git a/src/mutations/user/updateUserInfo.ts b/src/mutations/user/updateUserInfo.ts index 87d0ca247..c6ae108c4 100644 --- a/src/mutations/user/updateUserInfo.ts +++ b/src/mutations/user/updateUserInfo.ts @@ -27,7 +27,8 @@ import { ItemData, MutationToUpdateUserInfoResolver, } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('mutation-to-update-user-info') const resolver: MutationToUpdateUserInfoResolver = async ( _, diff --git a/src/queries/article/canSuperLike.ts b/src/queries/article/canSuperLike.ts index 16074efc9..e5d31357d 100644 --- a/src/queries/article/canSuperLike.ts +++ b/src/queries/article/canSuperLike.ts @@ -1,7 +1,8 @@ import { environment } from 'common/environment' import { getLogger } from 'common/logger' import { ArticleToCanSuperLikeResolver } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('mutation-superlike') const resolver: ArticleToCanSuperLikeResolver = async ( { articleId }, diff --git a/src/queries/article/index.ts b/src/queries/article/index.ts index 2760c650e..d7b50dbb2 100644 --- a/src/queries/article/index.ts +++ b/src/queries/article/index.ts @@ -71,7 +71,8 @@ import translation from './translation' import userArticles from './user/articles' // import userTags from './user/tags' import userTopics from './user/topics' -const logger = getLogger('default') + +const logger = getLogger('query-article') export default { Query: { diff --git a/src/queries/article/translation.ts b/src/queries/article/translation.ts index 35226562a..d7f626157 100644 --- a/src/queries/article/translation.ts +++ b/src/queries/article/translation.ts @@ -5,7 +5,8 @@ import { ARTICLE_ACCESS_TYPE, NODE_TYPES } from 'common/enums' import { getLogger } from 'common/logger' import { CacheService, gcp } from 'connectors' import { ArticleToTranslationResolver } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('query-translations') const resolver: ArticleToTranslationResolver = async ( { diff --git a/src/queries/user/appreciation.ts b/src/queries/user/appreciation.ts index 8d1812fcd..ab8c12d8b 100644 --- a/src/queries/user/appreciation.ts +++ b/src/queries/user/appreciation.ts @@ -5,7 +5,8 @@ import { ArticleNotFoundError } from 'common/errors' import { getLogger } from 'common/logger' import { i18n } from 'common/utils/i18n' import { GQLAppreciationTypeResolver } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('query-appreciation') const trans = { appreciateSubsidy: i18n({ diff --git a/src/queries/user/index.ts b/src/queries/user/index.ts index 828ad5e71..0c7e5ace3 100644 --- a/src/queries/user/index.ts +++ b/src/queries/user/index.ts @@ -100,7 +100,7 @@ const user: { CryptoWallet: GQLCryptoWalletTypeResolver } = { Query: { - viewer: (root, _, { viewer }) => viewer, + viewer: (_, __, { viewer }) => viewer, user: rootUser, }, User: { diff --git a/src/queries/user/liker/rateUSD.ts b/src/queries/user/liker/rateUSD.ts index bc7ba9730..f849b16cd 100644 --- a/src/queries/user/liker/rateUSD.ts +++ b/src/queries/user/liker/rateUSD.ts @@ -1,11 +1,10 @@ -import _ from 'lodash' - import { getLogger } from 'common/logger' import { LikerToRateUSDResolver } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('query-rate-usd') const resolver: LikerToRateUSDResolver = async ( - { id }, + _, __: any, { dataSources: { userService } } ) => { diff --git a/src/routes/oauth/index.ts b/src/routes/oauth/index.ts index 6cd34f7da..43e670a60 100644 --- a/src/routes/oauth/index.ts +++ b/src/routes/oauth/index.ts @@ -15,7 +15,8 @@ import { OAuthService } from 'connectors' import OAuthServer from './express-oauth-server' import initPassportStrategies from './strategies' -const logger = getLogger('default') + +const logger = getLogger('route-oauth') const oAuthRouter = Router() const oAuthService = new OAuthService() diff --git a/src/routes/oauth/strategies.ts b/src/routes/oauth/strategies.ts index b5ff3f17f..f5e84054c 100644 --- a/src/routes/oauth/strategies.ts +++ b/src/routes/oauth/strategies.ts @@ -1,13 +1,14 @@ import { invalidateFQC } from '@matters/apollo-response-cache' import LikeCoinStrategy from '@matters/passport-likecoin' -import _ from 'lodash' +import { get } from 'lodash' import passport from 'passport' import { NODE_TYPES, OAUTH_CALLBACK_ERROR_CODE } from 'common/enums' import { environment } from 'common/environment' import { getLogger } from 'common/logger' import { CacheService, UserService } from 'connectors' -const logger = getLogger('default') + +const logger = getLogger('route-auth') export default () => { passport.use( @@ -20,12 +21,12 @@ export default () => { callbackURL: environment.likecoinCallbackURL, passReqToCallback: true, }, - async (req, accessToken, refreshToken, params, profile, done) => { + async (req, accessToken, refreshToken, params, _, done) => { const userService = new UserService() const cacheService = new CacheService() const viewer = req.app.locals.viewer - const userId = _.get(viewer, 'id') - const likerId = _.get(params, 'user') + const userId = get(viewer, 'id') + const likerId = get(params, 'user') if (!userId) { return done(null, undefined, { diff --git a/src/routes/pay/likecoin.ts b/src/routes/pay/likecoin.ts index 31a218553..0302db47f 100644 --- a/src/routes/pay/likecoin.ts +++ b/src/routes/pay/likecoin.ts @@ -19,7 +19,8 @@ import { PaymentService, UserService, } from 'connectors' -const logger = getLogger('default') + +const logger = getLogger('route-likecoin') const likecoinRouter = Router() diff --git a/src/routes/pay/stripe/circle.ts b/src/routes/pay/stripe/circle.ts index 0aba9e5ff..0e83646b4 100644 --- a/src/routes/pay/stripe/circle.ts +++ b/src/routes/pay/stripe/circle.ts @@ -25,7 +25,8 @@ import { } from 'connectors' import SlackService from 'connectors/slack' import { CirclePrice, CircleSubscription, Customer } from 'definitions' -const logger = getLogger('default') + +const logger = getLogger('route-stripe-circle') const stripe = new Stripe(environment.stripeSecret, { apiVersion: '2020-08-27', diff --git a/src/routes/pay/stripe/connect/index.ts b/src/routes/pay/stripe/connect/index.ts index bc2c828a7..64a67b89a 100644 --- a/src/routes/pay/stripe/connect/index.ts +++ b/src/routes/pay/stripe/connect/index.ts @@ -7,7 +7,8 @@ import { getLogger } from 'common/logger' import SlackService from 'connectors/slack' import { updateAccount } from './account' -const logger = getLogger('default') + +const logger = getLogger('router-stripe-connect') const stripe = new Stripe(environment.stripeSecret, { apiVersion: '2020-08-27', diff --git a/src/routes/pay/stripe/index.ts b/src/routes/pay/stripe/index.ts index 272cebde5..3c568aaa8 100644 --- a/src/routes/pay/stripe/index.ts +++ b/src/routes/pay/stripe/index.ts @@ -16,7 +16,7 @@ import { import { updateCustomerCard } from './customer' import { createRefundTxs, updateTxState } from './transaction' -const logger = getLogger('route:stripe') +const logger = getLogger('route-stripe') const stripe = new Stripe(environment.stripeSecret, { apiVersion: '2020-08-27', From e98861a8b2451bd343f8e16562d37ac68b2c1b38 Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Fri, 12 May 2023 19:28:54 +0800 Subject: [PATCH 06/15] feat(logging): replace debuglog with logger --- package-lock.json | 1 - package.json | 1 - src/connectors/articleService.ts | 7 +++---- src/connectors/tagService.ts | 10 +++------- src/connectors/userService.ts | 6 +----- 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6732bbabf..48266650c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,6 @@ "cookie": "^0.4.1", "cors": "^2.8.5", "dataloader": "^2.0.0", - "debug": "^4.3.4", "dotenv": "^10.0.0", "eth-sig-util": "^3.0.1", "ethers": "^5.6.1", diff --git a/package.json b/package.json index 8e17702a7..818677f65 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "cookie": "^0.4.1", "cors": "^2.8.5", "dataloader": "^2.0.0", - "debug": "^4.3.4", "dotenv": "^10.0.0", "eth-sig-util": "^3.0.1", "ethers": "^5.6.1", diff --git a/src/connectors/articleService.ts b/src/connectors/articleService.ts index 5aae67337..bc085c746 100644 --- a/src/connectors/articleService.ts +++ b/src/connectors/articleService.ts @@ -4,7 +4,6 @@ import { } from '@matters/ipns-site-generator' import slugify from '@matters/slugify' import DataLoader from 'dataloader' -import createDebug from 'debug' import { Knex } from 'knex' import { v4 } from 'uuid' @@ -27,6 +26,7 @@ import { } from 'common/enums' import { environment } from 'common/environment' import { ArticleNotFoundError, ServerError } from 'common/errors' +import { getLogger } from 'common/logger' import { AtomService, BaseService, @@ -39,7 +39,7 @@ import { } from 'connectors' import { GQLSearchExclude, Item } from 'definitions' -const debugLog = createDebug('article-service') +const logger = getLogger('service-article') const IPFS_OP_TIMEOUT = 300e3 // increase time-out from 1 minute to 5 minutes @@ -977,8 +977,7 @@ export class ArticleService extends BaseService { // const totalCount = Number.parseInt(countRes?.count, 10) || nodes.length const totalCount = records.length === 0 ? 0 : +records[0].totalCount - debugLog( - // new Date(), + logger.debug( `articleService::searchV2 searchKnex instance got ${nodes.length} nodes from: ${totalCount} total:`, { key, keyOriginal, baseQuery: baseQuery.toString() }, // { countRes, articleIds } diff --git a/src/connectors/tagService.ts b/src/connectors/tagService.ts index e47aaa061..5eb1ea23c 100644 --- a/src/connectors/tagService.ts +++ b/src/connectors/tagService.ts @@ -1,5 +1,4 @@ import DataLoader from 'dataloader' -import createDebug from 'debug' import { Knex } from 'knex' import { @@ -9,11 +8,11 @@ import { VIEW, } from 'common/enums' import { environment } from 'common/environment' +import { getLogger } from 'common/logger' import { BaseService } from 'connectors' import { Item, ItemData } from 'definitions' -// import _ from 'lodash' -const debugLog = createDebug('tag-service') +const logger = getLogger('service-tag') export class TagService extends BaseService { constructor() { @@ -513,8 +512,6 @@ export class TagService extends BaseService { const c = +(coeffs?.[2] || environment.searchPgTagCoefficients?.[2] || 1) const d = +(coeffs?.[3] || environment.searchPgTagCoefficients?.[3] || 1) - // debugLog(new Date(), `searchV2 tag got search key:`, {key, keyOriginal,}) - const strip0 = key.startsWith('#') || key.startsWith('#') const _key = strip0 ? key.slice(1) : key @@ -592,8 +589,7 @@ export class TagService extends BaseService { const nodes = (await queryTags) as Item[] const totalCount = nodes.length === 0 ? 0 : +nodes[0].totalCount - debugLog( - // new Date(), + logger.debug( `tagService::searchV2 searchKnex instance got ${nodes.length} nodes from: ${totalCount} total:`, { key, keyOriginal, queryTags: queryTags.toString() }, { sample: nodes?.slice(0, 3) } diff --git a/src/connectors/userService.ts b/src/connectors/userService.ts index e8a14b631..b9772f787 100644 --- a/src/connectors/userService.ts +++ b/src/connectors/userService.ts @@ -1,6 +1,5 @@ import { compare } from 'bcrypt' import DataLoader from 'dataloader' -import createDebug from 'debug' import jwt from 'jsonwebtoken' import { Knex } from 'knex' import _, { random } from 'lodash' @@ -67,8 +66,6 @@ import { medium } from './medium' const logger = getLogger('service-user') -const debugLog = createDebug('user-service') - // const SEARCH_DEFAULT_TEXT_RANK_THRESHOLD = 0.0001 export class UserService extends BaseService { @@ -593,8 +590,7 @@ export class UserService extends BaseService { const records = (await queryUsers) as Item[] const totalCount = records.length === 0 ? 0 : +records[0].totalCount - debugLog( - // new Date(), + logger.debug( `userService::searchV2 searchKnex instance got ${records.length} nodes from: ${totalCount} total:`, { key, keyOriginal, queryUsers: queryUsers.toString() }, { sample: records?.slice(0, 3) } From 80ece7a29c08cee8b30ab46578658d4d4902d442 Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Fri, 12 May 2023 21:44:21 +0800 Subject: [PATCH 07/15] fix(logging): fix error stack formatter --- src/common/logger.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/logger.ts b/src/common/logger.ts index 0fa78bb60..d04227d76 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -14,16 +14,16 @@ const setContext = format((info, _) => { return info }) -const console = new transports.Console({ level: 'debug' }) +const consoleTransport = new transports.Console({ level: 'debug' }) const createWinstonLogger = (name: string, level: string) => createLogger({ level, format: format.combine( + format.errors({ stack: true }), format.splat(), setContext(), format.label({ label: name }), - format.errors({ stack: true }), format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss', }), @@ -31,10 +31,10 @@ const createWinstonLogger = (name: string, level: string) => (info) => `${info.timestamp} ${info.requestId ?? '-'} ${info.label} ${ info.level - }: ${info.message}` + }: ${info.message} ${info.stack ?? ''}` ) ), - transports: [console], + transports: [consoleTransport], }) const loggers = new Map() From 46a264623683d79255bf0ab163e98564ce1e0e9a Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Fri, 12 May 2023 22:41:20 +0800 Subject: [PATCH 08/15] feat(logging): turn off print during migration for tests --- ...20200226161830_migrate_article_read_to_article_read_count.js | 2 -- db/migrations/20200924152927_fix_article_draft_relationship.js | 2 -- db/migrations/20210519080506_payout_country.js | 1 - ...210604103456_fix_circle_subscription_billing_cycle_anchor.js | 1 - db/migrations/20210721140245_auto_follow_matty_tag.js | 1 - 5 files changed, 7 deletions(-) diff --git a/db/migrations/20200226161830_migrate_article_read_to_article_read_count.js b/db/migrations/20200226161830_migrate_article_read_to_article_read_count.js index 0f1778f89..8264ac5e6 100644 --- a/db/migrations/20200226161830_migrate_article_read_to_article_read_count.js +++ b/db/migrations/20200226161830_migrate_article_read_to_article_read_count.js @@ -9,7 +9,6 @@ exports.up = async (knex) => { const temp = await knex(source).from(querySource.as('source')).count().first() const count = parseInt(temp ? temp.count : '0', 10) - console.log('source count', count) // migrate await knex.raw(` @@ -32,7 +31,6 @@ exports.up = async (knex) => { // get total count of migrated records const result = await knex(target).count().first() const check = parseInt(result ? result.count : '0', 10) - console.log('migrated count', check) } exports.down = async (knex) => { diff --git a/db/migrations/20200924152927_fix_article_draft_relationship.js b/db/migrations/20200924152927_fix_article_draft_relationship.js index 384cf902b..0b47c50b6 100644 --- a/db/migrations/20200924152927_fix_article_draft_relationship.js +++ b/db/migrations/20200924152927_fix_article_draft_relationship.js @@ -71,7 +71,6 @@ exports.up = async (knex) => { GROUP BY article.id `) - console.log('created drafts.') // Update `draft_id` of articles await knex.raw(` @@ -94,7 +93,6 @@ exports.up = async (knex) => { WHERE article.id = draft_article.article_id `) - console.log('updated articles.') } exports.down = async (knex) => {} diff --git a/db/migrations/20210519080506_payout_country.js b/db/migrations/20210519080506_payout_country.js index bc6d1992a..cf1c7ebec 100644 --- a/db/migrations/20210519080506_payout_country.js +++ b/db/migrations/20210519080506_payout_country.js @@ -20,7 +20,6 @@ exports.up = async (knex) => { capabilities_transfers: true, }) if (!accounts || accounts.length <= 0) { - console.log('Payout accounts not found') return } diff --git a/db/migrations/20210604103456_fix_circle_subscription_billing_cycle_anchor.js b/db/migrations/20210604103456_fix_circle_subscription_billing_cycle_anchor.js index 5de28b40f..f3bf25ea1 100644 --- a/db/migrations/20210604103456_fix_circle_subscription_billing_cycle_anchor.js +++ b/db/migrations/20210604103456_fix_circle_subscription_billing_cycle_anchor.js @@ -60,7 +60,6 @@ exports.up = async (knex) => { .where({ provider: 'stripe' }) .whereIn('state', ['active', 'trialing']) if (!subs || subs.length <= 0) { - console.log(`${envLabel} subscriptions not found`) return } diff --git a/db/migrations/20210721140245_auto_follow_matty_tag.js b/db/migrations/20210721140245_auto_follow_matty_tag.js index a86c19096..257005547 100644 --- a/db/migrations/20210721140245_auto_follow_matty_tag.js +++ b/db/migrations/20210721140245_auto_follow_matty_tag.js @@ -6,7 +6,6 @@ exports.up = async (knex) => { .first() if (!matty) { - console.log('matty not found') return } From 47d31361cb0fc45e0a075bfe52d7ca1290da7b27 Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Mon, 15 May 2023 14:54:04 +0800 Subject: [PATCH 09/15] refactor(logging): replace console.log/error with logger --- src/common/utils/generateTypes.ts | 1 - src/connectors/__test__/tagService.test.ts | 2 - src/connectors/articleService.ts | 47 ++++++----------- src/connectors/aws/index.ts | 5 +- src/connectors/cloudflare/index.ts | 13 ++--- src/connectors/gcp/index.ts | 4 +- src/connectors/ipfs/index.ts | 12 ++--- src/connectors/likecoin/index.ts | 9 +--- src/connectors/opensea/index.ts | 1 - .../queue/__test__/publication.test.ts | 1 - src/connectors/queue/asset.ts | 1 - src/connectors/queue/publication.ts | 17 ++---- src/connectors/queue/revision.ts | 52 +++---------------- src/connectors/tagService.ts | 3 +- src/mutations/article/editArticle.ts | 5 +- src/mutations/system/singleFileUpload.ts | 5 +- src/mutations/user/updateUserInfo.ts | 5 +- src/mutations/user/walletLogin.ts | 5 +- src/routes/img-cache/index.ts | 7 ++- src/types/__test__/circle.test.ts | 5 -- 20 files changed, 71 insertions(+), 129 deletions(-) diff --git a/src/common/utils/generateTypes.ts b/src/common/utils/generateTypes.ts index d40c00cee..e6cf10b68 100644 --- a/src/common/utils/generateTypes.ts +++ b/src/common/utils/generateTypes.ts @@ -17,7 +17,6 @@ generateTypeScriptTypes(schema, 'src/definitions/schema.d.ts', { process.exit(0) }) .catch((err) => { - console.log(err) logger.error(err) process.exit(1) }) diff --git a/src/connectors/__test__/tagService.test.ts b/src/connectors/__test__/tagService.test.ts index 25ba7c8d3..5ae399cf8 100644 --- a/src/connectors/__test__/tagService.test.ts +++ b/src/connectors/__test__/tagService.test.ts @@ -49,7 +49,6 @@ describe('search', () => { take: 10, quicksearch: true, }) - console.log(new Date(), 'res:', res) expect(res.nodes?.[0]?.numArticles).toBeGreaterThanOrEqual( res.nodes?.[1]?.numArticles ) @@ -78,7 +77,6 @@ describe('search', () => { take: 10, quicksearch: true, }) - console.log(new Date(), 'res:', res1) expect(res1.nodes.length).toBe(4) expect(res1.totalCount).toBe(4) const res2 = await tagService.search({ diff --git a/src/connectors/articleService.ts b/src/connectors/articleService.ts index bc085c746..8fcf6a222 100644 --- a/src/connectors/articleService.ts +++ b/src/connectors/articleService.ts @@ -241,8 +241,7 @@ export class ArticleService extends BaseService { return { contentHash, mediaHash, key } } catch (err) { // if the active IPFS client throws exception, try a few more times on Secondary - console.error( - new Date(), + logger.error( `publishToIPFS failed, retries ${++retries} time, ERROR:`, err ) @@ -251,7 +250,7 @@ export class ArticleService extends BaseService { } while (ipfs && retries <= this.ipfsServers.size) // break the retry if there's no backup // re-fill dataHash & mediaHash later in IPNS-listener - console.error(new Date(), `failed publishToIPFS after ${retries} retries.`) + logger.error(`failed publishToIPFS after ${retries} retries.`) } // DEPRECATED, To Be Deleted @@ -281,7 +280,7 @@ export class ArticleService extends BaseService { const ipnsKeyRec = await userService.findOrCreateIPNSKey(author.userName) if (!ipnsKeyRec) { // cannot do anything if no ipns key - console.error(new Date(), 'create IPNS key ERROR:', ipnsKeyRec) + logger.error('create IPNS key ERROR:', ipnsKeyRec) return } @@ -300,11 +299,7 @@ export class ArticleService extends BaseService { } catch (err) { // ignore: key with name 'for-...' already exists if (!ipnsKey && err) { - console.error( - new Date(), - `ERROR: no ipnsKey for user: ${author.userName}`, - err - ) + logger.error(`ERROR: no ipnsKey for user: ${author.userName}`, err) } } @@ -329,7 +324,7 @@ export class ArticleService extends BaseService { const lastDraft = publishedDrafts[0] if (!lastDraft) { - console.error(new Date(), 'fetching published drafts ERROR:', { + logger.error('fetching published drafts ERROR:', { authorId: author.id, publishedDraftIds, }) @@ -361,7 +356,7 @@ export class ArticleService extends BaseService { 'last_published', ], }) - console.log(new Date(), 'start update IPNSRec:', updatedIPNSRec) + logger.info('start update IPNSRec:', updatedIPNSRec) // make a bundle of json+xml+html index const feed = new Feed(author, ipnsKey, publishedDrafts) @@ -387,7 +382,6 @@ export class ArticleService extends BaseService { results.push(result) } // const entriesMap = new Map(results.map((e: any) => [e.path, e])) - // console.log(new Date(), 'contents feed.json ::', results, entriesMap) let entry = results.filter( ({ path }: { path: string }) => path === directoryName @@ -455,8 +449,7 @@ export class ArticleService extends BaseService { break } catch (err) { // ignore HTTPError: GATEWAY_TIMEOUT - console.error( - new Date(), + logger.warn( `publishFeedToIPNS ipfs.files.cp attach'ing failed; delete target and retry ${retries} time, ERROR:`, err ) @@ -474,8 +467,7 @@ export class ArticleService extends BaseService { withLocal: true, timeout: IPFS_OP_TIMEOUT, // increase time-out from 1 minute to 5 minutes }) - console.log( - new Date(), + logger.info( `directoryName stat after tried ${ incremental ? 'last 1' : publishedDrafts.length }, and actually attached ${attached.length} articles:`, @@ -509,8 +501,7 @@ export class ArticleService extends BaseService { } catch (err) { // ignore: key with name 'for-...' already exists } - console.error( - new Date(), + logger.warn( `ipfs.name.publish (for ${userName}) failed; retry ${++retries} time, ERROR:`, err, { @@ -524,7 +515,7 @@ export class ArticleService extends BaseService { } while (retries <= this.ipfsServers.size) } - console.log(new Date(), `/${directoryName} published:`, published) + logger.info(`/${directoryName} published:`, published) this.aws .sqsSendMessage({ @@ -546,13 +537,11 @@ export class ArticleService extends BaseService { queueUrl: QUEUE_URL.ipfsArticles, }) // .then(res => {}) - .catch((err: Error) => - console.error(new Date(), 'failed sqs notify:', err) - ) + .catch((err: Error) => logger.error('failed sqs notify:', err)) return { ipnsKey, lastDataHash: cidToPublish.toString() } } catch (err) { - console.error(new Date(), `publishFeedToIPNS last ERROR:`, err, { + logger.error(`publishFeedToIPNS last ERROR:`, err, { ipnsKey, kname, directoryName, @@ -581,16 +570,14 @@ export class ArticleService extends BaseService { ], }) } else { - console.error( - new Date(), - 'publishFeedToIPNS: not published, or remained same:', - { published, cidToPublish: cidToPublish.toString() } - ) + logger.error('publishFeedToIPNS: not published, or remained same:', { + published, + cidToPublish: cidToPublish.toString(), + }) } const end = new Date() - console.log( - end, + logger.info( `IPNS published: elapsed ${((+end - started) / 60e3).toFixed(1)}min`, updatedRec ) diff --git a/src/connectors/aws/index.ts b/src/connectors/aws/index.ts index 1d48e8f9d..f919ee3bb 100644 --- a/src/connectors/aws/index.ts +++ b/src/connectors/aws/index.ts @@ -9,9 +9,12 @@ import { UPLOAD_IMAGE_SIZE_LIMIT, } from 'common/enums' import { environment, isLocal, isTest } from 'common/environment' +import { getLogger } from 'common/logger' import { getFileName } from 'common/utils' import { GQLAssetType } from 'definitions' +const logger = getLogger('service-aws') + export class AWSService { s3: AWS.S3 sqs: AWS.SQS @@ -173,7 +176,7 @@ export class AWSService { case 'NotFound': break default: - console.error(new Date(), 'ERROR:', err) + logger.error(err) throw err } } diff --git a/src/connectors/cloudflare/index.ts b/src/connectors/cloudflare/index.ts index 37fb6154b..abfc29d8a 100644 --- a/src/connectors/cloudflare/index.ts +++ b/src/connectors/cloudflare/index.ts @@ -4,8 +4,11 @@ import fetch from 'node-fetch' import path from 'path' import { environment, isProd } from 'common/environment' +import { getLogger } from 'common/logger' import { GQLAssetType } from 'definitions' +const logger = getLogger('service-cloudflare') + const envPrefix = isProd ? 'prod' : 'non-prod' const CLOUDFLARE_IMAGES_URL = `https://api.cloudflare.com/client/v4/accounts/${environment.cloudflareAccountId}/images/v1` @@ -40,10 +43,9 @@ export class CloudflareService { try { const resData = await res.json() - console.log(new Date(), 'CloudflareService upload image:', resData) + logger.info('CloudflareService upload image:', resData) } catch (err) { - console.error( - new Date(), + logger.error( 'CloudflareService upload image ERROR:', err, res.ok, @@ -81,10 +83,9 @@ export class CloudflareService { try { const resData = await res.json() - console.log(new Date(), 'CloudflareService upload image:', resData) + logger.info('CloudflareService upload image:', resData) } catch (err) { - console.error( - new Date(), + logger.error( 'CloudflareService upload image ERROR:', err, res.ok, diff --git a/src/connectors/gcp/index.ts b/src/connectors/gcp/index.ts index 1c571b18d..ba842474d 100644 --- a/src/connectors/gcp/index.ts +++ b/src/connectors/gcp/index.ts @@ -121,13 +121,13 @@ class GCP { const { success, score } = data if (!success) { - console.error(new Date(), 'gcp recaptcha no success:', data) + logger.warn('gcp recaptcha no success:', data) throw new ActionFailedError(`please try again: ${data['error-codes']}`) } // fail for less than 0.5 if (score < 0.5) { - console.log('very likely bot traffic:', data) + logger.info('very likely bot traffic:', data) } // pass diff --git a/src/connectors/ipfs/index.ts b/src/connectors/ipfs/index.ts index 295edb537..7d2cadea7 100644 --- a/src/connectors/ipfs/index.ts +++ b/src/connectors/ipfs/index.ts @@ -4,11 +4,13 @@ import { create } from 'ipfs-http-client' import fetch from 'node-fetch' import { Readable } from 'stream' import { promisify } from 'util' -// import { v4 } from 'uuid' - -const generateKeyPairPromisified = promisify(generateKeyPair) import { environment } from 'common/environment' +import { getLogger } from 'common/logger' + +const logger = getLogger('service-ipfs') + +const generateKeyPairPromisified = promisify(generateKeyPair) const ipfsServerUrls = ( environment.ipfsServers || @@ -66,13 +68,11 @@ export class IPFSServer { body: formData, }) try { - // console.log(new Date(), `POST ${ipfsServerUrls[idx]}/api/v0/key/import with formData:`, formData, 'res:', res.ok, res.headers) const imported = await res.json() return { imported, client: this.clients[idx] } } catch (err) { - console.error( - new Date(), + logger.error( 'importKey ERROR:', err, res.ok, diff --git a/src/connectors/likecoin/index.ts b/src/connectors/likecoin/index.ts index 9127e0a50..a4f0429dd 100644 --- a/src/connectors/likecoin/index.ts +++ b/src/connectors/likecoin/index.ts @@ -608,17 +608,12 @@ export class LikeCoin { }) if (!data) { - console.error('iscnPublish with no data:', res) + logger.error('iscnPublish with no data:', res) throw res } if (!data.iscnId) { - console.error( - 'iscnPublish failed posted results:', - res, - 'with:', - postData - ) + logger.error('iscnPublish failed posted results:', res, 'with:', postData) } return data.iscnId diff --git a/src/connectors/opensea/index.ts b/src/connectors/opensea/index.ts index 80f319aa8..d85c165c1 100644 --- a/src/connectors/opensea/index.ts +++ b/src/connectors/opensea/index.ts @@ -54,7 +54,6 @@ export class OpenSeaService extends RESTDataSource { return data.assets } catch (err) { logger.error(err) - // console.error(new Date(), 'ERROR:', err) return [] } diff --git a/src/connectors/queue/__test__/publication.test.ts b/src/connectors/queue/__test__/publication.test.ts index 934c542a8..50aca92d0 100644 --- a/src/connectors/queue/__test__/publication.test.ts +++ b/src/connectors/queue/__test__/publication.test.ts @@ -59,7 +59,6 @@ describe('publicationQueue.publishArticle', () => { test('publish pending draft unsuccessfully', async () => { // mock queue.userService.baseFindById = async (_) => { - console.log('mocked publicationQueue.userService.baseFindById is called') throw Error('mock error in queue test') } const { draft } = await createPendingDraft() diff --git a/src/connectors/queue/asset.ts b/src/connectors/queue/asset.ts index 6a195532f..1ed506e12 100644 --- a/src/connectors/queue/asset.ts +++ b/src/connectors/queue/asset.ts @@ -79,7 +79,6 @@ class AssetQueue extends BaseQueue { done(null, job.data) } catch (err) { logger.error(err) - console.error('delete assets ERROR:', err) done(err) } } diff --git a/src/connectors/queue/publication.ts b/src/connectors/queue/publication.ts index b991c99f2..5bb694282 100644 --- a/src/connectors/queue/publication.ts +++ b/src/connectors/queue/publication.ts @@ -137,7 +137,7 @@ export class PublicationQueue extends BaseQueue { try { contentMd = html2md(draft.content) } catch (e) { - console.error('failed to convert HTML to Markdown', draft.id) + logger.warn('failed to convert HTML to Markdown', draft.id) } const [publishedDraft, _] = await Promise.all([ this.draftService.baseUpdate(draft.id, { @@ -219,7 +219,7 @@ export class PublicationQueue extends BaseQueue { await job.progress(75) } catch (err) { // ignore errors caused by these steps - console.error(new Date(), 'optional step failed:', err, job, draft) + logger.warn('optional step failed:', err, job, draft) } // Step 7: trigger notifications @@ -323,10 +323,7 @@ export class PublicationQueue extends BaseQueue { await job.progress(95) } catch (err) { // ignore errors caused by these steps - logger.error(err) - - console.error( - new Date(), + logger.warn( 'job IPFS optional step failed (will retry async later in listener):', err, job, @@ -345,9 +342,7 @@ export class PublicationQueue extends BaseQueue { // no await to notify async this.articleService .sendArticleFeedMsgToSQS({ article, author, ipnsData: ipnsRes }) - .catch((err: Error) => - console.error(new Date(), 'failed sqs notify:', err) - ) + .catch((err: Error) => logger.error('failed sqs notify:', err)) // no await to notify async this.atomService.aws @@ -370,9 +365,7 @@ export class PublicationQueue extends BaseQueue { }, }) // .then(res => {}) - .catch((err: Error) => - console.error(new Date(), 'failed sns notify:', err) - ) + .catch((err: Error) => logger.error('failed sns notify:', err)) done(null, { articleId: article.id, diff --git a/src/connectors/queue/revision.ts b/src/connectors/queue/revision.ts index b07b72e47..20a2e8925 100644 --- a/src/connectors/queue/revision.ts +++ b/src/connectors/queue/revision.ts @@ -18,11 +18,14 @@ import { QUEUE_PRIORITY, } from 'common/enums' import { environment, isTest } from 'common/environment' +import { getLogger } from 'common/logger' import { countWords, fromGlobalId } from 'common/utils' import { AtomService, NotificationService } from 'connectors' import { BaseQueue } from './baseQueue' +const logger = getLogger('queue-revision') + interface RevisedArticleData { draftId: string iscnPublish?: boolean @@ -53,29 +56,6 @@ class RevisionQueue extends BaseQueue { return } - this.q - .on('error', (err) => { - // An error occured. - console.error('RevisionQueue: job error unhandled:', err) - }) - .on('waiting', (jobId) => { - // A Job is waiting to be processed as soon as a worker is idling. - }) - .on('progress', (job, progress) => { - // A job's progress was updated! - console.log( - `RevisionQueue: Job#${job.id}/${job.name} progress progress` - ) - }) - .on('failed', (job, err) => { - // A job failed with reason `err`! - console.error('RevisionQueue: job failed:', err, job) - }) - .on('completed', (job, result) => { - // A job successfully completed with a `result`. - console.log(`RevisionQueue: Job#${job.id}/${job.name} completed`) - }) - // publish revised article this.q.process( QUEUE_JOB.publishRevisedArticle, @@ -187,13 +167,7 @@ class RevisionQueue extends BaseQueue { job.progress(70) } catch (err) { // ignore errors caused by these steps - console.error( - new Date(), - 'job failed at optional step:', - err, - job, - draft.id - ) + logger.error('job failed at optional step:', err, job, draft.id) } // Step 8: trigger notifications @@ -296,13 +270,7 @@ class RevisionQueue extends BaseQueue { forceReplace: true, }) } catch (err) { - console.error( - new Date(), - 'job failed at optional step:', - err, - job, - draft.id - ) + logger.warn('job failed at optional step:', err, job, draft.id) } job.progress(100) @@ -310,9 +278,7 @@ class RevisionQueue extends BaseQueue { // no await to notify async this.articleService .sendArticleFeedMsgToSQS({ article, author, ipnsData: ipnsRes }) - .catch((err: Error) => - console.error(new Date(), 'failed sqs notify:', err) - ) + .catch((err: Error) => logger.error('failed sqs notify:', err)) // no await to notify async this.atomService.aws @@ -334,9 +300,7 @@ class RevisionQueue extends BaseQueue { displayName, }, }) - .catch((err: Error) => - console.error(new Date(), 'failed sns notify:', err) - ) + .catch((err: Error) => logger.error('failed sns notify:', err)) done(null, { articleId: article.id, @@ -377,7 +341,7 @@ class RevisionQueue extends BaseQueue { where: { articleId: article.id, circleId }, data: { secret, - updatedAt: this.knex.fn.now(), // new Date() + updatedAt: this.knex.fn.now(), }, }) } diff --git a/src/connectors/tagService.ts b/src/connectors/tagService.ts index 5eb1ea23c..04487a0eb 100644 --- a/src/connectors/tagService.ts +++ b/src/connectors/tagService.ts @@ -1064,8 +1064,7 @@ export class TagService extends BaseService { .filter(Boolean) .map((tag) => this.follow({ targetId: tag.id, userId }).catch((err) => - console.error( - new Date(), + logger.error( `ERROR: follow "${tag.id}-${tag.content}" failed:`, err, tag diff --git a/src/mutations/article/editArticle.ts b/src/mutations/article/editArticle.ts index bd7254742..f41a6edf0 100644 --- a/src/mutations/article/editArticle.ts +++ b/src/mutations/article/editArticle.ts @@ -38,6 +38,7 @@ import { TooManyTagsForArticleError, UserInputError, } from 'common/errors' +import { getLogger } from 'common/logger' import { fromGlobalId, measureDiffs, @@ -51,6 +52,8 @@ import { MutationToEditArticleResolver, } from 'definitions' +const logger = getLogger('mutation-edit-article') + const resolver: MutationToEditArticleResolver = async ( _, { @@ -386,7 +389,7 @@ const resolver: MutationToEditArticleResolver = async ( try { contentMd = html2md(_content) } catch (e) { - console.error('failed to convert HTML to Markdown', draft.id) + logger.warn('failed to convert HTML to Markdown', draft.id) } const data: Record = lodash.omitBy( { diff --git a/src/mutations/system/singleFileUpload.ts b/src/mutations/system/singleFileUpload.ts index cb9a6e1f6..16aeb11d2 100644 --- a/src/mutations/system/singleFileUpload.ts +++ b/src/mutations/system/singleFileUpload.ts @@ -11,9 +11,12 @@ import { UPLOAD_IMAGE_SIZE_LIMIT, } from 'common/enums' import { UnableToUploadFromUrl, UserInputError } from 'common/errors' +import { getLogger } from 'common/logger' import { fromGlobalId } from 'common/utils' import { ItemData, MutationToSingleFileUploadResolver } from 'definitions' +const logger = getLogger('mutation-upload') + const getFileName = (disposition: string, url: string) => { if (disposition) { const match = disposition.match(/filename="(.*)"/i) || [] @@ -114,7 +117,7 @@ const resolver: MutationToSingleFileUploadResolver = async ( ? await systemService.cfsvc.baseUploadFile(type, upload, uuid) : await systemService.aws.baseUploadFile(type, upload, uuid) } catch (err) { - console.error(new Date(), 'cloudflare upload image ERROR:') + logger.error('cloudflare upload image ERROR:', err) throw err } diff --git a/src/mutations/user/updateUserInfo.ts b/src/mutations/user/updateUserInfo.ts index c6ae108c4..7810344fb 100644 --- a/src/mutations/user/updateUserInfo.ts +++ b/src/mutations/user/updateUserInfo.ts @@ -28,7 +28,7 @@ import { MutationToUpdateUserInfoResolver, } from 'definitions' -const logger = getLogger('mutation-to-update-user-info') +const logger = getLogger('mutation-update-user-info') const resolver: MutationToUpdateUserInfoResolver = async ( _, @@ -72,8 +72,7 @@ const resolver: MutationToUpdateUserInfoResolver = async ( uuid ) } catch (err) { - // ... - console.error(`baseServerSideUploadFile error:`, err) + logger.error(`baseServerSideUploadFile error:`, err) throw err } if (keyPath) { diff --git a/src/mutations/user/walletLogin.ts b/src/mutations/user/walletLogin.ts index 5c7a11b84..60bb2ae20 100644 --- a/src/mutations/user/walletLogin.ts +++ b/src/mutations/user/walletLogin.ts @@ -19,6 +19,7 @@ import { EthAddressNotFoundError, UserInputError, } from 'common/errors' +import { getLogger } from 'common/logger' import { getAlchemyProvider, getViewerFromUser, @@ -33,6 +34,8 @@ import { MutationToWalletLoginResolver, } from 'definitions' +const logger = getLogger('mutation-wallet-login') + const resolver: MutationToWalletLoginResolver = async ( _, { input: { ethAddress, nonce, signedMessage, signature, email, codeId } }, @@ -251,7 +254,7 @@ const resolver: MutationToWalletLoginResolver = async ( // auto follow matty await userService .follow(newUser.id, environment.mattyId) - .then((err) => console.error(new Date(), 'follow matty failed:', err)) + .then((err) => logger.warn('follow matty failed:', err)) // auto follow tags await tagService.followTags(newUser.id, AUTO_FOLLOW_TAGS) diff --git a/src/routes/img-cache/index.ts b/src/routes/img-cache/index.ts index 729b66b5d..4a4cb49d6 100644 --- a/src/routes/img-cache/index.ts +++ b/src/routes/img-cache/index.ts @@ -1,10 +1,13 @@ import { Request, Response, Router } from 'express' import { v4 } from 'uuid' +import { getLogger } from 'common/logger' import { getViewerFromReq } from 'common/utils' import { cfsvc } from 'connectors' import { GQLAssetType } from 'definitions' +const logger = getLogger('route-img-cache') + export const imgCache = Router() imgCache.get('/*', async (req: Request, res: Response) => { @@ -12,7 +15,7 @@ imgCache.get('/*', async (req: Request, res: Response) => { try { viewer = await getViewerFromReq({ req }) } catch (err) { - console.error(new Date(), 'ERROR:', err) + logger.error('ERROR:', err) } if (!viewer?.id) { res.status(401).end() @@ -30,7 +33,7 @@ imgCache.get('/*', async (req: Request, res: Response) => { uuid ) } catch (err) { - console.error(new Date(), 'cloudflare upload image ERROR:', err) + logger.error('cloudflare upload image ERROR:', err) res.status(400).end() return } diff --git a/src/types/__test__/circle.test.ts b/src/types/__test__/circle.test.ts index 88904719b..0f8374b4c 100644 --- a/src/types/__test__/circle.test.ts +++ b/src/types/__test__/circle.test.ts @@ -595,11 +595,6 @@ describe('circle CRUD', () => { const circle = _get(data, 'viewer.ownCircles[0]') const article = _get(data, 'viewer.articles.edges[1].node') - console.log( - 'GET_VIEWER_OWN_CIRCLES::', - JSON.stringify({ data, circle, article }, null, 2) - ) - // add to circle with paywall access const paywallInput: Record = { id: circle.id, From 1747c8ce6a4caf210c3e0adfbc1ab54b7864ef08 Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Mon, 15 May 2023 15:44:19 +0800 Subject: [PATCH 10/15] fix(logging): fix broken logging level filter --- .env.example | 2 +- src/common/logger.ts | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index ca2eeb7ac..42d6dca15 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,6 @@ MATTERS_ENV=local MATTERS_LOGGING_LEVEL=info -MATTERS_DEBUG=queue,resolver +MATTERS_DEBUG=queue,service-article MATTERS_SERVER_DOMAIN=localhost:4000 MATTERS_SITE_DOMAIN=localhost:3000 MATTERS_OAUTH_SITE_DOMAIN=localhost:3000 diff --git a/src/common/logger.ts b/src/common/logger.ts index d04227d76..d00bea529 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -14,8 +14,6 @@ const setContext = format((info, _) => { return info }) -const consoleTransport = new transports.Console({ level: 'debug' }) - const createWinstonLogger = (name: string, level: string) => createLogger({ level, @@ -34,7 +32,7 @@ const createWinstonLogger = (name: string, level: string) => }: ${info.message} ${info.stack ?? ''}` ) ), - transports: [consoleTransport], + transports: [new transports.Console({ level })], }) const loggers = new Map() From 30e25ef158941bab5728473c3670f0ceef991075 Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Mon, 15 May 2023 16:30:11 +0800 Subject: [PATCH 11/15] ci(logging): set logging level to warn during test and turn of db seed logging in ci --- .github/workflows/test.yml | 1 + db/globalTestSetup.js | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c58f24fd1..6cc3e449f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -72,6 +72,7 @@ jobs: env: CODECOV_TOKEN: de5ab681-0837-4a24-b614-0a29225a7e4c MATTERS_ENV: test + MATTERS_LOGGING_LEVEL: warn MATTERS_PG_HOST: localhost MATTERS_PG_USER: postgres MATTERS_PG_PASSWORD: postgres diff --git a/db/globalTestSetup.js b/db/globalTestSetup.js index 77464e4ac..989dfce28 100644 --- a/db/globalTestSetup.js +++ b/db/globalTestSetup.js @@ -16,7 +16,7 @@ const user = process.env['MATTERS_PG_USER'] const password = process.env['MATTERS_PG_PASSWORD'] // https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables -const isCI = !!process.env['CI'] +const debug = process.env['MATTERS_LOGGING_LEVEL'] === 'debug' global.knex = knex @@ -79,11 +79,11 @@ async function runShellDBRollup() { const sh = spawn('sh', ['-xc', cmd], { cwd, env }) sh.stdout.on('data', (data) => { - if (isCI) console.log(`stdout: ${data}`) + if (debug) console.log(`stdout: ${data}`) }) sh.stderr.on('data', (data) => { - if (isCI) console.log(`stderr: ${data}`) + if (debug) console.log(`stderr: ${data}`) }) sh.on('error', (error) => { @@ -92,7 +92,7 @@ async function runShellDBRollup() { }) sh.on('close', (code) => { - if (isCI) console.log(`child process exited with code ${code}`) + if (debug) console.log(`child process exited with code ${code}`) fulfilled() }) }) From 7eda0381c09440df14dc73d459c099f2c1187b63 Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Mon, 15 May 2023 18:43:10 +0800 Subject: [PATCH 12/15] feat(logging): refine logging --- src/common/logger.ts | 6 +++- src/connectors/aws/index.ts | 31 +++++++++++-------- src/connectors/likecoin/index.ts | 3 +- src/connectors/notificationService/index.ts | 4 +-- src/connectors/queue/utils.ts | 4 +-- src/connectors/stripe/index.ts | 33 +++++++++++++++++++++ 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/common/logger.ts b/src/common/logger.ts index d00bea529..15b4d5810 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -18,8 +18,8 @@ const createWinstonLogger = (name: string, level: string) => createLogger({ level, format: format.combine( - format.errors({ stack: true }), format.splat(), + format.errors({ stack: true }), setContext(), format.label({ label: name }), format.timestamp({ @@ -49,3 +49,7 @@ export const getLogger = (name: string) => { loggers.set(name, newLogger) return newLogger } + +// print environment + +getLogger('env').debug('environment %s', environment) diff --git a/src/connectors/aws/index.ts b/src/connectors/aws/index.ts index f919ee3bb..332089f79 100644 --- a/src/connectors/aws/index.ts +++ b/src/connectors/aws/index.ts @@ -196,13 +196,15 @@ export class AWSService { /** * Delete file from AWS S3 by a given path key. */ - baseDeleteFile = async (key: string) => - this.s3 + baseDeleteFile = async (key: string) => { + logger.info(`Deleting file from S3: ${key}`) + await this.s3 .deleteObject({ Bucket: this.s3Bucket, Key: key, }) .promise() + } sqsSendMessage = async ({ messageBody, @@ -214,15 +216,16 @@ export class AWSService { queueUrl: typeof QUEUE_URL[keyof typeof QUEUE_URL] messageGroupId?: string messageDeduplicationId?: string - }) => - this.sqs - ?.sendMessage({ - MessageBody: JSON.stringify(messageBody), - QueueUrl: queueUrl, - MessageGroupId: messageGroupId, - MessageDeduplicationId: messageDeduplicationId, - }) - .promise() + }) => { + const payload = { + MessageBody: JSON.stringify(messageBody), + QueueUrl: queueUrl, + MessageGroupId: messageGroupId, + MessageDeduplicationId: messageDeduplicationId, + } + const res = await this.sqs?.sendMessage(payload).promise() + logger.info(`Sent message %o to SQS: %o`, payload, res) + } snsPublishMessage = async ({ // MessageGroupId, @@ -231,8 +234,8 @@ export class AWSService { // MessageGroupId: string // Message: any MessageBody: any - }) => - this.sns + }) => { + const res = this.sns ?.publish({ Message: JSON.stringify({ default: JSON.stringify(MessageBody), @@ -246,6 +249,8 @@ export class AWSService { TopicArn: environment.awsArticlesSnsTopic, }) .promise() + logger.info(`Sent message %o to SNS: %o`, MessageBody, res) + } } export const aws = new AWSService() diff --git a/src/connectors/likecoin/index.ts b/src/connectors/likecoin/index.ts index a4f0429dd..99f661e7b 100644 --- a/src/connectors/likecoin/index.ts +++ b/src/connectors/likecoin/index.ts @@ -155,6 +155,7 @@ export class LikeCoin { } } + logger.info('request %s with %s', endpoint, params) return axios({ url: endpoint, baseURL: likecoinApiURL, @@ -613,7 +614,7 @@ export class LikeCoin { } if (!data.iscnId) { - logger.error('iscnPublish failed posted results:', res, 'with:', postData) + logger.warn('iscnPublish failed posted results:', res, 'with:', postData) } return data.iscnId diff --git a/src/connectors/notificationService/index.ts b/src/connectors/notificationService/index.ts index 6314a13ed..09e6ae358 100644 --- a/src/connectors/notificationService/index.ts +++ b/src/connectors/notificationService/index.ts @@ -201,7 +201,7 @@ export class NotificationService extends BaseService { )) as User if (!recipient) { - logger.info(`recipient ${params.recipientId} not found, skipped`) + logger.warn(`recipient ${params.recipientId} not found, skipped`) return } @@ -213,7 +213,7 @@ export class NotificationService extends BaseService { // skip if actor === recipient if ('actorId' in params && params.actorId === params.recipientId) { - logger.info( + logger.warn( `Actor ${params.actorId} is same as recipient ${params.recipientId}, skipped` ) return diff --git a/src/connectors/queue/utils.ts b/src/connectors/queue/utils.ts index 97f54d627..49dd0dfce 100644 --- a/src/connectors/queue/utils.ts +++ b/src/connectors/queue/utils.ts @@ -45,7 +45,7 @@ export const createQueue = ( queue.on('active', (job, _) => { // A job has started. You can use `jobPromise.cancel()`` to abort it. - logger.debug(`Job#%s has started.`, job.id) + logger.info(`Job#%s has started.`, job.id) }) queue.on('stalled', (job) => { @@ -66,7 +66,7 @@ export const createQueue = ( queue.on('completed', (job, result) => { // A job successfully completed with a `result`. - logger.debug('Job#%s/%s has been completed: %o.', job.id, job.name, result) + logger.info('Job#%s/%s has been completed: %o.', job.id, job.name, result) }) queue.on('failed', (job, err) => { diff --git a/src/connectors/stripe/index.ts b/src/connectors/stripe/index.ts index ccbd69668..f6363eeb9 100644 --- a/src/connectors/stripe/index.ts +++ b/src/connectors/stripe/index.ts @@ -72,6 +72,7 @@ class StripeService { * Customer */ createCustomer = async ({ user }: { user: User }) => { + logger.info('create customer for user %s', user.id) try { return await this.stripeAPI.customers.create({ email: user.email, @@ -89,6 +90,7 @@ class StripeService { id: string paymentMethod: string }) => { + logger.info('update customer %s with payment method %s', id, paymentMethod) try { return await this.stripeAPI.customers.update(id, { invoice_settings: { @@ -125,6 +127,7 @@ class StripeService { amount: number currency: PAYMENT_CURRENCY }) => { + logger.info('create payment intent for customer %s', customerId) try { return await this.stripeAPI.paymentIntents.create({ customer: customerId, @@ -151,6 +154,7 @@ class StripeService { customerId: string metadata?: Stripe.MetadataParam }) => { + logger.info('create setup intent for customer %s', customerId) try { return await this.stripeAPI.setupIntents.create({ customer: customerId, @@ -178,6 +182,7 @@ class StripeService { const isUS = country === 'UnitedStates' const returnUrlPrefix = `https://${environment.siteDomain}/oauth/stripe-connect` + logger.info('create express account for user %s', user.id) try { const account = await this.stripeAPI.accounts.create({ type: 'express', @@ -225,6 +230,13 @@ class StripeService { recipientStripeConnectedId: string txId: string }) => { + logger.info( + 'transfer[%s] %s %s to %s', + txId, + amount, + currency, + recipientStripeConnectedId + ) try { return await this.stripeAPI.transfers.create({ amount: toProviderAmount({ amount }), @@ -241,6 +253,7 @@ class StripeService { * Product & Price */ createProduct = async ({ name, owner }: { name: string; owner: string }) => { + logger.info('create product %s for user %s', name, owner) try { return await this.stripeAPI.products.create({ name, @@ -252,6 +265,7 @@ class StripeService { } updateProduct = async ({ id, name }: { id: string; name: string }) => { + logger.info('update product %s to %s', id, name) try { return await this.stripeAPI.products.update(id, { name }) } catch (error) { @@ -270,6 +284,13 @@ class StripeService { interval: 'month' | 'week' productId: string }) => { + logger.info( + 'create price %s %s %s for product %s', + amount, + currency, + interval, + productId + ) try { return await this.stripeAPI.prices.create({ currency, @@ -292,6 +313,11 @@ class StripeService { customer: string price: string }) => { + logger.info( + 'create subscription for customer %s with price %s', + customer, + price + ) try { const trialEndAt = (isProd ? getUTCNextMonthDayOne() : getUTCNextMonday()) / 1000 @@ -308,6 +334,7 @@ class StripeService { } cancelSubscription = async (id: string) => { + logger.info('cancel subscription %s', id) try { return await this.stripeAPI.subscriptions.del(id, { prorate: false }) } catch (error) { @@ -322,6 +349,11 @@ class StripeService { price: string subscription: string }) => { + logger.info( + 'create subscription item %s for subscription %s', + price, + subscription + ) try { return await this.stripeAPI.subscriptionItems.create({ price, @@ -335,6 +367,7 @@ class StripeService { } deleteSubscriptionItem = async (id: string) => { + logger.info('delete subscription item %s', id) try { return await this.stripeAPI.subscriptionItems.del(id, { proration_behavior: 'none', From c33b9677e25f21d490f7eee6ac24687c468e70e1 Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Mon, 15 May 2023 20:01:14 +0800 Subject: [PATCH 13/15] feat(logging): logging resolvers' error with diffiently level --- src/middlewares/logger.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/middlewares/logger.ts b/src/middlewares/logger.ts index f77e98e37..40eecf272 100644 --- a/src/middlewares/logger.ts +++ b/src/middlewares/logger.ts @@ -13,7 +13,13 @@ export const loggerMiddleware = async ( const result = await resolve(root, args, context, info) return result } catch (error) { - logger.error(error) + if (error.extensions) { + // expected errors + logger.warn(error.name) + } else { + // unexpected errors + logger.error(error) + } throw error } } From 15b5ac65f37e929f80c2d79e33cb1e2d2ada9407 Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Mon, 15 May 2023 22:40:27 +0800 Subject: [PATCH 14/15] feat(logging): better log format --- src/common/logger.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/logger.ts b/src/common/logger.ts index 15b4d5810..4c0f6ef46 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -27,9 +27,9 @@ const createWinstonLogger = (name: string, level: string) => }), format.printf( (info) => - `${info.timestamp} ${info.requestId ?? '-'} ${info.label} ${ + `${info.timestamp} ${info.requestId ?? '-'} ${info.label} [${ info.level - }: ${info.message} ${info.stack ?? ''}` + }]: ${info.message} ${info.stack ?? ''}` ) ), transports: [new transports.Console({ level })], From f190c9f1d759c0e3572b170c3300ee80d88d820e Mon Sep 17 00:00:00 2001 From: xdj <13580441+gary02@users.noreply.github.com> Date: Tue, 16 May 2023 10:33:02 +0800 Subject: [PATCH 15/15] feat(logging): add logging enums and types --- src/common/enums/index.ts | 1 + src/common/enums/logging.ts | 10 ++++++++++ src/common/logger.ts | 15 +++++++++++---- src/definitions/generic.d.ts | 1 + src/definitions/index.d.ts | 1 + src/index.ts | 8 ++++---- 6 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 src/common/enums/logging.ts create mode 100644 src/definitions/generic.d.ts diff --git a/src/common/enums/index.ts b/src/common/enums/index.ts index 78a4bfeb2..98d63ed3e 100644 --- a/src/common/enums/index.ts +++ b/src/common/enums/index.ts @@ -25,6 +25,7 @@ export * from './hardcode' export * from './cors' export * from './routes' export * from './sqs' +export * from './logging' export const GRAPHQL_COST_LIMIT = 500 diff --git a/src/common/enums/logging.ts b/src/common/enums/logging.ts new file mode 100644 index 000000000..dcbe4765d --- /dev/null +++ b/src/common/enums/logging.ts @@ -0,0 +1,10 @@ +export const LOGGING_LEVEL = { + debug: 'debug', + info: 'info', + warn: 'warn', + error: 'error', +} as const + +export const LOGGING_CONTEXT_KEY = { + requestId: 'requestId', +} as const diff --git a/src/common/logger.ts b/src/common/logger.ts index 4c0f6ef46..e72c23776 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -1,9 +1,16 @@ import { AsyncLocalStorage } from 'async_hooks' import { createLogger, format, transports } from 'winston' +import { LOGGING_CONTEXT_KEY, LOGGING_LEVEL } from 'common/enums' import { environment } from 'common/environment' +import type { ValueOf } from 'definitions' -export const contextStorage = new AsyncLocalStorage>() +export type LoggingLevel = ValueOf +export type LoggingContextKey = ValueOf + +export const contextStorage = new AsyncLocalStorage< + Map +>() const setContext = format((info, _) => { const context = contextStorage.getStore() @@ -14,7 +21,7 @@ const setContext = format((info, _) => { return info }) -const createWinstonLogger = (name: string, level: string) => +const createWinstonLogger = (name: string, level: LoggingLevel) => createLogger({ level, format: format.combine( @@ -43,8 +50,8 @@ export const getLogger = (name: string) => { return logger } const level = environment.debug.includes(name) - ? 'debug' - : environment.loggingLevel + ? LOGGING_LEVEL.debug + : (environment.loggingLevel as LoggingLevel) const newLogger = createWinstonLogger(name, level) loggers.set(name, newLogger) return newLogger diff --git a/src/definitions/generic.d.ts b/src/definitions/generic.d.ts new file mode 100644 index 000000000..834a4ab81 --- /dev/null +++ b/src/definitions/generic.d.ts @@ -0,0 +1 @@ +export type ValueOf = T[keyof T] diff --git a/src/definitions/index.d.ts b/src/definitions/index.d.ts index 123f725c7..53c32506f 100644 --- a/src/definitions/index.d.ts +++ b/src/definitions/index.d.ts @@ -27,6 +27,7 @@ export * from './article' export * from './language' export * from './schema' export * from './notification' +export * from './generic' export type User = { id: string diff --git a/src/index.ts b/src/index.ts index f037e8ae4..713952199 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,9 +6,9 @@ import 'module-alias/register' import requestIp from 'request-ip' import { v4 } from 'uuid' -import { CORS_OPTIONS, IMG_CACHE_PATH } from 'common/enums' +import { CORS_OPTIONS, IMG_CACHE_PATH, LOGGING_CONTEXT_KEY } from 'common/enums' import { environment } from 'common/environment' -import { contextStorage } from 'common/logger' +import { contextStorage, LoggingContextKey } from 'common/logger' import * as routes from './routes' ;(async () => { @@ -39,8 +39,8 @@ import * as routes from './routes' // store request-id in AsyncLocalStorage app.use((req, _, next) => { const traceId = req.header('x-trace-id') - const context = new Map() - context.set('requestId', traceId ?? v4()) + const context = new Map() + context.set(LOGGING_CONTEXT_KEY.requestId, traceId ?? v4()) contextStorage.enterWith(context) next() })