diff --git a/README.md b/README.md index e73a888..3f10288 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ The template aims to be production ready with strict schemas & types, security m | Morgan | HTTP Request logger | | ESLint & Prettier | Enforce code style and formatting | | Redis | Redis backend for caching | +| Sentry | Monitoring | ## Features @@ -111,6 +112,10 @@ It sort of creates a schema which can be used in different files, with static ty For SQL queries, a basic middleware setup is present in `src/core/prisma/client.ts`. +### Monitoring + +The project contains a basic [Sentry](https://sentry.io/welcome/) setup for monitoring. You can add new integrations and change config based on your requirements. + ### Repositories (CRUD actions) and Types `src/repositories` contains all methods which carry out CRUD operations on db level. diff --git a/package.json b/package.json index 96ef924..e13aa9f 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ }, "dependencies": { "@prisma/client": "^5.3.1", + "@sentry/integrations": "^7.79.0", + "@sentry/node": "^7.79.0", "@types/bcryptjs": "^2.4.4", "@types/nodemailer": "^6.4.11", "bcryptjs": "^2.4.3", diff --git a/src/core/config.ts b/src/core/config.ts index 1fdc0dc..536e42e 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -15,6 +15,8 @@ const envVarsSchema = Joi.object() JWT_RESET_PASSWORD_EXPIRATION_MINUTES: Joi.number().required(), JWT_VERIFY_EMAIL_EXPIRATION_MINUTES: Joi.number().required(), SHOW_SQL_QUERIES: Joi.bool().default(false), + SENTRY_DSN: Joi.string().default(''), + SENTRY_ENVIRONMENT: Joi.string().default('development'), }) .unknown(); @@ -40,4 +42,8 @@ export default { resetPasswordExpirationMinutes: envVars.JWT_RESET_PASSWORD_EXPIRATION_MINUTES, verifyEmailExpirationMinutes: envVars.JWT_VERIFY_EMAIL_EXPIRATION_MINUTES, }, + sentry: { + dsn: envVars.SENTRY_DSN, + environment: envVars.SENTRY_ENVIRONMENT, + }, }; diff --git a/src/core/sentry.ts b/src/core/sentry.ts new file mode 100644 index 0000000..d5a9454 --- /dev/null +++ b/src/core/sentry.ts @@ -0,0 +1,23 @@ +import * as Sentry from '@sentry/node'; +import { RewriteFrames } from '@sentry/integrations'; +import config from './config'; + +Sentry.init({ + dsn: config.sentry.dsn, + environment: config.sentry.environment, + debug: true, + attachStacktrace: true, + normalizeDepth: 5, + includeLocalVariables: true, + integrations: [new RewriteFrames({ root: global.__dirname })], +}); + +export const captureMessage = (message: string, payload: object) => { + for (const entry in Object.entries(payload)) Sentry.setExtra(entry[0], entry[1]); + Sentry.captureMessage(message); +}; + +export const captureException = (exception: Error, payload: object) => { + for (const entry in Object.entries(payload)) Sentry.setExtra(entry[0], entry[1]); + Sentry.captureException(exception); +}; diff --git a/yarn.lock b/yarn.lock index 6d5d2fd..ba37717 100644 --- a/yarn.lock +++ b/yarn.lock @@ -843,6 +843,56 @@ resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.0.5.tgz#a6d70ef7a0e71e083ea09b967df0a0ed742bc6ad" integrity sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg== +"@sentry-internal/tracing@7.79.0": + version "7.79.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.79.0.tgz#db99820e93e15bf4d990f1b270a1d1c2a69fd564" + integrity sha512-Mf9Bd0OrZ24h1qZpvmz9IRnfORMGYNYC1xWBBFpIR1AauEDX89x+mJwIOrUc4KKAAAwt73shrJv1QA8QOm4E3g== + dependencies: + "@sentry/core" "7.79.0" + "@sentry/types" "7.79.0" + "@sentry/utils" "7.79.0" + +"@sentry/core@7.79.0": + version "7.79.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.79.0.tgz#08871bd686afd58125f43421d3dcb65a3b9208b0" + integrity sha512-9vG7SfOcJNJNiqlqg4MuHDUCaSf2ZXpv3eZYRPbBkgPGr8X1ekrSABpOK+6kBNvbtKxfWVTWbLpAA6xU+cwnVw== + dependencies: + "@sentry/types" "7.79.0" + "@sentry/utils" "7.79.0" + +"@sentry/integrations@^7.79.0": + version "7.79.0" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.79.0.tgz#8ee7df9e036a8b59a72aa5151f02cb62e2b593cc" + integrity sha512-BcD9KDgvFFoVkWGTZXu4jZ/zitXYJr39B0CQuJUfO/QquoKdAGvzcNXOKrq/sT9yMu1kl3e9MVqNxxrbXUkWWQ== + dependencies: + "@sentry/core" "7.79.0" + "@sentry/types" "7.79.0" + "@sentry/utils" "7.79.0" + localforage "^1.8.1" + +"@sentry/node@^7.79.0": + version "7.79.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.79.0.tgz#8921037fa5af805d35597d210725b730b31df33e" + integrity sha512-7kZpYG5hGyt3JhEfo9YtEhbUMwFOzNRQqL/weKgHSyFXU20VcScorceKG2Hynn0rhdAZR6GfdKHsM4kFQvgmtg== + dependencies: + "@sentry-internal/tracing" "7.79.0" + "@sentry/core" "7.79.0" + "@sentry/types" "7.79.0" + "@sentry/utils" "7.79.0" + https-proxy-agent "^5.0.0" + +"@sentry/types@7.79.0": + version "7.79.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.79.0.tgz#b47c53a3f8b9057aac820fe99e1154949aac934d" + integrity sha512-3tV32+v/DF8w7kD0p3kLWtgVTVdFL39oGY02+vz//rjWg/vzeqSE95mCYKm5pUfd6cPETX/8dunCiuTBQIkTHQ== + +"@sentry/utils@7.79.0": + version "7.79.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.79.0.tgz#c410b6c0e3032dbc9e708177555c70bdb8d1f63b" + integrity sha512-tUTlb6PvfZawqBmBK9CPXflqrZDXHKWoX3fve2zLK6W0FSpIMOO4TH8PBqkHBFs0ZgF/bnv/bsM4z7uEAlAtzg== + dependencies: + "@sentry/types" "7.79.0" + "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -1300,6 +1350,13 @@ acorn@^8.4.1, acorn@^8.9.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + agent-base@^7.0.2, agent-base@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" @@ -2852,6 +2909,14 @@ http-status@^1.7.0: resolved "https://registry.yarnpkg.com/http-status/-/http-status-1.7.0.tgz#df919bb5dcb879275e839ea0b2677664995d38c2" integrity sha512-6HZ8T2ywZKtNKOrRA22x4Z+fK+UiWzimWYSTROVHrZ46RX+hKsg9wCQiodRtfNrKfsvOkwsXA6R9q+TmDY+8nQ== +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + https-proxy-agent@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b" @@ -2892,6 +2957,11 @@ ignore@^5.2.0, ignore@^5.2.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -3608,6 +3678,13 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lie@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== + dependencies: + immediate "~3.0.5" + lilconfig@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" @@ -3646,6 +3723,13 @@ listr2@6.6.1: rfdc "^1.3.0" wrap-ansi "^8.1.0" +localforage@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" + integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== + dependencies: + lie "3.1.1" + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"