diff --git a/.env.example b/.env.example index f03f0fe4f..42d6dca15 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,6 @@ MATTERS_ENV=local +MATTERS_LOGGING_LEVEL=info +MATTERS_DEBUG=queue,service-article MATTERS_SERVER_DOMAIN=localhost:4000 MATTERS_SITE_DOMAIN=localhost:3000 MATTERS_OAUTH_SITE_DOMAIN=localhost:3000 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() }) }) 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 } diff --git a/package-lock.json b/package-lock.json index 510248dc9..48266650c 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", @@ -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", @@ -81,7 +80,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 +3556,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 +3616,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 +13350,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 +21430,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 +21448,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 +21466,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 +21487,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 +28937,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..818677f65 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", @@ -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", @@ -109,7 +108,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/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/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 bd04122e6..e72c23776 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -1,87 +1,62 @@ -import * as Sentry from '@sentry/node' -import * as fs from 'fs' -import _get from 'lodash/get' -import * as path from 'path' +import { AsyncLocalStorage } from 'async_hooks' import { createLogger, format, transports } from 'winston' -import Transport from 'winston-transport' -import { isProd, isTest } from 'common/environment' +import { LOGGING_CONTEXT_KEY, LOGGING_LEVEL } from 'common/enums' +import { environment } from 'common/environment' +import type { ValueOf } from 'definitions' -const logPath = 'logs' +export type LoggingLevel = ValueOf +export type LoggingContextKey = ValueOf -// create logs dir if it does not exist -if (!fs.existsSync(logPath)) { - fs.mkdirSync(logPath) -} +export const contextStorage = new AsyncLocalStorage< + Map +>() -/** - * Custom winston transport for Sentry. - * - */ -class SentryTransport extends Transport { - constructor(opts?: Transport.TransportStreamOptions) { - super(opts) +const setContext = format((info, _) => { + const context = contextStorage.getStore() + if (context) { + info.requestId = context!.get('requestId') + // info.jobId = context!.get('jobId') } + return info +}) - 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() +const createWinstonLogger = (name: string, level: LoggingLevel) => + createLogger({ + level, + format: format.combine( + format.splat(), + format.errors({ stack: true }), + setContext(), + format.label({ label: name }), + format.timestamp({ + format: 'YYYY-MM-DD HH:mm:ss', + }), + format.printf( + (info) => + `${info.timestamp} ${info.requestId ?? '-'} ${info.label} [${ + info.level + }]: ${info.message} ${info.stack ?? ''}` + ) + ), + transports: [new transports.Console({ level })], + }) + +const loggers = new Map() + +export const getLogger = (name: string) => { + const logger = loggers.get(name) + if (logger) { + return logger } + const level = environment.debug.includes(name) + ? LOGGING_LEVEL.debug + : (environment.loggingLevel as LoggingLevel) + const newLogger = createWinstonLogger(name, level) + loggers.set(name, newLogger) + return newLogger } -/** - * Simple format outputs: - * - * 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' }), - ], -}) - -if (!isProd) { - logger.add( - new transports.Console({ - level: isTest ? 'warn' : 'info', - }) - ) -} +// print environment -export default logger +getLogger('env').debug('environment %s', environment) diff --git a/src/common/utils/exportSchema.ts b/src/common/utils/exportSchema.ts index b24fead41..baadc2449 100644 --- a/src/common/utils/exportSchema.ts +++ b/src/common/utils/exportSchema.ts @@ -3,9 +3,11 @@ 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('utils') + const schemaObj = makeExecutableSchema({ typeDefs, // resolverValidationOptions: { diff --git a/src/common/utils/generateTypes.ts b/src/common/utils/generateTypes.ts index a900c8bfd..e6cf10b68 100644 --- a/src/common/utils/generateTypes.ts +++ b/src/common/utils/generateTypes.ts @@ -2,7 +2,9 @@ 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('utils') const schema = fs.readFileSync('schema.graphql', { encoding: 'utf8' }) @@ -15,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/common/utils/getLanguage.ts b/src/common/utils/getLanguage.ts index f5326c6ac..050511d35 100644 --- a/src/common/utils/getLanguage.ts +++ b/src/common/utils/getLanguage.ts @@ -1,7 +1,9 @@ import _ from 'lodash' import { LANGUAGE } from 'common/enums' -import logger from 'common/logger' +import { getLogger } from 'common/logger' + +const logger = getLogger('utils-language') // map supported language to header language export const langMap = { @@ -44,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 61e486411..aac05e42e 100644 --- a/src/common/utils/getViewer.ts +++ b/src/common/utils/getViewer.ts @@ -11,11 +11,13 @@ 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('utils-auth') + export const roleAccess = [USER_ROLE.visitor, USER_ROLE.user, USER_ROLE.admin] export const authModes = [ AUTH_MODE.visitor, @@ -44,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 b8c744122..8e375a824 100644 --- a/src/common/utils/updateWordCount.ts +++ b/src/common/utils/updateWordCount.ts @@ -1,6 +1,5 @@ import 'module-alias/register' -import logger from 'common/logger' import { ArticleService, DraftService } from 'connectors' import { countWords } from './content' @@ -33,7 +32,7 @@ async function main() { }) ) - logger.info('done.') + console.info('done.') process.exit() } 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 5aae67337..8fcf6a222 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 @@ -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 ) @@ -977,8 +964,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/aws/index.ts b/src/connectors/aws/index.ts index 1d48e8f9d..332089f79 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 } } @@ -193,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, @@ -211,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, @@ -228,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), @@ -243,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/baseService.ts b/src/connectors/baseService.ts index cb4109fdf..7dc003277 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('service-base') + export class BaseService extends DataSource { aws: typeof aws cfsvc: typeof cfsvc @@ -157,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) { @@ -221,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) } @@ -284,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/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/exchangeRate/index.ts b/src/connectors/exchangeRate/index.ts index 2d04c0ae8..c59d43125 100644 --- a/src/connectors/exchangeRate/index.ts +++ b/src/connectors/exchangeRate/index.ts @@ -3,9 +3,11 @@ 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('service-exchange-rate') + // TYPES type TokenCurrency = 'LIKE' | 'USDT' diff --git a/src/connectors/gcp/index.ts b/src/connectors/gcp/index.ts index 469ef744a..ba842474d 100644 --- a/src/connectors/gcp/index.ts +++ b/src/connectors/gcp/index.ts @@ -4,7 +4,9 @@ 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('service-gcp') const { zh_hans, zh_hant, en } = LANGUAGE @@ -119,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 847e1e208..99f661e7b 100644 --- a/src/connectors/likecoin/index.ts +++ b/src/connectors/likecoin/index.ts @@ -11,10 +11,12 @@ 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('service-likecoin') + interface LikeData { likerId: string likerIp?: string @@ -153,6 +155,7 @@ export class LikeCoin { } } + logger.info('request %s with %s', endpoint, params) return axios({ url: endpoint, baseURL: likecoinApiURL, @@ -606,17 +609,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.warn('iscnPublish failed posted results:', res, 'with:', postData) } return data.iscnId diff --git a/src/connectors/medium/index.ts b/src/connectors/medium/index.ts index f2c15aa91..aa0693d14 100644 --- a/src/connectors/medium/index.ts +++ b/src/connectors/medium/index.ts @@ -8,12 +8,14 @@ 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('service-medium') + const throttle = pThrottle({ limit: 2, interval: 1000, // equals to 600/5min, don't use more than half of cloudflare 1,200/5min global API rate limit diff --git a/src/connectors/notificationService/index.ts b/src/connectors/notificationService/index.ts index 71a01ca18..09e6ae358 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, @@ -16,6 +16,8 @@ import { mail } from './mail' import { notice } from './notice' import trans from './translations' +const logger = getLogger('service-notification') + export class NotificationService extends BaseService { mail: typeof mail notice: typeof notice @@ -30,7 +32,7 @@ export class NotificationService extends BaseService { try { await this.__trigger(params) } catch (e) { - logger.error('[Notification:trigger]', e) + logger.error(e) } } @@ -199,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 } @@ -211,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/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..e65ddd27f 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 { @@ -19,6 +19,8 @@ import { User, } from 'definitions' +const logger = getLogger('service-oauth') + export class OAuthService extends BaseService { constructor() { super('oauth_client') diff --git a/src/connectors/opensea/index.ts b/src/connectors/opensea/index.ts index ad6eff267..d85c165c1 100644 --- a/src/connectors/opensea/index.ts +++ b/src/connectors/opensea/index.ts @@ -2,7 +2,9 @@ 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('service-opensea') export class OpenSeaService extends RESTDataSource { apiKey?: string | undefined @@ -52,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/paymentService.ts b/src/connectors/paymentService.ts index 4f94b2579..fc251f15f 100644 --- a/src/connectors/paymentService.ts +++ b/src/connectors/paymentService.ts @@ -19,13 +19,15 @@ 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('service-payment') + export class PaymentService extends BaseService { stripe: typeof stripe 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/appreciation.ts b/src/connectors/queue/appreciation.ts index da8126ad1..40faf3295 100644 --- a/src/connectors/queue/appreciation.ts +++ b/src/connectors/queue/appreciation.ts @@ -17,11 +17,13 @@ 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('queue-appreciation') + interface AppreciationParams { amount: number articleId: string diff --git a/src/connectors/queue/asset.ts b/src/connectors/queue/asset.ts index dada7574a..1ed506e12 100644 --- a/src/connectors/queue/asset.ts +++ b/src/connectors/queue/asset.ts @@ -2,10 +2,12 @@ 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' import { BaseQueue } from './baseQueue' +const logger = getLogger('queue-asset') + interface AssetParams { ids: string[] } @@ -77,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/baseQueue.ts b/src/connectors/queue/baseQueue.ts index 95931c172..d0b004d48 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, @@ -16,6 +16,8 @@ import { knex } from 'connectors/db' import { createQueue, CustomQueueOpts } from './utils' +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 0475985e4..d3ae70b8f 100644 --- a/src/connectors/queue/ipfs.ts +++ b/src/connectors/queue/ipfs.ts @@ -10,13 +10,15 @@ 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('queue-ipfs') + class IPFSQueue extends BaseQueue { slackService: InstanceType ipfs: typeof ipfsServers diff --git a/src/connectors/queue/migration.ts b/src/connectors/queue/migration.ts index 90ec7c78d..8fd58bf6f 100644 --- a/src/connectors/queue/migration.ts +++ b/src/connectors/queue/migration.ts @@ -15,7 +15,9 @@ import { QUEUE_PRIORITY, } from 'common/enums' import { isTest } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' + +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 e1071932e..9da1c438b 100644 --- a/src/connectors/queue/payTo/matters.ts +++ b/src/connectors/queue/payTo/matters.ts @@ -11,11 +11,13 @@ 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('queue-payto-by-matters') + interface PaymentParams { txId: string } diff --git a/src/connectors/queue/payout.ts b/src/connectors/queue/payout.ts index e80166c5e..503041104 100644 --- a/src/connectors/queue/payout.ts +++ b/src/connectors/queue/payout.ts @@ -9,13 +9,15 @@ 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('queue-payout') + interface PaymentParams { txId: string } diff --git a/src/connectors/queue/publication.ts b/src/connectors/queue/publication.ts index e776371a8..5bb694282 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, @@ -28,6 +28,8 @@ import { import { BaseQueue } from './baseQueue' +const logger = getLogger('queue-publication') + export class PublicationQueue extends BaseQueue { constructor() { super(QUEUE_NAME.publication) @@ -135,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, { @@ -217,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 @@ -321,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, @@ -343,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 @@ -368,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/queue/user.ts b/src/connectors/queue/user.ts index 79d5b2d2d..8d141713a 100644 --- a/src/connectors/queue/user.ts +++ b/src/connectors/queue/user.ts @@ -9,11 +9,13 @@ 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('queue-user') + interface ArchiveUserData { userId: string } diff --git a/src/connectors/queue/utils.ts b/src/connectors/queue/utils.ts index 8facff410..49dd0dfce 100644 --- a/src/connectors/queue/utils.ts +++ b/src/connectors/queue/utils.ts @@ -3,7 +3,9 @@ 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('queue-base') export interface CustomQueueOpts { limiter?: RateLimiter @@ -33,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.info(`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.info('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', () => { @@ -97,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 1d6840e52..5ddc9d46f 100644 --- a/src/connectors/slack/index.ts +++ b/src/connectors/slack/index.ts @@ -2,7 +2,9 @@ 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('service-slack') class SlackService { client: WebClient diff --git a/src/connectors/stripe/index.ts b/src/connectors/stripe/index.ts index 14ac6f9c9..f6363eeb9 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, @@ -19,6 +19,8 @@ import { import SlackService from 'connectors/slack' import { User } from 'definitions' +const logger = getLogger('service-stripe') + /** * Interact with Stripe * @@ -70,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, @@ -87,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: { @@ -123,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, @@ -149,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, @@ -176,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', @@ -223,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 }), @@ -239,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, @@ -250,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) { @@ -268,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, @@ -290,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 @@ -306,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) { @@ -320,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, @@ -333,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', diff --git a/src/connectors/systemService.ts b/src/connectors/systemService.ts index 67dfbbeb9..bebb55470 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('service-system') + 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..04487a0eb 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,10 +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' -const debugLog = createDebug('tag-service') +const logger = getLogger('service-tag') export class TagService extends BaseService { constructor() { @@ -512,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 @@ -591,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) } @@ -1067,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/connectors/userService.ts b/src/connectors/userService.ts index ab1b9de37..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' @@ -36,7 +35,7 @@ import { PasswordNotAvailableError, UserInputError, } from 'common/errors' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { generatePasswordhash, isValidUserName, @@ -65,7 +64,7 @@ import { import { likecoin } from './likecoin' import { medium } from './medium' -const debugLog = createDebug('user-service') +const logger = getLogger('service-user') // const SEARCH_DEFAULT_TEXT_RANK_THRESHOLD = 0.0001 @@ -591,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) } 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 930a928f2..713952199 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 { CORS_OPTIONS, IMG_CACHE_PATH, LOGGING_CONTEXT_KEY } from 'common/enums' import { environment } from 'common/environment' +import { contextStorage, LoggingContextKey } 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(LOGGING_CONTEXT_KEY.requestId, traceId ?? v4()) + contextStorage.enterWith(context) + next() + }) app.use(helmet({ contentSecurityPolicy: false }) as RequestHandler) app.use(requestIp.mw()) app.use(cors(CORS_OPTIONS)) diff --git a/src/middlewares/logger.ts b/src/middlewares/logger.ts new file mode 100644 index 000000000..40eecf272 --- /dev/null +++ b/src/middlewares/logger.ts @@ -0,0 +1,25 @@ +import { getLogger } from 'common/logger' + +const logger = getLogger('middleware-logger') + +export const loggerMiddleware = async ( + resolve: any, + root: { [key: string]: any }, + args: any, + context: any, + info: any +) => { + try { + const result = await resolve(root, args, context, info) + return result + } catch (error) { + if (error.extensions) { + // expected errors + logger.warn(error.name) + } else { + // unexpected errors + logger.error(error) + } + throw error + } +} diff --git a/src/middlewares/sentry.ts b/src/middlewares/sentry.ts deleted file mode 100644 index 43fc1c7a8..000000000 --- a/src/middlewares/sentry.ts +++ /dev/null @@ -1,18 +0,0 @@ -import logger from 'common/logger' - -export const sentryMiddleware = async ( - resolve: any, - root: { [key: string]: any }, - args: any, - context: any, - info: any -) => { - try { - 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/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/article/readArticle.ts b/src/mutations/article/readArticle.ts index 565f124df..27bf72aca 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-read-article') + 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..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' @@ -7,12 +6,14 @@ 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('mutation-put-oauth-client') + const resolver: MutationToPutOAuthClientResolver = async ( - root, + _, { input: { id, 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/sendVerificationCode.ts b/src/mutations/user/sendVerificationCode.ts index adad73eb0..748a7dc2f 100644 --- a/src/mutations/user/sendVerificationCode.ts +++ b/src/mutations/user/sendVerificationCode.ts @@ -8,20 +8,20 @@ import { AuthenticationError, EmailExistsError, EmailNotFoundError, - // 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('mutation-send-verificaiton-code') + const resolver: MutationToSendVerificationCodeResolver = async ( _, - { input: { email: rawEmail, type, token, redirectUrl } }, + { input: { email: rawEmail, type, redirectUrl } }, { viewer, dataSources: { @@ -49,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 8c6321876..7810344fb 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, @@ -28,6 +28,8 @@ import { MutationToUpdateUserInfoResolver, } from 'definitions' +const logger = getLogger('mutation-update-user-info') + const resolver: MutationToUpdateUserInfoResolver = async ( _, { input }, @@ -70,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/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/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/queries/article/canSuperLike.ts b/src/queries/article/canSuperLike.ts index d6247ef56..e5d31357d 100644 --- a/src/queries/article/canSuperLike.ts +++ b/src/queries/article/canSuperLike.ts @@ -1,7 +1,9 @@ import { environment } from 'common/environment' -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { ArticleToCanSuperLikeResolver } from 'definitions' +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 dbecedf6e..d7b50dbb2 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' @@ -72,6 +72,8 @@ import userArticles from './user/articles' // import userTags from './user/tags' import userTopics from './user/topics' +const logger = getLogger('query-article') + export default { Query: { article: rootArticle, diff --git a/src/queries/article/translation.ts b/src/queries/article/translation.ts index 95277d963..d7f626157 100644 --- a/src/queries/article/translation.ts +++ b/src/queries/article/translation.ts @@ -2,10 +2,12 @@ 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('query-translations') + const resolver: ArticleToTranslationResolver = async ( { content: originContent, diff --git a/src/queries/user/appreciation.ts b/src/queries/user/appreciation.ts index 1ac5ee501..ab8c12d8b 100644 --- a/src/queries/user/appreciation.ts +++ b/src/queries/user/appreciation.ts @@ -2,10 +2,12 @@ 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('query-appreciation') + const trans = { appreciateSubsidy: i18n({ zh_hant: '平台補貼', 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 9704808aa..f849b16cd 100644 --- a/src/queries/user/liker/rateUSD.ts +++ b/src/queries/user/liker/rateUSD.ts @@ -1,10 +1,10 @@ -import _ from 'lodash' - -import logger from 'common/logger' +import { getLogger } from 'common/logger' import { LikerToRateUSDResolver } from 'definitions' +const logger = getLogger('query-rate-usd') + const resolver: LikerToRateUSDResolver = async ( - { id }, + _, __: any, { dataSources: { userService } } ) => { diff --git a/src/routes/graphql.ts b/src/routes/graphql.ts index 1cbbaff8b..1c7b9e2b6 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, @@ -40,10 +40,12 @@ import { TagService, UserService, } from 'connectors' -import { sentryMiddleware } from 'middlewares/sentry' +import { loggerMiddleware } from 'middlewares/logger' import schema from '../schema' +const logger = getLogger('graphql-cost-analysis') + const API_ENDPOINT = '/graphql' const PLAYGROUND_ENDPOINT = '/playground' @@ -74,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), }), ], } @@ -88,7 +88,7 @@ const cache = new RedisCache({ port: environment.cachePort, }) -const composedSchema = applyMiddleware(schema, sentryMiddleware) +const composedSchema = applyMiddleware(schema, loggerMiddleware) const exceptVariableNames = [ 'email', 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/routes/oauth/index.ts b/src/routes/oauth/index.ts index 7ca1a8950..43e670a60 100644 --- a/src/routes/oauth/index.ts +++ b/src/routes/oauth/index.ts @@ -9,13 +9,15 @@ 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('route-oauth') + const oAuthRouter = Router() const oAuthService = new OAuthService() const oAuthServer = new OAuthServer({ diff --git a/src/routes/oauth/strategies.ts b/src/routes/oauth/strategies.ts index 7d6cc2d43..f5e84054c 100644 --- a/src/routes/oauth/strategies.ts +++ b/src/routes/oauth/strategies.ts @@ -1,13 +1,15 @@ 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 logger from 'common/logger' +import { getLogger } from 'common/logger' import { CacheService, UserService } from 'connectors' +const logger = getLogger('route-auth') + export default () => { passport.use( new LikeCoinStrategy( @@ -19,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 f7b6bf773..0302db47f 100644 --- a/src/routes/pay/likecoin.ts +++ b/src/routes/pay/likecoin.ts @@ -12,7 +12,7 @@ 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, @@ -20,6 +20,8 @@ import { UserService, } from 'connectors' +const logger = getLogger('route-likecoin') + const likecoinRouter = Router() const invalidateCache = async ({ diff --git a/src/routes/pay/stripe/circle.ts b/src/routes/pay/stripe/circle.ts index 490d11754..0e83646b4 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, @@ -26,6 +26,8 @@ import { import SlackService from 'connectors/slack' import { CirclePrice, CircleSubscription, Customer } from 'definitions' +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 1bf4c6c12..64a67b89a 100644 --- a/src/routes/pay/stripe/connect/index.ts +++ b/src/routes/pay/stripe/connect/index.ts @@ -3,11 +3,13 @@ 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('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 ac75e6c0f..3c568aaa8 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', }) 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,