add Sentry setup for logs tracking

Change-Id: Ie297275f7f16c954102355f56ff99ef843bff4c2
diff --git a/.gitignore b/.gitignore
index d1a74c5..486810e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,5 @@
 .idea/
 .vscode/
 *.iml
+
+sentry.config.json
diff --git a/app.js b/app.js
index da9e365..90d0c84 100644
--- a/app.js
+++ b/app.js
@@ -28,6 +28,7 @@
 
 import JamiRestApi from './routes/jami.js'
 import JamiDaemon from './JamiDaemon.js'
+import { sentrySetUp } from './sentry.js'
 
 const configPath = 'jamiServerConfig.json'
 
@@ -270,6 +271,8 @@
         }
     }
 
+    sentrySetUp(app);
+
     app.get('/auth', (req, res) => {
         const state = getState(req)
         if (req.user) {
@@ -293,6 +296,7 @@
         })
     })
 
+
     const server = http.Server(app)
 
     const io = new Server(server, { cors: corsOptions })
diff --git a/package-lock.json b/package-lock.json
index 8ac579e..e104254 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,8 @@
       "version": "1.0.0",
       "license": "ISC",
       "dependencies": {
+        "@sentry/node": "^7.11.1",
+        "@sentry/tracing": "^7.11.1",
         "body-parser": "^1.20.0",
         "connect-redis": "^6.1.3",
         "cookie-parser": "^1.4.6",
@@ -2663,6 +2665,85 @@
         }
       }
     },
+    "node_modules/@sentry/core": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.13.0.tgz",
+      "integrity": "sha512-hB46fklmKrSDMEvZOF8qBHhys7PONBFyxQtbNDZUlv/kabs4gF3VEg1ftCaXnjx4lLNlsUl/ScFdM6194RvISg==",
+      "dependencies": {
+        "@sentry/hub": "7.13.0",
+        "@sentry/types": "7.13.0",
+        "@sentry/utils": "7.13.0",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@sentry/hub": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-7.13.0.tgz",
+      "integrity": "sha512-88/GsD1BoyrBwRKJCmVHZtSH5rizOsImUHWEXc1AOa1aR8nanfn56JdAbd6tC55pA+nT4R4H4vN/PrUaomTbtg==",
+      "dependencies": {
+        "@sentry/types": "7.13.0",
+        "@sentry/utils": "7.13.0",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@sentry/node": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.13.0.tgz",
+      "integrity": "sha512-uP3bPAIRHPilnOEiYGQQDLaQphc/c7d87wm91bZrTJ+WPnMW4D/NmT7fna5zGGDQIr/KTdQ/LEpDeZOILbkCqQ==",
+      "dependencies": {
+        "@sentry/core": "7.13.0",
+        "@sentry/hub": "7.13.0",
+        "@sentry/types": "7.13.0",
+        "@sentry/utils": "7.13.0",
+        "cookie": "^0.4.1",
+        "https-proxy-agent": "^5.0.0",
+        "lru_map": "^0.3.3",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@sentry/tracing": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.13.0.tgz",
+      "integrity": "sha512-/MKSd25rGv6Pc0FPBLXJifkfvSaYVPA8XUOLzVeDN0gl07h8AXli4qG9amTh/4Wb5h4dFpbcscOvW2VC+pxkIA==",
+      "dependencies": {
+        "@sentry/hub": "7.13.0",
+        "@sentry/types": "7.13.0",
+        "@sentry/utils": "7.13.0",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@sentry/types": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.13.0.tgz",
+      "integrity": "sha512-ttckM1XaeyHRLMdr79wmGA5PFbTGx2jio9DCD/mkEpSfk6OGfqfC7gpwy7BNstDH/VKyQj/lDCJPnwvWqARMoQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@sentry/utils": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.13.0.tgz",
+      "integrity": "sha512-jnR85LgRLSk7IQe2OhKOPMY4fasJCNQNW0iCXsH+S2R1qnsF+N4ksNkQ+7JyyM9E7F03YpI2qd76bKY0VIn5iA==",
+      "dependencies": {
+        "@sentry/types": "7.13.0",
+        "tslib": "^1.9.3"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/@sinclair/typebox": {
       "version": "0.24.28",
       "dev": true,
@@ -3522,6 +3603,17 @@
         "acorn": "^8"
       }
     },
+    "node_modules/agent-base": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+      "dependencies": {
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6.0.0"
+      }
+    },
     "node_modules/ajv": {
       "version": "6.12.6",
       "dev": true,
@@ -5415,6 +5507,18 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/https-proxy-agent": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+      "dependencies": {
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/hyphenate-style-name": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
@@ -6371,6 +6475,11 @@
       "dev": true,
       "license": "0BSD"
     },
+    "node_modules/lru_map": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
+      "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ=="
+    },
     "node_modules/lru-cache": {
       "version": "6.0.0",
       "dev": true,
@@ -8269,6 +8378,11 @@
         "node": ">=8"
       }
     },
+    "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/type-fest": {
       "version": "0.21.3",
       "dev": true,
@@ -10240,6 +10354,67 @@
         "reselect": "^4.1.5"
       }
     },
