John Clark пре 5 година
родитељ
комит
b3b7a0273c
8 измењених фајлова са 204 додато и 59 уклоњено
  1. 15 0
      client/helpers/analytics.ts
  2. 5 1
      client/pages/_app.tsx
  3. 2 1
      next.config.js
  4. 160 45
      package-lock.json
  5. 3 1
      package.json
  6. 2 1
      server/env.ts
  7. 3 5
      server/handlers/helpers.ts
  8. 14 5
      server/server.ts

+ 15 - 0
client/helpers/analytics.ts

@@ -1,5 +1,7 @@
 import getConfig from "next/config";
 import ReactGA from "react-ga";
+import * as Sentry from '@sentry/react';
+import { Integrations } from '@sentry/apm';
 
 const { publicRuntimeConfig } = getConfig();
 
@@ -12,6 +14,19 @@ export const logPageView = () => {
   ReactGA.pageview(window.location.pathname);
 };
 
+export const initSentry = () => {
+  if (publicRuntimeConfig.SENTRY_PUBLIC_DSN) {
+    Sentry.init({
+      dsn: publicRuntimeConfig.SENTRY_PUBLIC_DSN,
+      environment: process.env.NODE_ENV,
+      integrations: [
+        new Integrations.Tracing(),
+      ],
+      tracesSampleRate: 1.0,
+    });
+  };
+};
+
 export const logEvent = (category = "", action = "") => {
   if (category && action) {
     ReactGA.event({ category, action });

+ 5 - 1
client/pages/_app.tsx

@@ -7,13 +7,17 @@ import cookie from "js-cookie";
 import Head from "next/head";
 import React from "react";
 
-import { initGA, logPageView } from "../helpers/analytics";
+import { initGA, logPageView , initSentry } from "../helpers/analytics";
 import { initializeStore } from "../store";
 import { TokenPayload } from "../types";
 
 const isProd = process.env.NODE_ENV === "production";
 const { publicRuntimeConfig } = getConfig();
 
+if (isProd) {
+  initSentry();
+};
+
 // TODO: types
 class MyApp extends App<any> {
   static async getInitialProps({ Component, ctx }: AppContext) {

+ 2 - 1
next.config.js

@@ -9,6 +9,7 @@ module.exports = {
     GOOGLE_ANALYTICS: localEnv && localEnv.GOOGLE_ANALYTICS,
     REPORT_EMAIL: localEnv && localEnv.REPORT_EMAIL,
     DISALLOW_ANONYMOUS_LINKS: localEnv && localEnv.DISALLOW_ANONYMOUS_LINKS,
-    DISALLOW_REGISTRATION: localEnv && localEnv.DISALLOW_REGISTRATION
+    DISALLOW_REGISTRATION: localEnv && localEnv.DISALLOW_REGISTRATION,
+    SENTRY_PUBLIC_DSN: localEnv && localEnv.SENTRY_PUBLIC_DSN,
   }
 };

+ 160 - 45
package-lock.json

@@ -3270,6 +3270,122 @@
       "resolved": "https://registry.npmjs.org/@next/react-refresh-utils/-/react-refresh-utils-9.4.4.tgz",
       "integrity": "sha512-9nKENeWRI6kQk44TbeqleIVtNLfcS3klVUepzl/ZCqzR5Bi06uqBCD277hdVvG/wL1pxA+R/pgJQLqnF5E2wPQ=="
     },
+    "@sentry/apm": {
+      "version": "5.21.1",
+      "resolved": "https://registry.npmjs.org/@sentry/apm/-/apm-5.21.1.tgz",
+      "integrity": "sha512-mxMOCpeXULbQCC/f9SwPqW+g12mk3nWRNjeAUm5dyiKHY13agtQBSSYs4ROEH190YxmwTZr3vxhlR2jNSdSZcg==",
+      "requires": {
+        "@sentry/browser": "5.21.1",
+        "@sentry/hub": "5.21.1",
+        "@sentry/minimal": "5.21.1",
+        "@sentry/types": "5.21.1",
+        "@sentry/utils": "5.21.1",
+        "tslib": "^1.9.3"
+      }
+    },
+    "@sentry/browser": {
+      "version": "5.21.1",
+      "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.21.1.tgz",
+      "integrity": "sha512-sUxsW545klZxJE4iBAYQ8SuVS85HTOGNmIIIZWFUogB5oW3O0L+nJluXEqf/pHU82LnjDIzqsWCYQ0cRUaeYow==",
+      "requires": {
+        "@sentry/core": "5.21.1",
+        "@sentry/types": "5.21.1",
+        "@sentry/utils": "5.21.1",
+        "tslib": "^1.9.3"
+      }
+    },
+    "@sentry/core": {
+      "version": "5.21.1",
+      "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.21.1.tgz",
+      "integrity": "sha512-Luulwx3GLUiY0gmHOhU+4eSga28Ce8DwoBcRq9GkGuhPu9r80057d5urxrDLp/leIZBXVvpY7tvmSN/rMtvF9w==",
+      "requires": {
+        "@sentry/hub": "5.21.1",
+        "@sentry/minimal": "5.21.1",
+        "@sentry/types": "5.21.1",
+        "@sentry/utils": "5.21.1",
+        "tslib": "^1.9.3"
+      }
+    },
+    "@sentry/hub": {
+      "version": "5.21.1",
+      "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.21.1.tgz",
+      "integrity": "sha512-x5i9Ggi5ZYMhBYL5kyTu2fUJ6owjKH2tgJL3UExoZdRyZkbLAFZb+DtfSnteWgQ6wriGfgPD3r/hAIEdaomk2A==",
+      "requires": {
+        "@sentry/types": "5.21.1",
+        "@sentry/utils": "5.21.1",
+        "tslib": "^1.9.3"
+      }
+    },
+    "@sentry/minimal": {
+      "version": "5.21.1",
+      "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.21.1.tgz",
+      "integrity": "sha512-OBVPASZ+mcXMKajvJon9RjEZ+ny3+VGhOI66acoP1hmYxKvji1OC2bYEuP1r4qtHxWVLAdV7qFj3EQ9ckErZmQ==",
+      "requires": {
+        "@sentry/hub": "5.21.1",
+        "@sentry/types": "5.21.1",
+        "tslib": "^1.9.3"
+      }
+    },
+    "@sentry/node": {
+      "version": "5.21.1",
+      "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.21.1.tgz",
+      "integrity": "sha512-+QLqGz6+/gtShv0F16nI2+AuVEDZG2k9L25BVCNoysYzH1J1/QIKHsl7YF2trDMlWM4T7cbu5Fh8AhK6an+5/g==",
+      "requires": {
+        "@sentry/apm": "5.21.1",
+        "@sentry/core": "5.21.1",
+        "@sentry/hub": "5.21.1",
+        "@sentry/types": "5.21.1",
+        "@sentry/utils": "5.21.1",
+        "cookie": "^0.4.1",
+        "https-proxy-agent": "^5.0.0",
+        "lru_map": "^0.3.3",
+        "tslib": "^1.9.3"
+      },
+      "dependencies": {
+        "cookie": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+          "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
+        }
+      }
+    },
+    "@sentry/react": {
+      "version": "5.21.1",
+      "resolved": "https://registry.npmjs.org/@sentry/react/-/react-5.21.1.tgz",
+      "integrity": "sha512-e60erzdQOwZ88+j6Hi1AnRlxex7ZmwQPGSoFjtihQJR3Xv9Esj5DBKVrWu6Z/QCDxTc8uaX08XjUyhse2YyutQ==",
+      "requires": {
+        "@sentry/browser": "5.21.1",
+        "@sentry/minimal": "5.21.1",
+        "@sentry/types": "5.21.1",
+        "@sentry/utils": "5.21.1",
+        "hoist-non-react-statics": "^3.3.2",
+        "tslib": "^1.9.3"
+      },
+      "dependencies": {
+        "hoist-non-react-statics": {
+          "version": "3.3.2",
+          "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+          "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+          "requires": {
+            "react-is": "^16.7.0"
+          }
+        }
+      }
+    },
+    "@sentry/types": {
+      "version": "5.21.1",
+      "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.21.1.tgz",
+      "integrity": "sha512-hFN4aDduMpjj6vZSIIp+9kSr8MglcKO/UmbuUXN6hKLewhxt+Zj2wjXN7ulSs5OK5mjXP9QLA5YJvVQsl2//qw=="
+    },
+    "@sentry/utils": {
+      "version": "5.21.1",
+      "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.21.1.tgz",
+      "integrity": "sha512-p5vPuc7+GfOmW8CXxWd0samS77Q00YrN8q5TC/ztF8nBhEF18GiMeWAdQnlSwt3iWal3q3gSSrbF4c9guIugng==",
+      "requires": {
+        "@sentry/types": "5.21.1",
+        "tslib": "^1.9.3"
+      }
+    },
     "@sinonjs/commons": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz",
@@ -4112,6 +4228,24 @@
         }
       }
     },
