56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
import * as winston from 'winston';
|
|
import {LeveledLogMethod} from 'winston';
|
|
import {RequestHandler} from 'express';
|
|
import * as colors from 'colors';
|
|
import {DefaultConfig} from '.';
|
|
import prune = require('json-prune');
|
|
|
|
|
|
const logger = winston.createLogger({
|
|
level: DefaultConfig.isProduction ? 'info' : 'silly',
|
|
format: winston.format.json(),
|
|
transports: [
|
|
new winston.transports.Console({
|
|
format: winston.format.simple(),
|
|
}),
|
|
],
|
|
});
|
|
|
|
export const levels = ['error', 'warn', 'info', 'http', 'verbose', 'debug', 'silly'] as const;
|
|
export type LogLevels = typeof levels[number]|'log';
|
|
const wrapper = (original: LeveledLogMethod) => {
|
|
return (...args: unknown[]) => {
|
|
return original(args.map((obj) => typeof obj === 'string' ? obj : prune(obj)).join(' '));
|
|
};
|
|
};
|
|
|
|
export const Logger = {
|
|
} as {[level in LogLevels]: ReturnType<typeof wrapper>};
|
|
|
|
for (const level of levels) {
|
|
Logger[level] = wrapper(logger[level]);
|
|
}
|
|
Logger.log = wrapper(logger['silly']);
|
|
|
|
export const HttpLogger: RequestHandler = (req, res, next) => {
|
|
const start = Date.now();
|
|
const path = req.path;
|
|
type Callback = (() => void)|undefined;
|
|
const end = res.end;
|
|
res.end = function(...args: [Callback] & [unknown, Callback] & [unknown, BufferEncoding, Callback]) {
|
|
const statusCode = res.statusCode;
|
|
const colorFunction = statusCode >= 500 ? colors.red
|
|
: statusCode >= 400 ? colors.yellow
|
|
: statusCode >= 300 ? colors.cyan
|
|
: statusCode >= 200 ? colors.green
|
|
: colors.gray;
|
|
const status = colorFunction(res.statusCode.toString(10));
|
|
const method = req.method.toUpperCase().padEnd(6, ' ');
|
|
const responseTime = (Date.now()-start).toString(10).padStart(3, ' ');
|
|
if (!req.noHttpLogging)
|
|
Logger.http(`${status} ${method} ${responseTime}ms ${path}`);
|
|
end.apply(res, args);
|
|
};
|
|
next();
|
|
};
|