+    "@sentry/core": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.13.0.tgz",
+      "integrity": "sha512-hB46fklmKrSDMEvZOF8qBHhys7PONBFyxQtbNDZUlv/kabs4gF3VEg1ftCaXnjx4lLNlsUl/ScFdM6194RvISg==",
+      "requires": {
+        "@sentry/hub": "7.13.0",
+        "@sentry/types": "7.13.0",
+        "@sentry/utils": "7.13.0",
+        "tslib": "^1.9.3"
+      }
+    },
+    "@sentry/hub": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-7.13.0.tgz",
+      "integrity": "sha512-88/GsD1BoyrBwRKJCmVHZtSH5rizOsImUHWEXc1AOa1aR8nanfn56JdAbd6tC55pA+nT4R4H4vN/PrUaomTbtg==",
+      "requires": {
+        "@sentry/types": "7.13.0",
+        "@sentry/utils": "7.13.0",
+        "tslib": "^1.9.3"
+      }
+    },
+    "@sentry/node": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.13.0.tgz",
+      "integrity": "sha512-uP3bPAIRHPilnOEiYGQQDLaQphc/c7d87wm91bZrTJ+WPnMW4D/NmT7fna5zGGDQIr/KTdQ/LEpDeZOILbkCqQ==",
+      "requires": {
+        "@sentry/core": "7.13.0",
+        "@sentry/hub": "7.13.0",
+        "@sentry/types": "7.13.0",
+        "@sentry/utils": "7.13.0",
+        "cookie": "^0.4.1",
+        "https-proxy-agent": "^5.0.0",
+        "lru_map": "^0.3.3",
+        "tslib": "^1.9.3"
+      }
+    },
+    "@sentry/tracing": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.13.0.tgz",
+      "integrity": "sha512-/MKSd25rGv6Pc0FPBLXJifkfvSaYVPA8XUOLzVeDN0gl07h8AXli4qG9amTh/4Wb5h4dFpbcscOvW2VC+pxkIA==",
+      "requires": {
+        "@sentry/hub": "7.13.0",
+        "@sentry/types": "7.13.0",
+        "@sentry/utils": "7.13.0",
+        "tslib": "^1.9.3"
+      }
+    },
+    "@sentry/types": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.13.0.tgz",
+      "integrity": "sha512-ttckM1XaeyHRLMdr79wmGA5PFbTGx2jio9DCD/mkEpSfk6OGfqfC7gpwy7BNstDH/VKyQj/lDCJPnwvWqARMoQ=="
+    },
+    "@sentry/utils": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.13.0.tgz",
+      "integrity": "sha512-jnR85LgRLSk7IQe2OhKOPMY4fasJCNQNW0iCXsH+S2R1qnsF+N4ksNkQ+7JyyM9E7F03YpI2qd76bKY0VIn5iA==",
+      "requires": {
+        "@sentry/types": "7.13.0",
+        "tslib": "^1.9.3"
+      }
+    },
     "@sinclair/typebox": {
       "version": "0.24.28",
       "dev": true
@@ -10800,6 +10975,14 @@
       "dev": true,
       "requires": {}
     },
+    "agent-base": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+      "requires": {
+        "debug": "4"
+      }
+    },
     "ajv": {
       "version": "6.12.6",
       "dev": true,
@@ -12004,6 +12187,15 @@
         "toidentifier": "1.0.1"
       }
     },
+    "https-proxy-agent": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+      "requires": {
+        "agent-base": "6",
+        "debug": "4"
+      }
+    },
     "hyphenate-style-name": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
@@ -12672,6 +12864,11 @@
         }
       }
     },
+    "lru_map": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
+      "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ=="
+    },
     "lru-cache": {
       "version": "6.0.0",
       "dev": true,
@@ -13833,6 +14030,11 @@
         }
       }
     },
+    "tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
     "type-fest": {
       "version": "0.21.3",
       "dev": true,
diff --git a/package.json b/package.json
index 6d4bd98..f5500ba 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,8 @@
   "description": "Jaas Web API that handles client requests to Jami daemon",
   "main": "index.js",
   "dependencies": {
+    "@sentry/node": "^7.11.1",
+    "@sentry/tracing": "^7.11.1",
     "body-parser": "^1.20.0",
     "connect-redis": "^6.1.3",
     "cookie-parser": "^1.4.6",
diff --git a/sentry.js b/sentry.js
new file mode 100644
index 0000000..2e67dd6
--- /dev/null
+++ b/sentry.js
@@ -0,0 +1,46 @@
+import * as Sentry from "@sentry/node";
+import * as Tracing from "@sentry/tracing";
+import config from "./sentry.config.json" assert { type: "json" };
+
+export function sentrySetUp(app) {
+  Sentry.init({
+    ...config,
+    integrations: [
+      // enable HTTP calls tracing
+      new Sentry.Integrations.Http({ tracing: true }),
+      // enable Express.js middleware tracing
+      new Tracing.Integrations.Express({ app }),
+    ],
+  });
+
+  // RequestHandler creates a separate execution context using domains, so that every
+  // transaction/span/breadcrumb is attached to its own Hub instance
+  app.use(Sentry.Handlers.requestHandler());
+  // TracingHandler creates a trace for every incoming request
+  app.use(Sentry.Handlers.tracingHandler());
+
+  app.get("/debug-sentry", function mainHandler(req, res) {
+    throw new Error("My first Sentry error!");
+  });
+
+  // The error handler must be before any other error middleware and after all controllers
+  // app.use(Sentry.Handlers.errorHandler());
+  app.use(
+    Sentry.Handlers.errorHandler({
+      shouldHandleError(error) {
+        // Capture all 404 and 500 errors
+        if (error.status === 404 || error.status === 500) {
+          return true;
+        }
+        return false;
+      },
+    })
+  );
+  // Optional fallthrough error handler
+  app.use(function onError(err, req, res, next) {
+    // The error id is attached to `res.sentry` to be returned
+    // and optionally displayed to the user for support.
+    res.statusCode = 500;
+    res.end(res.sentry + "\n");
+  });
+}