+    "agent-base": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz",
+      "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==",
+      "requires": {
+        "debug": "4"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        }
+      }
+    },
     "aggregate-error": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
@@ -6330,11 +6464,6 @@
       "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
       "dev": true
     },
-    "charenc": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
-      "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
-    },
     "check-error": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
@@ -7021,11 +7150,6 @@
         }
       }
     },
-    "crypt": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
-      "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
-    },
     "crypto-browserify": {
       "version": "3.12.0",
       "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
@@ -10301,6 +10425,25 @@
       "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
       "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
     },
+    "https-proxy-agent": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+      "requires": {
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        }
+      }
+    },
     "husky": {
       "version": "0.15.0-rc.13",
       "resolved": "https://registry.npmjs.org/husky/-/husky-0.15.0-rc.13.tgz",
@@ -11450,6 +11593,11 @@
         "yallist": "^3.0.2"
       }
     },
+    "lru_map": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
+      "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0="
+    },
     "lunr": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.8.tgz",
@@ -11531,16 +11679,6 @@
       "dev": true,
       "optional": true
     },
-    "md5": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
-      "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=",
-      "requires": {
-        "charenc": "~0.0.1",
-        "crypt": "~0.0.1",
-        "is-buffer": "~1.1.1"
-      }
-    },
     "md5.js": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -15276,25 +15414,6 @@
       "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
       "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
     },
-    "raven": {
-      "version": "2.6.4",
-      "resolved": "https://registry.npmjs.org/raven/-/raven-2.6.4.tgz",
-      "integrity": "sha512-6PQdfC4+DQSFncowthLf+B6Hr0JpPsFBgTVYTAOq7tCmx/kR4SXbeawtPch20+3QfUcQDoJBLjWW1ybvZ4kXTw==",
-      "requires": {
-        "cookie": "0.3.1",
-        "md5": "^2.2.1",
-        "stack-trace": "0.0.10",
-        "timed-out": "4.0.1",
-        "uuid": "3.3.2"
-      },
-      "dependencies": {
-        "uuid": {
-          "version": "3.3.2",
-          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
-          "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
-        }
-      }
-    },
     "raw-body": {
       "version": "2.4.0",
       "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
@@ -16696,11 +16815,6 @@
       "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
       "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w=="
     },
-    "stack-trace": {
-      "version": "0.0.10",
-      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
-      "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
-    },
     "stacktrace-parser": {
       "version": "0.1.10",
       "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz",
@@ -17445,7 +17559,8 @@
     "timed-out": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
-      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
+      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+      "dev": true
     },
     "timers-browserify": {
       "version": "2.0.11",

+ 3 - 1
package.json

@@ -35,6 +35,9 @@
   },
   "homepage": "https://github.com/TheDevs-Network/kutt#readme",
   "dependencies": {
+    "@sentry/apm": "^5.21.1",
+    "@sentry/node": "^5.21.1",
+    "@sentry/react": "^5.21.1",
     "axios": "^0.19.1",
     "babel-plugin-inline-react-svg": "^1.1.0",
     "bcryptjs": "^2.4.3",
@@ -74,7 +77,6 @@
     "prop-types": "^15.7.2",
     "qrcode.react": "^0.8.0",
     "query-string": "^6.10.1",
-    "raven": "^2.6.4",
     "react": "^16.12.0",
     "react-copy-to-clipboard": "^5.0.2",
     "react-dom": "^16.12.0",

+ 2 - 1
server/env.ts

@@ -40,7 +40,8 @@ const env = cleanEnv(process.env, {
   MAIL_PASSWORD: str(),
   REPORT_EMAIL: str({ default: "" }),
   CONTACT_EMAIL: str({ default: "" }),
-  RAVEN_DSN: str({ default: "" })
+  SENTRY_PRIVATE_DSN: str({ default: "" }),
+  SENTRY_PUBLIC_DSN: str({ default: "" })
 });
 
 export default env;

+ 3 - 5
server/handlers/helpers.ts

@@ -1,6 +1,6 @@
 import { Handler, ErrorRequestHandler } from "express";
 import { validationResult } from "express-validator";
-import Raven from "raven";
+import * as Sentry from "@sentry/node";
 import signale from "signale";
 
 import { CustomError } from "../utils";
@@ -21,10 +21,8 @@ export const error: ErrorRequestHandler = (error, req, res, next) => {
     return res.status(error.statusCode || 500).json({ error: error.message });
   }
 
-  if (env.RAVEN_DSN) {
-    Raven.captureException(error, {
-      user: { email: req.user && req.user.email }
-    });
+  if (env.SENTRY_PRIVATE_DSN) {
+    Sentry.captureException(error);
   }
 
   return res.status(500).json({ error: "An error occurred." });

+ 14 - 5
server/server.ts

@@ -7,7 +7,7 @@ import express from "express";
 import helmet from "helmet";
 import morgan from "morgan";
 import nextApp from "next";
-import Raven from "raven";
+import * as Sentry from "@sentry/node";
 
 import * as helpers from "./handlers/helpers";
 import * as links from "./handlers/links";
@@ -18,20 +18,29 @@ import routes from "./routes";
 import "./cron";
 import "./passport";
 
-if (env.RAVEN_DSN) {
-  Raven.config(env.RAVEN_DSN).install();
-}
-
 const port = env.PORT;
 const app = nextApp({ dir: "./client", dev: env.isDev });
 const handle = app.getRequestHandler();
 
 app.prepare().then(async () => {
   const server = express();
+
   server.set("trust proxy", true);
 
   if (env.isDev) {
     server.use(morgan("dev"));
+  } else if (env.SENTRY_PRIVATE_DSN) {
+    Sentry.init({
+      dsn: env.SENTRY_PRIVATE_DSN,
+      environment: process.env.NODE_ENV
+    });
+
+    server.use(
+      Sentry.Handlers.requestHandler({
+        ip: true,
+        user: ["id", "email"]
+      })
+    );
   }
 
   server.use(helmet());