@mgcrea/fastify-request-logger
Version:
Compact request logger plugin for fastify written in TypeScript
132 lines (129 loc) • 5.25 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
default: () => src_default
});
module.exports = __toCommonJS(src_exports);
var import_fastify_plugin = __toESM(require("fastify-plugin"), 1);
// src/plugin.ts
var color = __toESM(require("kolorist"), 1);
var IS_WINDOWS = process.platform === "win32";
var IS_POWERSHELL = IS_WINDOWS && Boolean(process.env["PSModulePath"] ?? process.env["PSHOME"]);
var plugin = async (fastify, options2 = {}) => {
const {
logBody = true,
logResponseTime = true,
logBindings = { plugin: "fastify-request-logger" },
ignoredPaths = [],
ignore,
ignoredBindings,
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
supportsArt = !IS_POWERSHELL && color.options.supportLevel >= 2
} = options2;
const icons = { req: supportsArt ? "\u2190" : "<", res: supportsArt ? "\u2192" : ">" };
const isIgnoredRequest = (request) => {
const { url } = request.routeOptions;
const isIgnoredPath = ignoredPaths.some((ignoredPath) => {
if (typeof ignoredPath === "string") {
return ignoredPath === url;
} else if (ignoredPath instanceof RegExp) {
return ignoredPath.test(url ?? "");
}
return false;
});
if (isIgnoredPath) {
return true;
}
return ignore ? ignore(request) : false;
};
fastify.addHook("onRequest", async (request) => {
if (isIgnoredRequest(request)) {
if (ignoredBindings) {
request.log.setBindings(ignoredBindings);
}
return;
}
const contentLength = request.headers["content-length"];
request.log.info(
logBindings,
`${color.bold(color.yellow(icons.req))}${color.yellow(request.method)}:${color.green(
request.url
)} request from ip ${color.blue(request.ip)}${contentLength ? ` with a ${color.yellow(contentLength)}-length body` : ""}`
);
request.log.trace({ ...logBindings, req: request }, `Request trace`);
});
fastify.addHook("preHandler", async (request) => {
if (isIgnoredRequest(request)) {
return;
}
const isJson = request.headers["content-type"]?.includes("application/json");
if (request.body && logBody) {
if (Buffer.isBuffer(request.body)) {
request.log.debug({ ...logBindings, body: `<Buffer ${request.body.length} bytes>` }, `Request body`);
} else if (isJson) {
request.log.debug({ ...logBindings, body: request.body }, `Request body`);
}
}
});
fastify.addHook("onResponse", async (request, reply) => {
if (isIgnoredRequest(request)) {
return;
}
const message = `${color.bold(color.yellow(icons.res))}${color.yellow(request.method)}:${color.green(
request.url
)} response with a ${color.magenta(reply.statusCode)}-status${logResponseTime ? ` took ${color.magenta(reply.elapsedTime.toFixed(3))}ms` : ""}`;
if (reply.statusCode && reply.statusCode >= 500) {
request.log.error(logBindings, message);
} else if (reply.statusCode && reply.statusCode >= 400) {
request.log.warn(logBindings, message);
} else {
request.log.info(logBindings, message);
}
});
fastify.addHook("onError", async (request, reply, error) => {
if (isIgnoredRequest(request)) {
return;
}
if (error.statusCode && error.statusCode >= 500) {
request.log.error({ ...logBindings, req: request, res: reply, err: error }, error?.message);
} else if (reply.statusCode && reply.statusCode >= 400) {
request.log.warn({ ...logBindings, res: reply, err: error }, error?.message);
} else {
request.log.info({ ...logBindings, res: reply, err: error }, error?.message);
}
});
};
// src/index.ts
var src_default = (0, import_fastify_plugin.default)(plugin, {
fastify: ">=4",
name: "fastify-request-logger"
});
//# sourceMappingURL=index.cjs.map