Use AsyncLocalStorage to provide requestId context
This commit is contained in:
parent
6f9ecaa9c4
commit
8fab93e709
@ -35,6 +35,7 @@
|
||||
"@types/jest": "^26.0.4",
|
||||
"@types/mjml": "^4.0.4",
|
||||
"@types/mysql": "^2.15.10",
|
||||
"@types/nanoid": "^2.1.0",
|
||||
"@types/node-fetch": "^2.5.7",
|
||||
"@types/nodemailer": "^6.4.0",
|
||||
"@types/nunjucks": "^3.1.3",
|
||||
@ -69,6 +70,7 @@
|
||||
"geoip-lite": "^1.4.2",
|
||||
"mjml": "^4.6.2",
|
||||
"mysql": "^2.18.1",
|
||||
"nanoid": "^3.1.20",
|
||||
"nodemailer": "^6.4.6",
|
||||
"nunjucks": "^3.2.1",
|
||||
"on-finished": "^2.3.0",
|
||||
|
@ -16,7 +16,7 @@ import * as path from "path";
|
||||
import CacheProvider from "./CacheProvider";
|
||||
import RedisComponent from "./components/RedisComponent";
|
||||
import Extendable from "./Extendable";
|
||||
import {log} from "./Logger";
|
||||
import {logger, loggingContextMiddleware} from "./Logger";
|
||||
import TemplateError = lib.TemplateError;
|
||||
|
||||
export default abstract class Application implements Extendable<ApplicationComponent | WebSocketListener<Application>> {
|
||||
@ -46,7 +46,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
||||
const path = thing.path();
|
||||
this.webSocketListeners[path] = thing;
|
||||
thing.init(this);
|
||||
log.info(`Added websocket listener on ${path}`);
|
||||
logger.info(`Added websocket listener on ${path}`);
|
||||
} else {
|
||||
thing.setApp(this);
|
||||
this.components.push(thing);
|
||||
@ -58,7 +58,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
||||
}
|
||||
|
||||
public async start(): Promise<void> {
|
||||
log.info(`${config.get('app.name')} v${this.version} - hi`);
|
||||
logger.info(`${config.get('app.name')} v${this.version} - hi`);
|
||||
process.once('SIGINT', () => {
|
||||
this.stop().catch(console.error);
|
||||
});
|
||||
@ -82,6 +82,11 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
||||
|
||||
// Init express
|
||||
const app = express();
|
||||
|
||||
// Logging context
|
||||
app.use(loggingContextMiddleware);
|
||||
|
||||
// Routers
|
||||
const initRouter = express.Router();
|
||||
const handleRouter = express.Router();
|
||||
app.use(initRouter);
|
||||
@ -191,7 +196,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
||||
for (let i = 2; i < args.length; i++) {
|
||||
switch (args[i]) {
|
||||
case '--verbose':
|
||||
log.setSettings({minLevel: "trace"});
|
||||
logger.setSettings({minLevel: "trace"});
|
||||
break;
|
||||
case '--full-http-requests':
|
||||
LogRequestsComponent.logFullHttpRequests();
|
||||
@ -200,7 +205,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
||||
await MysqlConnectionManager.migrationCommand(args.slice(i + 1));
|
||||
return true;
|
||||
default:
|
||||
log.warn('Unrecognized argument', args[i]);
|
||||
logger.warn('Unrecognized argument', args[i]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -228,13 +233,13 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
||||
}
|
||||
|
||||
public async stop(): Promise<void> {
|
||||
log.info('Stopping application...');
|
||||
logger.info('Stopping application...');
|
||||
|
||||
for (const component of this.components) {
|
||||
await component.stop?.();
|
||||
}
|
||||
|
||||
log.info(`${this.constructor.name} v${this.version} - bye`);
|
||||
logger.info(`${this.constructor.name} v${this.version} - bye`);
|
||||
}
|
||||
|
||||
private routes(initRouter: Router, handleRouter: Router) {
|
||||
@ -242,7 +247,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
||||
if (controller.hasGlobalMiddlewares()) {
|
||||
controller.setupGlobalHandlers(handleRouter);
|
||||
|
||||
log.info(`Registered global middlewares for controller ${controller.constructor.name}`);
|
||||
logger.info(`Registered global middlewares for controller ${controller.constructor.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,7 +256,7 @@ export default abstract class Application implements Extendable<ApplicationCompo
|
||||
initRouter.use(controller.getRoutesPrefix(), fileUploadFormRouter);
|
||||
handleRouter.use(controller.getRoutesPrefix(), mainRouter);
|
||||
|
||||
log.info(`> Registered routes for controller ${controller.constructor.name} at ${controller.getRoutesPrefix()}`);
|
||||
logger.info(`> Registered routes for controller ${controller.constructor.name} at ${controller.getRoutesPrefix()}`);
|
||||
}
|
||||
|
||||
handleRouter.use((req: Request) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Express, Router} from "express";
|
||||
import {log} from "./Logger";
|
||||
import {logger} from "./Logger";
|
||||
import {sleep} from "./Utils";
|
||||
import Application from "./Application";
|
||||
import config from "config";
|
||||
@ -28,11 +28,11 @@ export default abstract class ApplicationComponent {
|
||||
err = null;
|
||||
} catch (e) {
|
||||
err = e;
|
||||
log.error(err, `${name} failed to prepare; retrying in 5s...`);
|
||||
logger.error(err, `${name} failed to prepare; retrying in 5s...`);
|
||||
await sleep(5000);
|
||||
}
|
||||
} while (err);
|
||||
log.info(`${name} ready!`);
|
||||
logger.info(`${name} ready!`);
|
||||
}
|
||||
|
||||
protected async close(thingName: string, fn: (callback: (err?: Error | null) => void) => void): Promise<void> {
|
||||
@ -42,9 +42,9 @@ export default abstract class ApplicationComponent {
|
||||
else resolve();
|
||||
}));
|
||||
|
||||
log.info(`${thingName} closed.`);
|
||||
logger.info(`${thingName} closed.`);
|
||||
} catch (e) {
|
||||
log.error(e, `An error occurred while closing the ${thingName}.`);
|
||||
logger.error(e, `An error occurred while closing the ${thingName}.`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import express, {IRouter, RequestHandler, Router} from "express";
|
||||
import {PathParams} from "express-serve-static-core";
|
||||
import config from "config";
|
||||
import {log} from "./Logger";
|
||||
import {logger} from "./Logger";
|
||||
import FileUploadMiddleware from "./FileUploadMiddleware";
|
||||
import * as querystring from "querystring";
|
||||
import {ParsedUrlQueryInput} from "querystring";
|
||||
@ -75,7 +75,7 @@ export default abstract class Controller {
|
||||
|
||||
protected use(handler: RequestHandler): void {
|
||||
this.router.use(this.wrap(handler));
|
||||
log.info('Installed anonymous middleware on ' + this.getRoutesPrefix());
|
||||
logger.info('Installed anonymous middleware on ' + this.getRoutesPrefix());
|
||||
}
|
||||
|
||||
protected useMiddleware(...middlewares: MiddlewareType<Middleware>[]): void {
|
||||
@ -87,7 +87,7 @@ export default abstract class Controller {
|
||||
this.router.use(this.wrap(instance.getRequestHandler()));
|
||||
}
|
||||
|
||||
log.info('Installed ' + middleware.name + ' on ' + this.getRoutesPrefix());
|
||||
logger.info('Installed ' + middleware.name + ' on ' + this.getRoutesPrefix());
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,10 +176,10 @@ export default abstract class Controller {
|
||||
|
||||
if (!Controller.routes[routeName]) {
|
||||
if (typeof routePath === 'string') {
|
||||
log.info(`Route ${routeName} has path ${routePath}`);
|
||||
logger.info(`Route ${routeName} has path ${routePath}`);
|
||||
Controller.routes[routeName] = routePath;
|
||||
} else {
|
||||
log.warn(`Cannot assign path to route ${routeName}.`);
|
||||
logger.warn(`Cannot assign path to route ${routeName}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,18 @@
|
||||
import {v4 as uuid} from "uuid";
|
||||
import {Logger as TsLogger} from "tslog";
|
||||
import {AsyncLocalStorage} from "async_hooks";
|
||||
import {RequestHandler} from "express";
|
||||
import {nanoid} from "nanoid";
|
||||
|
||||
export const log = new TsLogger();
|
||||
const requestIdStorage: AsyncLocalStorage<string> = new AsyncLocalStorage();
|
||||
|
||||
export function makeUniqueLogger(): TsLogger {
|
||||
const id = uuid();
|
||||
return log.getChildLogger({
|
||||
requestId: id,
|
||||
export const logger = new TsLogger({
|
||||
requestId: (): string => {
|
||||
return requestIdStorage.getStore() as string;
|
||||
},
|
||||
});
|
||||
|
||||
export const loggingContextMiddleware: RequestHandler = (req, res, next) => {
|
||||
requestIdStorage.run(nanoid(8), () => {
|
||||
next();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -27,10 +27,10 @@ import CsrfProtectionComponent from "./components/CsrfProtectionComponent";
|
||||
import MailController from "./mail/MailController";
|
||||
import WebSocketServerComponent from "./components/WebSocketServerComponent";
|
||||
import Controller from "./Controller";
|
||||
import packageJson = require('../package.json');
|
||||
import AccountController from "./auth/AccountController";
|
||||
import MakeMagicLinksSessionNotUniqueMigration from "./auth/magic_link/MakeMagicLinksSessionNotUniqueMigration";
|
||||
import AddUsedToMagicLinksMigration from "./auth/magic_link/AddUsedToMagicLinksMigration";
|
||||
import packageJson = require('../package.json');
|
||||
|
||||
export const MIGRATIONS = [
|
||||
CreateMigrationsTable,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {TooManyRequestsHttpError} from "./HttpError";
|
||||
import {log} from "./Logger";
|
||||
import {logger} from "./Logger";
|
||||
|
||||
export default class Throttler {
|
||||
private static readonly throttles: Record<string, Throttle | undefined> = {};
|
||||
@ -81,7 +81,7 @@ class Throttle {
|
||||
trigger.jailed = currentDate;
|
||||
|
||||
const unjailedIn = trigger.jailed + this.jailPeriod - currentDate;
|
||||
log.info(`Jail ${this.jailName} triggered by ${id} and will be unjailed in ${unjailedIn}ms.`);
|
||||
logger.info(`Jail ${this.jailName} triggered by ${id} and will be unjailed in ${unjailedIn}ms.`);
|
||||
|
||||
return this.throw(unjailedIn);
|
||||
}
|
||||
|
13
src/Utils.ts
13
src/Utils.ts
@ -1,5 +1,3 @@
|
||||
import * as crypto from "crypto";
|
||||
|
||||
export async function sleep(ms: number): Promise<void> {
|
||||
return await new Promise(resolve => {
|
||||
setTimeout(() => resolve(), ms);
|
||||
@ -23,17 +21,6 @@ export abstract class WrappingError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
export function cryptoRandomDictionary(size: number, dictionary: string): string {
|
||||
const randomBytes = crypto.randomBytes(size);
|
||||
const output = new Array(size);
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
output[i] = dictionary[Math.floor(randomBytes[i] / 255 * dictionary.length)];
|
||||
}
|
||||
|
||||
return output.join('');
|
||||
}
|
||||
|
||||
export type Type<T> = { new(...args: never[]): T };
|
||||
|
||||
export function bufferToUuid(buffer: Buffer): string {
|
||||
|
@ -11,7 +11,7 @@ import UserEmail from "./models/UserEmail";
|
||||
import MagicLinkController from "./magic_link/MagicLinkController";
|
||||
import {MailTemplate} from "../mail/Mail";
|
||||
import {ADD_EMAIL_MAIL_TEMPLATE} from "../Mails";
|
||||
import {log} from "../Logger";
|
||||
import {logger} from "../Logger";
|
||||
import AuthMagicLinkActionType from "./magic_link/AuthMagicLinkActionType";
|
||||
|
||||
export default class AccountController extends Controller {
|
||||
@ -65,7 +65,7 @@ export default class AccountController extends Controller {
|
||||
|
||||
await passwordComponent.setPassword(req.body.new_password, 'new_password');
|
||||
await user.save();
|
||||
log.debug('user ' + user.id + ' changed their password and was saved.');
|
||||
logger.debug('user ' + user.id + ' changed their password and was saved.');
|
||||
|
||||
req.flash('success', 'Password changed successfully.');
|
||||
res.redirectBack(Controller.route('account'));
|
||||
|
@ -17,7 +17,7 @@ import AuthMagicLinkActionType from "./AuthMagicLinkActionType";
|
||||
import {QueryVariable} from "../../db/MysqlConnectionManager";
|
||||
import UserNameComponent from "../models/UserNameComponent";
|
||||
import MagicLinkUserNameComponent from "../models/MagicLinkUserNameComponent";
|
||||
import {log} from "../../Logger";
|
||||
import {logger} from "../../Logger";
|
||||
|
||||
export default class MagicLinkController<A extends Application> extends Controller {
|
||||
public static async sendMagicLink(
|
||||
@ -233,7 +233,7 @@ export default class MagicLinkController<A extends Application> extends Controll
|
||||
break;
|
||||
}
|
||||
default:
|
||||
log.warn('Unknown magic link action type ' + magicLink.action_type);
|
||||
logger.warn('Unknown magic link action type ' + magicLink.action_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ import config from "config";
|
||||
import * as child_process from "child_process";
|
||||
import ApplicationComponent from "../ApplicationComponent";
|
||||
import {ForbiddenHttpError} from "../HttpError";
|
||||
import {log} from "../Logger";
|
||||
import {logger} from "../Logger";
|
||||
|
||||
export default class AutoUpdateComponent extends ApplicationComponent {
|
||||
private static async runCommand(command: string): Promise<void> {
|
||||
log.info(`> ${command}`);
|
||||
log.info(child_process.execSync(command).toString());
|
||||
logger.info(`> ${command}`);
|
||||
logger.info(child_process.execSync(command).toString());
|
||||
}
|
||||
|
||||
public async checkSecuritySettings(): Promise<void> {
|
||||
@ -21,7 +21,7 @@ export default class AutoUpdateComponent extends ApplicationComponent {
|
||||
if (!token || token !== config.get<string>('gitlab_webhook_token'))
|
||||
throw new ForbiddenHttpError('Invalid token', req.url);
|
||||
|
||||
this.update(req.body).catch(req.log.error);
|
||||
this.update(req.body).catch(logger.error);
|
||||
|
||||
res.json({
|
||||
'status': 'ok',
|
||||
@ -30,10 +30,10 @@ export default class AutoUpdateComponent extends ApplicationComponent {
|
||||
}
|
||||
|
||||
private async update(params: { [p: string]: unknown }) {
|
||||
log.info('Update params:', params);
|
||||
logger.info('Update params:', params);
|
||||
|
||||
try {
|
||||
log.info('Starting auto update...');
|
||||
logger.info('Starting auto update...');
|
||||
|
||||
// Fetch
|
||||
await AutoUpdateComponent.runCommand(`git pull`);
|
||||
@ -47,9 +47,9 @@ export default class AutoUpdateComponent extends ApplicationComponent {
|
||||
// Stop app
|
||||
await this.getApp().stop();
|
||||
|
||||
log.info('Success!');
|
||||
logger.info('Success!');
|
||||
} catch (e) {
|
||||
log.error(e, 'An error occurred while running the auto update.');
|
||||
logger.error(e, 'An error occurred while running the auto update.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import ApplicationComponent from "../ApplicationComponent";
|
||||
import express, {Express, Router} from "express";
|
||||
import {log, makeUniqueLogger} from "../Logger";
|
||||
import {logger} from "../Logger";
|
||||
import {Server} from "http";
|
||||
import compression from "compression";
|
||||
import Middleware from "../Middleware";
|
||||
@ -20,7 +20,7 @@ export default class ExpressAppComponent extends ApplicationComponent {
|
||||
|
||||
public async start(app: Express): Promise<void> {
|
||||
this.server = app.listen(this.port, this.addr, () => {
|
||||
log.info(`Web server running on ${this.addr}:${this.port}.`);
|
||||
logger.info(`Web server running on ${this.addr}:${this.port}.`);
|
||||
});
|
||||
|
||||
// Proxy
|
||||
@ -41,7 +41,6 @@ export default class ExpressAppComponent extends ApplicationComponent {
|
||||
router.use(compression());
|
||||
|
||||
router.use((req, res, next) => {
|
||||
req.log = makeUniqueLogger();
|
||||
req.middlewares = [];
|
||||
req.as = <M extends Middleware>(type: Type<M>): M => {
|
||||
const middleware = req.middlewares.find(m => m.constructor === type);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import ApplicationComponent from "../ApplicationComponent";
|
||||
import onFinished from "on-finished";
|
||||
import {log} from "../Logger";
|
||||
import {logger} from "../Logger";
|
||||
import {Request, Response, Router} from "express";
|
||||
import {HttpError} from "../HttpError";
|
||||
|
||||
@ -9,7 +9,7 @@ export default class LogRequestsComponent extends ApplicationComponent {
|
||||
|
||||
public static logFullHttpRequests(): void {
|
||||
this.fullRequests = true;
|
||||
log.info('Http requests will be logged with more details.');
|
||||
logger.info('Http requests will be logged with more details.');
|
||||
}
|
||||
|
||||
public static logRequest(
|
||||
@ -38,12 +38,12 @@ export default class LogRequestsComponent extends ApplicationComponent {
|
||||
}, null, 4);
|
||||
if (err) {
|
||||
if (err instanceof Error) {
|
||||
return req.log.error(err, requestObj, err).requestId;
|
||||
return logger.error(err, requestObj, err).requestId;
|
||||
} else {
|
||||
return req.log.error(new Error(String(err)), requestObj).requestId;
|
||||
return logger.error(new Error(String(err)), requestObj).requestId;
|
||||
}
|
||||
} else {
|
||||
req.log.info(requestObj);
|
||||
logger.info(requestObj);
|
||||
}
|
||||
} else {
|
||||
let codeDescription = '';
|
||||
@ -59,15 +59,15 @@ export default class LogRequestsComponent extends ApplicationComponent {
|
||||
if (silent) {
|
||||
if (err instanceof HttpError) logStr += ` ${err.errorCode}`;
|
||||
logStr += ` ${err.name}`;
|
||||
return req.log.info(err.name, logStr).requestId;
|
||||
return logger.info(err.name, logStr).requestId;
|
||||
} else {
|
||||
return req.log.error(err, logStr, additionalStr, err).requestId;
|
||||
return logger.error(err, logStr, additionalStr, err).requestId;
|
||||
}
|
||||
} else {
|
||||
return req.log.error(new Error(String(err)), logStr).requestId;
|
||||
return logger.error(new Error(String(err)), logStr).requestId;
|
||||
}
|
||||
} else {
|
||||
req.log.info(logStr);
|
||||
logger.info(logStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ import {ParsedUrlQueryInput} from "querystring";
|
||||
import * as util from "util";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import {log} from "../Logger";
|
||||
import {logger} from "../Logger";
|
||||
import Middleware from "../Middleware";
|
||||
|
||||
export default class NunjucksComponent extends ApplicationComponent {
|
||||
@ -29,7 +29,7 @@ export default class NunjucksComponent extends ApplicationComponent {
|
||||
try {
|
||||
coreVersion = JSON.parse(fs.readFileSync(file).toString()).version;
|
||||
} catch (e) {
|
||||
log.warn('Couldn\'t determine coreVersion.', e);
|
||||
logger.warn('Couldn\'t determine coreVersion.', e);
|
||||
}
|
||||
|
||||
const opts = {
|
||||
|
@ -2,6 +2,7 @@ import ApplicationComponent from "../ApplicationComponent";
|
||||
import {Request, Router} from "express";
|
||||
import {ServerError} from "../HttpError";
|
||||
import onFinished from "on-finished";
|
||||
import {logger} from "../Logger";
|
||||
|
||||
export default class RedirectBackComponent extends ApplicationComponent {
|
||||
public static getPreviousURL(req: Request, defaultUrl?: string): string | undefined {
|
||||
@ -28,10 +29,10 @@ export default class RedirectBackComponent extends ApplicationComponent {
|
||||
contentType && typeof contentType !== 'number' && contentType.indexOf('text/html') >= 0
|
||||
)) {
|
||||
session.previousUrl = req.originalUrl;
|
||||
req.log.debug('Prev url set to', session.previousUrl);
|
||||
logger.debug('Prev url set to', session.previousUrl);
|
||||
session.save((err) => {
|
||||
if (err) {
|
||||
req.log.error(err, 'Error while saving session');
|
||||
logger.error(err, 'Error while saving session');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import ApplicationComponent from "../ApplicationComponent";
|
||||
import {Express} from "express";
|
||||
import redis, {RedisClient} from "redis";
|
||||
import config from "config";
|
||||
import {log} from "../Logger";
|
||||
import {logger} from "../Logger";
|
||||
import session, {Store} from "express-session";
|
||||
import connect_redis from "connect-redis";
|
||||
import CacheProvider from "../CacheProvider";
|
||||
@ -18,7 +18,7 @@ export default class RedisComponent extends ApplicationComponent implements Cach
|
||||
password: config.has('redis.password') ? config.get<string>('redis.password') : undefined,
|
||||
});
|
||||
this.redisClient.on('error', (err: Error) => {
|
||||
log.error(err, 'An error occurred with redis.');
|
||||
logger.error(err, 'An error occurred with redis.');
|
||||
});
|
||||
this.store = new RedisStore({
|
||||
client: this.redisClient,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import ApplicationComponent from "../ApplicationComponent";
|
||||
import {Express, Request} from "express";
|
||||
import WebSocket, {Server as WebSocketServer} from "ws";
|
||||
import {log} from "../Logger";
|
||||
import {logger} from "../Logger";
|
||||
import cookie from "cookie";
|
||||
import cookieParser from "cookie-parser";
|
||||
import config from "config";
|
||||
@ -28,9 +28,9 @@ export default class WebSocketServerComponent extends ApplicationComponent {
|
||||
this.wss = new WebSocketServer({
|
||||
server: this.expressAppComponent.getServer(),
|
||||
}, () => {
|
||||
log.info(`Websocket server started over webserver.`);
|
||||
logger.info(`Websocket server started over webserver.`);
|
||||
}).on('error', (err) => {
|
||||
log.error(err, 'An error occurred in the websocket server.');
|
||||
logger.error(err, 'An error occurred in the websocket server.');
|
||||
}).on('connection', (socket, request) => {
|
||||
const listener = request.url ? listeners[request.url] : null;
|
||||
|
||||
@ -39,12 +39,12 @@ export default class WebSocketServerComponent extends ApplicationComponent {
|
||||
return;
|
||||
} else if (!request.headers.cookie) {
|
||||
listener.handle(socket, request, null).catch(err => {
|
||||
log.error(err, 'Error in websocket listener.');
|
||||
logger.error(err, 'Error in websocket listener.');
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug(`Websocket on ${request.url}`);
|
||||
logger.debug(`Websocket on ${request.url}`);
|
||||
|
||||
const cookies = cookie.parse(request.headers.cookie);
|
||||
const sid = cookieParser.signedCookie(cookies['connect.sid'], config.get('session.secret'));
|
||||
@ -57,7 +57,7 @@ export default class WebSocketServerComponent extends ApplicationComponent {
|
||||
const store = this.storeComponent.getStore();
|
||||
store.get(sid, (err, session) => {
|
||||
if (err || !session) {
|
||||
log.error(err, 'Error while initializing session in websocket.');
|
||||
logger.error(err, 'Error while initializing session in websocket.');
|
||||
socket.close(1011);
|
||||
return;
|
||||
}
|
||||
@ -66,7 +66,7 @@ export default class WebSocketServerComponent extends ApplicationComponent {
|
||||
|
||||
store.createSession(<Request>request, session);
|
||||
listener.handle(socket, request, (<Request>request).session).catch(err => {
|
||||
log.error(err, 'Error in websocket listener.');
|
||||
logger.error(err, 'Error in websocket listener.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
import mysql, {Connection, FieldInfo, MysqlError, Pool, PoolConnection} from 'mysql';
|
||||
import config from 'config';
|
||||
import Migration, {MigrationType} from "./Migration";
|
||||
import {log} from "../Logger";
|
||||
import {logger} from "../Logger";
|
||||
import {Type} from "../Utils";
|
||||
|
||||
export interface QueryResult {
|
||||
@ -50,7 +50,7 @@ export default class MysqlConnectionManager {
|
||||
public static async prepare(runMigrations: boolean = true): Promise<void> {
|
||||
if (config.get('mysql.create_database_automatically') === true) {
|
||||
const dbName = config.get('mysql.database');
|
||||
log.info(`Creating database ${dbName}...`);
|
||||
logger.info(`Creating database ${dbName}...`);
|
||||
const connection = mysql.createConnection({
|
||||
host: config.get('mysql.host'),
|
||||
user: config.get('mysql.user'),
|
||||
@ -65,7 +65,7 @@ export default class MysqlConnectionManager {
|
||||
});
|
||||
});
|
||||
connection.end();
|
||||
log.info(`Database ${dbName} created!`);
|
||||
logger.info(`Database ${dbName} created!`);
|
||||
}
|
||||
this.databaseReady = true;
|
||||
|
||||
@ -97,7 +97,7 @@ export default class MysqlConnectionManager {
|
||||
}
|
||||
|
||||
this.currentPool.end(() => {
|
||||
log.info('Mysql connection pool ended.');
|
||||
logger.info('Mysql connection pool ended.');
|
||||
resolve();
|
||||
});
|
||||
this.currentPool = undefined;
|
||||
@ -110,7 +110,7 @@ export default class MysqlConnectionManager {
|
||||
connection?: Connection,
|
||||
): Promise<QueryResult> {
|
||||
return await new Promise<QueryResult>((resolve, reject) => {
|
||||
log.debug('SQL:', log.settings.minLevel === 'trace' || log.settings.minLevel === 'silly' ?
|
||||
logger.debug('SQL:', logger.settings.minLevel === 'trace' || logger.settings.minLevel === 'silly' ?
|
||||
mysql.format(queryString, values) :
|
||||
queryString);
|
||||
|
||||
@ -195,7 +195,7 @@ export default class MysqlConnectionManager {
|
||||
const currentVersion = await this.getCurrentMigrationVersion();
|
||||
for (const migration of this.migrations) {
|
||||
if (await migration.shouldRun(currentVersion)) {
|
||||
log.info('Running migration ', migration.version, migration.constructor.name);
|
||||
logger.info('Running migration ', migration.version, migration.constructor.name);
|
||||
await MysqlConnectionManager.wrapTransaction<void>(async c => {
|
||||
migration.setCurrentConnection(c);
|
||||
await migration.install();
|
||||
@ -219,7 +219,7 @@ export default class MysqlConnectionManager {
|
||||
public static async rollbackMigration(migrationId: number = 0): Promise<void> {
|
||||
migrationId--;
|
||||
const migration = this.migrations[migrationId];
|
||||
log.info('Rolling back migration ', migration.version, migration.constructor.name);
|
||||
logger.info('Rolling back migration ', migration.version, migration.constructor.name);
|
||||
await MysqlConnectionManager.wrapTransaction<void>(async c => {
|
||||
migration.setCurrentConnection(c);
|
||||
await migration.rollback();
|
||||
@ -230,7 +230,7 @@ export default class MysqlConnectionManager {
|
||||
|
||||
public static async migrationCommand(args: string[]): Promise<void> {
|
||||
try {
|
||||
log.info('Current migration:', await this.getCurrentMigrationVersion());
|
||||
logger.info('Current migration:', await this.getCurrentMigrationVersion());
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] === 'rollback') {
|
||||
|
@ -5,7 +5,7 @@ import {Environment} from 'nunjucks';
|
||||
import * as util from "util";
|
||||
import {WrappingError} from "../Utils";
|
||||
import mjml2html from "mjml";
|
||||
import {log} from "../Logger";
|
||||
import {logger} from "../Logger";
|
||||
import Controller from "../Controller";
|
||||
import {ParsedUrlQueryInput} from "querystring";
|
||||
|
||||
@ -38,7 +38,7 @@ export default class Mail {
|
||||
throw new MailError('Connection to mail service unsuccessful.', e);
|
||||
}
|
||||
|
||||
log.info(`Mail ready to be distributed via ${config.get('mail.host')}:${config.get('mail.port')}`);
|
||||
logger.info(`Mail ready to be distributed via ${config.get('mail.host')}:${config.get('mail.port')}`);
|
||||
}
|
||||
|
||||
public static end(): void {
|
||||
@ -110,7 +110,7 @@ export default class Mail {
|
||||
this.data.app = config.get('app');
|
||||
|
||||
// Log
|
||||
log.debug('Send mail', this.options);
|
||||
logger.debug('Send mail', this.options);
|
||||
|
||||
// Render email
|
||||
this.options.html = Mail.parse(this.environment, 'mails/' + this.template.template + '.mjml.njk',
|
||||
|
@ -6,15 +6,15 @@ process.env['NODE_CONFIG_DIR'] =
|
||||
+ delimiter
|
||||
+ (process.env['NODE_CONFIG_DIR'] || __dirname + '/../../config/');
|
||||
|
||||
import {log} from "./Logger";
|
||||
import {logger} from "./Logger";
|
||||
import TestApp from "./TestApp";
|
||||
import config from "config";
|
||||
|
||||
(async () => {
|
||||
log.debug('Config path:', process.env['NODE_CONFIG_DIR']);
|
||||
logger.debug('Config path:', process.env['NODE_CONFIG_DIR']);
|
||||
|
||||
const app = new TestApp(config.get<string>('listen_addr'), config.get<number>('port'));
|
||||
await app.start();
|
||||
})().catch(err => {
|
||||
log.error(err);
|
||||
logger.error(err);
|
||||
});
|
||||
|
4
src/types/Express.d.ts
vendored
4
src/types/Express.d.ts
vendored
@ -2,16 +2,12 @@ import {Files} from "formidable";
|
||||
import {Type} from "../Utils";
|
||||
import Middleware from "../Middleware";
|
||||
import {FlashMessages} from "../components/SessionComponent";
|
||||
import {Logger} from "tslog";
|
||||
import {Session, SessionData} from "express-session";
|
||||
import {PasswordAuthProofSessionData} from "../auth/password/PasswordAuthProof";
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
export interface Request {
|
||||
log: Logger;
|
||||
|
||||
|
||||
getSession(): Session & Partial<SessionData>;
|
||||
|
||||
getSessionOptional(): Session & Partial<SessionData> | undefined;
|
||||
|
@ -2,7 +2,7 @@ import MysqlConnectionManager from "../src/db/MysqlConnectionManager";
|
||||
import Model from "../src/db/Model";
|
||||
import ModelFactory from "../src/db/ModelFactory";
|
||||
import {ValidationBag} from "../src/db/Validator";
|
||||
import {log} from "../src/Logger";
|
||||
import {logger} from "../src/Logger";
|
||||
import {ManyThroughModelRelation, OneModelRelation} from "../src/db/ModelRelation";
|
||||
import {MIGRATIONS} from "../src/TestApp";
|
||||
import config from "config";
|
||||
@ -104,7 +104,7 @@ beforeAll(async () => {
|
||||
await MysqlConnectionManager.query('DROP DATABASE IF EXISTS ' + config.get<string>('mysql.database'));
|
||||
await MysqlConnectionManager.endPool();
|
||||
|
||||
log.setSettings({minLevel: "trace"});
|
||||
logger.setSettings({minLevel: "trace"});
|
||||
MysqlConnectionManager.registerMigrations(MIGRATIONS);
|
||||
ModelFactory.register(FakeDummyModel);
|
||||
ModelFactory.register(Post);
|
||||
|
12
yarn.lock
12
yarn.lock
@ -742,6 +742,13 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/nanoid@^2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/nanoid/-/nanoid-2.1.0.tgz#41edfda78986e9127d0dc14de982de766f994020"
|
||||
integrity sha512-xdkn/oRTA0GSNPLIKZgHWqDTWZsVrieKomxJBOQUK9YDD+zfSgmwD5t4WJYra5S7XyhTw7tfvwznW+pFexaepQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node-fetch@^2.5.7":
|
||||
version "2.5.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.8.tgz#e199c835d234c7eb0846f6618012e558544ee2fb"
|
||||
@ -4815,6 +4822,11 @@ mysql@^2.18.1:
|
||||
safe-buffer "5.1.2"
|
||||
sqlstring "2.3.1"
|
||||
|
||||
nanoid@^3.1.20:
|
||||
version "3.1.20"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788"
|
||||
integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
version "1.2.13"
|
||||
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
|
||||
|
Loading…
Reference in New Issue
Block a user