import { NextFunction, Request, Response } from "express"; import { Client } from "@elastic/elasticsearch"; import { AppDataSource } from "../database/data-source"; import { PosMaster } from "../entities/PosMaster"; if (!process.env.ELASTICSEARCH_INDEX) { throw new Error("Require ELASTICSEARCH_INDEX to store log."); } const ELASTICSEARCH_INDEX = process.env.ELASTICSEARCH_INDEX; const LOG_LEVEL_MAP: Record = { debug: 4, info: 3, warning: 2, error: 1, none: 0, }; const elasticsearch = new Client({ node: `${process.env.ELASTICSEARCH_PROTOCOL}://${process.env.ELASTICSEARCH_HOST}:${process.env.ELASTICSEARCH_PORT}`, }); async function logMiddleware(req: Request, res: Response, next: NextFunction) { if (!req.url.startsWith("/api/")) return next(); let data: any; const repoPosmaster = AppDataSource.getRepository(PosMaster); const originalJson = res.json; res.json = function (v: any) { data = v; return originalJson.call(this, v); }; const timestamp = new Date().toISOString(); const start = performance.now(); req.app.locals.logData = {}; const rootId = await repoPosmaster.findOne({ where: { current_holderId: req.app.locals.logData.userId }, }); res.on("finish", () => { if (!req.url.startsWith("/api/")) return; let system = "organization"; if (req.url.startsWith("/api/v1/org/metadata/")) system = "master"; if (req.url.startsWith("/api/v1/org/pos/position/")) system = "master"; if (req.url.startsWith("/api/v1/org/pos/type/")) system = "master"; if (req.url.startsWith("/api/v1/org/employee/pos/position/")) system = "master"; if (req.url.startsWith("api/v1/org/employee/pos/type/")) system = "master"; if (req.url.startsWith("/api/v1/org/auth/authRoleAttr/")) system = "admin"; if (req.url.startsWith("/api/v1/org/auth/authRole/")) system = "admin"; // if (req.url.startsWith("/api/v1/org/keycloak")) system = "admin"; if (req.url.startsWith("/api/v1/org/pos/admin/master/list")) system = "admin"; if (req.url.startsWith("/api/v1/org/super-admin/{id}")) system = "admin"; if (req.url.startsWith("/api/v1/org/permission-org/")) system = "admin"; if (req.url.startsWith("/api/v1/org/pos/assign/")) system = "admin"; if (req.url.startsWith("/api/v1/org/profile/")) system = "registry"; if (req.url.startsWith("/api/v1/org/profile-employee/")) system = "registry"; if (req.url.startsWith("/api/v1/org/profile-temp/")) system = "registry"; const level = LOG_LEVEL_MAP[process.env.LOG_LEVEL ?? "debug"] || 4; if (level === 1 && res.statusCode < 500) return; if (level === 2 && res.statusCode < 400) return; if (level === 3 && res.statusCode < 200) return; const obj = { logType: res.statusCode >= 500 ? "error" : res.statusCode >= 400 ? "warning" : "info", ip: req.ip, rootId: rootId?rootId.orgRootId:null, systemName: system, startTimeStamp: timestamp, endTimeStamp: new Date().toISOString(), processTime: performance.now() - start, host: req.hostname, method: req.method, endpoint: req.url, responseCode: String(res.statusCode === 304 ? 200 : res.statusCode), responseDescription: data?.message, input: (level === 4 && JSON.stringify(req.body, null, 2)) || undefined, output: (level === 4 && JSON.stringify(data, null, 2)) || undefined, ...req.app.locals.logData, }; elasticsearch.index({ index: ELASTICSEARCH_INDEX, document: obj, }); }); return next(); } export default logMiddleware;