82 lines
3.1 KiB
JavaScript
82 lines
3.1 KiB
JavaScript
|
import { cyan, red, magenta, bold } from 'colorette';
|
||
|
import statusEmoji from 'http-status-emojis';
|
||
|
import dayjs from 'dayjs';
|
||
|
import { METHODS } from 'node:http';
|
||
|
import { FileLogger } from './filelogger.js';
|
||
|
export var LogLevel;
|
||
|
(function (LogLevel) {
|
||
|
LogLevel["error"] = "error";
|
||
|
LogLevel["warn"] = "warn";
|
||
|
LogLevel["trace"] = "trace";
|
||
|
LogLevel["info"] = "info";
|
||
|
LogLevel["log"] = "log";
|
||
|
})(LogLevel || (LogLevel = {}));
|
||
|
const compileArgs = (args, req, res, options = {}, status, msg) => {
|
||
|
const { method } = req;
|
||
|
const { statusCode } = res;
|
||
|
const url = req.originalUrl || req.url;
|
||
|
const methods = options.methods ?? METHODS;
|
||
|
const timestamp = options.timestamp ?? false;
|
||
|
const emojiEnabled = options.emoji;
|
||
|
const level = options.output && options.output.level ? options.output.level : null;
|
||
|
if (level)
|
||
|
args.push('[' + level.toUpperCase() + ']');
|
||
|
if (methods.includes(method) && timestamp) {
|
||
|
args.push(`${dayjs()
|
||
|
.format(typeof timestamp !== 'boolean' && timestamp.format ? timestamp.format : 'HH:mm:ss')
|
||
|
.toString()} - `);
|
||
|
}
|
||
|
if (options.ip)
|
||
|
args.push(req.ip);
|
||
|
if (emojiEnabled)
|
||
|
args.push(statusEmoji[statusCode]);
|
||
|
args.push(method);
|
||
|
args.push(status || res.statusCode);
|
||
|
args.push(msg || res.statusMessage);
|
||
|
args.push(url);
|
||
|
};
|
||
|
export const logger = (options = {}) => {
|
||
|
const methods = options.methods ?? METHODS;
|
||
|
const output = options.output ?? { callback: console.log, color: true, level: null };
|
||
|
let filelogger = null;
|
||
|
if (options.output && options.output.filename) {
|
||
|
filelogger = new FileLogger(options.output.filename);
|
||
|
}
|
||
|
return (req, res, next) => {
|
||
|
res.on('finish', () => {
|
||
|
const args = [];
|
||
|
// every time
|
||
|
if (methods.includes(req.method)) {
|
||
|
const s = res.statusCode.toString();
|
||
|
let stringToLog = '';
|
||
|
if (!output.color) {
|
||
|
compileArgs(args, req, res, options);
|
||
|
const m = args.join(' ');
|
||
|
stringToLog = m;
|
||
|
}
|
||
|
else {
|
||
|
switch (s[0]) {
|
||
|
case '2':
|
||
|
compileArgs(args, req, res, options, cyan(bold(s)), cyan(res.statusMessage));
|
||
|
stringToLog = args.join(' ');
|
||
|
break;
|
||
|
case '4':
|
||
|
compileArgs(args, req, res, options, red(bold(s)), red(res.statusMessage));
|
||
|
stringToLog = args.join(' ');
|
||
|
break;
|
||
|
case '5':
|
||
|
compileArgs(args, req, res, options, magenta(bold(s)), magenta(res.statusMessage));
|
||
|
stringToLog = args.join(' ');
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
output.callback(stringToLog);
|
||
|
if (filelogger) {
|
||
|
filelogger.toFile(stringToLog);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
next?.();
|
||
|
};
|
||
|
};
|