Adds sentry to the backend and removes the dump-generation e-mail

parent f31d7612
...@@ -44,6 +44,7 @@ build: ...@@ -44,6 +44,7 @@ build:
script: script:
- npm install - npm install
- export NODE_ENV='production' - export NODE_ENV='production'
- export SENTRY_DSN='https://c8d694a532814105b667236ffb2181e4@sentry.io/1833051'
- export ARSNOVA_CLICK_BACKEND_PORT_INTERNAL='3000' - export ARSNOVA_CLICK_BACKEND_PORT_INTERNAL='3000'
- export ARSNOVA_CLICK_BACKEND_ROUTE_PREFIX='/backend' - export ARSNOVA_CLICK_BACKEND_ROUTE_PREFIX='/backend'
- export LEADERBOARD_ALGORITHM='PointBased' - export LEADERBOARD_ALGORITHM='PointBased'
......
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
"dependency-check": "npx --ignore-existing madge --circular --extensions ts src" "dependency-check": "npx --ignore-existing madge --circular --extensions ts src"
}, },
"dependencies": { "dependencies": {
"@sentry/node": "^5.9.0",
"@typegoose/typegoose": "^6.1.0",
"amqplib": "^0.5.5",
"api-spec-converter": "^2.10.1", "api-spec-converter": "^2.10.1",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"bunyan": "^1.8.12", "bunyan": "^1.8.12",
...@@ -45,9 +48,7 @@ ...@@ -45,9 +48,7 @@
"routing-controllers-openapi": "^1.7.0", "routing-controllers-openapi": "^1.7.0",
"source-map-support": "^0.5.16", "source-map-support": "^0.5.16",
"swagger-ui-express": "^4.1.2", "swagger-ui-express": "^4.1.2",
"@typegoose/typegoose": "^6.1.0", "xml2js": "^0.4.22"
"xml2js": "^0.4.22",
"amqplib": "^0.5.5"
}, },
"devDependencies": { "devDependencies": {
"@types/amqplib": "^0.5.13", "@types/amqplib": "^0.5.13",
......
import { IGlobal } from '../main';
import LoggerService from '../services/LoggerService';
export function rejectionToCreateDump(reason): void {
try {
(<IGlobal>global).createDump(reason);
} catch (e) {
LoggerService.error('Cannot create dump', e.message);
} finally {
console.error(reason.stack || reason.message || reason);
}
}
declare function require(name: string): any; declare function require(name: string): any;
import * as child_process from 'child_process';
import * as http from 'http'; import * as http from 'http';
import { Server } from 'http'; import { Server } from 'http';
import * as Minimist from 'minimist'; import * as Minimist from 'minimist';
import * as path from 'path';
import * as process from 'process'; import * as process from 'process';
import 'reflect-metadata'; import 'reflect-metadata';
import App from './App'; import App from './App';
...@@ -16,8 +14,6 @@ import MathjaxDAO from './db/MathjaxDAO'; ...@@ -16,8 +14,6 @@ import MathjaxDAO from './db/MathjaxDAO';
import MemberDAO from './db/MemberDAO'; import MemberDAO from './db/MemberDAO';
import QuizDAO from './db/quiz/QuizDAO'; import QuizDAO from './db/quiz/QuizDAO';
import UserDAO from './db/UserDAO'; import UserDAO from './db/UserDAO';
import { jsonCensor } from './lib/jsonCensor';
import { rejectionToCreateDump } from './lib/rejectionToCreateDump';
import LoggerService from './services/LoggerService'; import LoggerService from './services/LoggerService';
import { staticStatistics } from './statistics'; import { staticStatistics } from './statistics';
import { LoadTester } from './tests/LoadTester'; import { LoadTester } from './tests/LoadTester';
...@@ -40,7 +36,6 @@ export interface IGlobal extends NodeJS.Global { ...@@ -40,7 +36,6 @@ export interface IGlobal extends NodeJS.Global {
DAO: { DAO: {
AssetDAO: {}, CasDAO: {}, I18nDAO: {}, MathjaxDAO: {}, QuizDAO: {}, DbDAO: {}, UserDAO: {}, MemberDAO: {}, AssetDAO: {}, CasDAO: {}, I18nDAO: {}, MathjaxDAO: {}, QuizDAO: {}, DbDAO: {}, UserDAO: {}, MemberDAO: {},
}; };
createDump: Function;
} }
interface IInetAddress { interface IInetAddress {
...@@ -49,10 +44,9 @@ interface IInetAddress { ...@@ -49,10 +44,9 @@ interface IInetAddress {
address: string; address: string;
} }
process.on('unhandledRejection', rejectionToCreateDump);
// process.on('uncaughtException', rejectionToCreateDump); // Throws exceptions when debugging with IntelliJ
if (process.env.NODE_ENV === 'production') { if (process.env.NODE_ENV === 'production') {
const Sentry = require('@sentry/node');
Sentry.init({ dsn: process.env.SENTRY_DSN });
} }
(<IGlobal>global).DAO = { (<IGlobal>global).DAO = {
...@@ -65,61 +59,6 @@ if (process.env.NODE_ENV === 'production') { ...@@ -65,61 +59,6 @@ if (process.env.NODE_ENV === 'production') {
UserDAO, UserDAO,
MemberDAO, MemberDAO,
}; };
(<IGlobal>global).createDump = (plainError) => {
const error = {
type: '',
code: '',
message: '',
stack: '',
};
if (plainError) {
if (typeof plainError === 'string') {
plainError = new Error(plainError);
}
error.type = plainError.constructor.name;
error.code = plainError.code;
error.message = plainError.message;
error.stack = plainError.stack;
}
const daoDump = { error };
Object.keys((<IGlobal>global).DAO).forEach((dao) => {
daoDump[dao] = (<IGlobal>global).DAO[dao].createDump();
});
const insecureDumpAsJson = JSON.stringify(daoDump, jsonCensor(daoDump));
const dumpCryptorParams: ReadonlyArray<string> = [
path.join(staticStatistics.pathToJobs, 'DumpCryptor.js'), `--base-path=${__dirname}`, '--command=encrypt', `--data=${insecureDumpAsJson}`,
];
const dumpCryptorInstance = child_process.spawn(`node`, dumpCryptorParams);
dumpCryptorInstance.stderr.on('data', (data) => {
LoggerService.error(`DumpCryptor (stderr): ${data.toString().replace('\n', '')}`);
});
dumpCryptorInstance.on('exit', () => {
LoggerService.error(`DumpCryptor (exit): Dump generated`);
});
const mailParams: ReadonlyArray<string> = [
path.join(staticStatistics.pathToJobs, 'SendMail.js'),
'--command=buildServerInfoMail',
`--attachment=${insecureDumpAsJson}`,
`--header=Arsnova.click Server Error Report (${error.type}: ${error.message})`,
`--text=${error.stack || JSON.stringify('unknown - no stack provided')}`,
];
const mailInstance = child_process.spawn(`node`, mailParams);
mailInstance.stderr.on('data', (data) => {
LoggerService.error(`SendMail (stderr): ${data.toString().replace('\n', '')}`);
});
mailInstance.stdout.on('data', (data) => {
LoggerService.error(`SendMail (stdout): ${data.toString().replace('\n', '')}`);
});
mailInstance.on('exit', () => {
LoggerService.error(`SendMail (exit): Done`);
});
};
const port: string | number | boolean = normalizePort(staticStatistics.port); const port: string | number | boolean = normalizePort(staticStatistics.port);
App.set('port', port); App.set('port', port);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment