This commit is contained in:
2022-03-25 13:54:46 +01:00
6 changed files with 190 additions and 1903 deletions

View File

@ -100,12 +100,6 @@
"@typescript-eslint/no-require-imports":"error",
"@typescript-eslint/no-this-alias":"error",
"@typescript-eslint/no-throw-literal":"error",
"@typescript-eslint/no-type-alias":[
"error",
{
"allowAliases":"always"
}
],
"@typescript-eslint/no-unsafe-call":"error",
"@typescript-eslint/no-unsafe-member-access":"error",
"@typescript-eslint/no-unsafe-return":"error",
@ -159,8 +153,9 @@
}
],
"no-unused-vars":"off",
"unused-imports/no-unused-vars": "off",
"unused-imports/no-unused-imports":"error",
"unused-imports/no-unused-vars":[
"@typescript-eslint/no-unused-vars":[
"warn",
{
"vars":"all",

View File

@ -28,6 +28,7 @@
"args-command-parser": "^1.2.4",
"eslint-import-resolver-alias": "^1.1.2",
"fastify": "^3.25.3",
"fastify-plugin": "^3.0.0",
"fastify-sensible": "^3.1.2",
"winston": "^3.4.0"
},

View File

@ -0,0 +1,155 @@
/* eslint-disable @typescript-eslint/require-await */
import { FastifyLogFn, FastifyLoggerInstance, FastifyPluginAsync, FastifyRequest} from "fastify";
import fastifyPlugin from "fastify-plugin";
import { Bindings } from "fastify/types/logger";
import getlogger from "./logger";
import chalk from "chalk";
const logger = getlogger("fastify");
const customLogger: FastifyLoggerInstance = {
info: function (obj: unknown, msg?: string, ...args: unknown[]): void {
if(typeof obj === "string")
logger.info(obj, msg, ...args);
else if(msg)
logger.info(msg, obj, ...args);
} as FastifyLogFn,
warn: function (obj: unknown, msg?: string, ...args: unknown[]): void {
if(typeof obj === "string")
logger.warning(obj, msg, ...args);
else if(msg)
logger.warning(msg, obj, ...args);
} as FastifyLogFn,
error: function (obj: unknown, msg?: string, ...args: unknown[]): void {
if(typeof obj === "string")
logger.error(obj, msg, ...args);
else if(msg)
logger.error(msg, obj, ...args);
} as FastifyLogFn,
fatal: function (obj: unknown, msg?: string, ...args: unknown[]): void {
if(typeof obj === "string")
logger.fatal(obj, msg, ...args);
else if(msg)
logger.fatal(msg, obj, ...args);
} as FastifyLogFn,
trace: function (obj: unknown, msg?: string, ...args: unknown[]): void {
if(typeof obj === "string")
logger.trace(obj, msg, ...args);
else if(msg)
logger.trace(msg, obj, ...args);
} as FastifyLogFn,
debug: function (obj: unknown, msg?: string, ...args: unknown[]): void {
if(typeof obj === "string")
logger.debug(obj, msg, ...args);
else if(msg)
logger.debug(msg, obj, ...args);
} as FastifyLogFn,
child: function (_bindings: Bindings): FastifyLoggerInstance {
return customLogger;
},
setBindings: function (_bindings: Bindings): void {
// OK
}
};
export type FastifyRequestLoggerOptions = {
logBody?: boolean;
ignoredPaths?: Array<string>;
};
export const plugin: FastifyPluginAsync<FastifyRequestLoggerOptions> = async (fastify, options = {}): Promise<void> => {
const {
logBody = true,
ignoredPaths = [],
} = options;
const isIgnoredRequest = (request: FastifyRequest): boolean => {
const { routerPath } = request;
if (ignoredPaths.includes(routerPath)) {
return true;
}
return false;
};
fastify.addHook("onRequest", async (request) => {
if (isIgnoredRequest(request)) {
return;
}
const id = request.id;
const method = request.method;
const referrer = (request.headers["Referer"] ?? (request.headers["referer"]) ?? request.headers["Refferer"]) ?? request.headers["refferer"];
const remoteAddr = request.ip;
const remoteUser = "???";
const url = request.url;
const httpVersion = request.raw.httpVersion;
const userAgent = request.headers["User-Agents"];
const contentLength = request.headers["content-length"];
request.log.info(`${chalk.bold.yellow("→")} ${chalk.yellow(method)} ${chalk.green(url)} HTTP/${httpVersion} - ${chalk.blue(remoteAddr)} ${remoteUser} - ${referrer} - ${contentLength} bytes [${id}]`);
request.log.trace(`${chalk.bold.yellow("→")} ${chalk.yellow(method)} ${chalk.green(url)} ${userAgent} [${id}]`);
request.log.info(
`${chalk.bold.yellow("←")}${chalk.yellow(request.method)}:${chalk.green(
request.url
)} request from ip ${chalk.blue(request.ip)}${
contentLength ? ` with a ${chalk.yellow(contentLength)}-length body` : ""
}`
);
request.log.trace("Request trace %s", JSON.stringify({header: request.headers, body: request.body}));
});
fastify.addHook("preHandler", async (request) => {
if (isIgnoredRequest(request)) {
return;
}
const id = request.id;
const method = request.method;
// const referrer = (request.headers["Referer"] ?? (request.headers["referer"]) ?? request.headers["Refferer"]) ?? request.headers["refferer"];
const remoteAddr = request.ip;
const remoteUser = "???";
const url = request.url;
const httpVersion = request.raw.httpVersion;
const userAgent = request.headers["User-Agents"];
if (request.body && logBody) {
request.log.debug("Request body: %s", {body: request.body });
}
});
fastify.addHook("onResponse", async (request, reply) => {
if (isIgnoredRequest(request)) {
return;
}
const id = request.id;
const method = request.method;
const remoteAddr = request.ip;
const remoteUser = "???";
const responseTime = Math.ceil(reply.getResponseTime());
const status = reply.statusCode + "";
const url = request.url;
const httpVersion = request.raw.httpVersion;
const contentLength = reply.getHeaders()["content-length"] ?? -1;
const statusColor = function (status: string): string {
if(status.startsWith("2"))
return chalk.green(status);
if(status.startsWith("3"))
return chalk.blue(status);
if(status.startsWith("4"))
return chalk.yellow(status);
if(status.startsWith("5"))
return chalk.red(status);
return status;
};
request.log.info(`${chalk.bold.yellow("→")} ${chalk.yellow(method)} ${chalk.green(url)} ${statusColor(status)} HTTP/${httpVersion} - ${chalk.blue(remoteAddr)} ${remoteUser} - ${contentLength} bytes ${responseTime} ms [${id}]`);
});
};
declare module "fastify" {
interface FastifyLoggerInstance {
setBindings(bindings: Bindings): void;
}
}
export const fastifyRequestLogger = fastifyPlugin(plugin, {
fastify: "3.x",
name: "fastify-request-logger",
});
export const fastifyLogger = customLogger;

View File

@ -5,9 +5,32 @@ const { combine, timestamp, label, printf, errors, splat } = format;
// Custom logging format
const customFormat = printf(({ level, message, label, timestamp, stack }) => {
return `${timestamp} [${label || "-"}] ${level}: ${message} ${stack || ""}`;
return `${level}\t ${timestamp} · ${label || "-"}: ${message} ${stack || ""}`;
});
const myCustomLevels = {
levels: {
alert: 0,
fatal: 1,
error: 2,
warning: 3,
verbose: 4,
info: 5,
debug: 6,
trace: 7
},
colors: {
alert: "magentaBG white",
fatal: "redBG white",
error: "red",
warning: "yellow",
verbose: "green",
info: "blue",
debug: "cyan",
trace: "cyanBG black"
}
};
// Custom combined logging format:
const customCombinedFormat = (module: string): Format =>
combine(
@ -25,15 +48,19 @@ const customTransports = (): Transport[] => [new transports.Console()];
// Container to provide different pre-configured loggers
const logContainer = new winston.Container();
winston.addColors(myCustomLevels.colors);
// Default logger for modules:
const getLogger = (module: string): Logger => {
const getLogger = (module: string): Logger & Record<keyof typeof myCustomLevels["levels"], winston.LeveledLogMethod> => {
if (!logContainer.has(module)) {
logContainer.add(module, {
level: "trace",
levels: myCustomLevels.levels,
format: customCombinedFormat(module),
transports: customTransports()
});
}
return logContainer.get(module);
return logContainer.get(module) as Logger & Record<keyof typeof myCustomLevels["levels"], winston.LeveledLogMethod>;
};
export default getLogger;

View File

@ -9,7 +9,8 @@ console.log(configuration.getCommand());
serverLogger.warn("sss");
const fastify = Fastify({
logger: true
logger: fastifyLogger,
disableRequestLogging: true
});
await fastify.register(fastifySensible);

1892
yarn.lock

File diff suppressed because it is too large Load Diff