当前位置: 首页 > news >正文

Nestjs使用log4j打印日志

众所周知,nest是自带日志的。但是好像没有log4j香,所以咱们来用log4j吧~

我只演示最简单的用法,用具体怎么样用大家可以自己进行封装。就像前端封装自己的请求一样。

一、安装

yarn add log4js stacktrace-js

二、使用

主要就三个文件:配置log4j文件、中间件文件、main.ts

配置log4j文件:src/utils/log4j.ts

import * as Path from 'path';
import * as Log4js from 'log4js';
import * as Util from 'util';
import * as Moment from 'moment'; // 处理时间的工具
import * as StackTrace from 'stacktrace-js';
import Chalk from 'chalk';
import config from '../config/log4js';// 日志级别
export enum LoggerLevel {ALL = 'ALL',MARK = 'MARK',TRACE = 'TRACE',DEBUG = 'DEBUG',INFO = 'INFO',WARN = 'WARN',ERROR = 'ERROR',FATAL = 'FATAL',OFF = 'OFF',
}// 内容跟踪类
export class ContextTrace {constructor(public readonly context: string,public readonly path?: string,public readonly lineNumber?: number,public readonly columnNumber?: number,) {}
}Log4js.addLayout('Awesome-nest', (logConfig: any) => {return (logEvent: Log4js.LoggingEvent): string => {let moduleName = '';let position = '';// 日志组装const messageList: string[] = [];logEvent.data.forEach((value: any) => {if (value instanceof ContextTrace) {moduleName = value.context;// 显示触发日志的坐标(行,列)if (value.lineNumber && value.columnNumber) {position = `${value.lineNumber}, ${value.columnNumber}`;}return;}if (typeof value !== 'string') {value = Util.inspect(value, false, 3, true);}messageList.push(value);});// 日志组成部分const messageOutput: string = messageList.join(' ');const positionOutput: string = position ? ` [${position}]` : '';const typeOutput = `[${logConfig.type}] ${logEvent.pid.toString()}   - `;const dateOutput = `${Moment(logEvent.startTime).format('YYYY-MM-DD HH:mm:ss',)}`;const moduleOutput: string = moduleName? `[${moduleName}] `: '[LoggerService] ';let levelOutput = `[${logEvent.level}] ${messageOutput}`;// 根据日志级别,用不同颜色区分switch (logEvent.level.toString()) {case LoggerLevel.DEBUG:levelOutput = Chalk.green(levelOutput);break;case LoggerLevel.INFO:levelOutput = Chalk.cyan(levelOutput);break;case LoggerLevel.WARN:levelOutput = Chalk.yellow(levelOutput);break;case LoggerLevel.ERROR:levelOutput = Chalk.red(levelOutput);break;case LoggerLevel.FATAL:levelOutput = Chalk.hex('#DD4C35')(levelOutput);break;default:levelOutput = Chalk.grey(levelOutput);break;}return `${Chalk.green(typeOutput)}${dateOutput}  ${Chalk.yellow(moduleOutput,)}${levelOutput}${positionOutput}`;};
});// 注入配置
Log4js.configure(config);// 实例化
const logger = Log4js.getLogger();
logger.level = LoggerLevel.TRACE;export class Logger {static trace(...args) {logger.trace(Logger.getStackTrace(), ...args);}static debug(...args) {logger.debug(Logger.getStackTrace(), ...args);}static log(...args) {logger.info(Logger.getStackTrace(), ...args);}static info(...args) {logger.info(Logger.getStackTrace(), ...args);}static warn(...args) {logger.warn(Logger.getStackTrace(), ...args);}static warning(...args) {logger.warn(Logger.getStackTrace(), ...args);}static error(...args) {logger.error(Logger.getStackTrace(), ...args);}static fatal(...args) {logger.fatal(Logger.getStackTrace(), ...args);}static access(...args) {const loggerCustom = Log4js.getLogger('http');loggerCustom.info(Logger.getStackTrace(), ...args);}// 日志追踪,可以追溯到哪个文件、第几行第几列static getStackTrace(deep = 2): string {const stackList: StackTrace.StackFrame[] = StackTrace.getSync();const stackInfo: StackTrace.StackFrame = stackList[deep];const lineNumber: number = stackInfo.lineNumber;const columnNumber: number = stackInfo.columnNumber;const fileName: string = stackInfo.fileName;const basename: string = Path.basename(fileName);return `${basename}(line: ${lineNumber}, column: ${columnNumber}): \n`;}
}

中间件文件:src/middleware/logger.middleware.ts

import { Request, Response } from 'express';
import { Logger } from '../utils/log4js';// 函数式中间件
export function logger(req: Request, res: Response, next: () => any) {const code = res.statusCode; // 响应状态码next();// 组装日志信息const logFormat = ` >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>请求参数Request original url: ${req.originalUrl}Method: ${req.method}IP: ${req.ip}Status code: ${code}Parmas: ${JSON.stringify(req.params)}Query: ${JSON.stringify(req.query)}Body: ${JSON.stringify(req.body,)} \n  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`;// 根据状态码,进行日志类型区分if (code >= 500) {Logger.error(logFormat);} else if (code >= 400) {Logger.warn(logFormat);} else {Logger.access(logFormat);Logger.log(logFormat);}
}

main.ts

import { logger } from './middleware/logger.middleware';async function bootstrap() {const app = await NestFactory.create(AppModule, { logger: console });app.use(logger);
}
bootstrap();

然后就可以记录日志辣~稍微详细一点的可以参考这位老哥的:https://blog.csdn.net/fwzzzzz/article/details/116160816

http://www.lryc.cn/news/268006.html

相关文章:

  • Selenium - 自动化测试框架
  • RFID技术在汽车制造:提高生产效率、优化物流管理和增强安全性
  • git异常
  • 【C语言学习疑难杂症】第12期:如何从汇编角度深入理解y = (*--p)++这行代码(易懂版)
  • 5G阅信应用场景有哪些?
  • 使用OpenSSL生成自签名SSL/TLS证书和私钥
  • pycharm2023.2激活和新建项目,python3.12安装永久换源
  • FPGA分频电路设计(2)
  • 【三】【C语言\动态规划】珠宝的最高价值、下降路径最小和、最小路径和,三道题目深度解析
  • 爬虫工作量由小到大的思维转变---<第二十八章 Scrapy中间件说明书>
  • 从Maven初级到高级
  • orangepi--开发板配置网络SSH登录
  • 简单通讯录管理系统第4关:简单通讯录管理系统之修改通讯录用户信息
  • macOS编译ckb-next
  • 漏刻有时数据可视化Echarts组件开发(46)散点图颜色判断
  • 智能优化算法应用:基于驾驶训练算法3D无线传感器网络(WSN)覆盖优化 - 附代码
  • 【论文阅读】MCANet: Medical Image Segmentation with Multi-Scale Cross-Axis Attention
  • 机器视觉实战应用:手势、人脸、动作以及手势鼠标构建(一)
  • python作业题百度网盘,python作业答案怎么查
  • centos7.9中离线安装nginx开启ssl,arm架构
  • LENOVO联想笔记本小新Pro 14 IRH8 2023款(83AL)电脑原装出厂Win11系统恢复预装OEM系统
  • blender使用faceit绑定自己的表情动作
  • 有关List的线程安全、高效读取:不变模式下的CopyOnWriteArrayList类、数据共享通道:BlockingQueue
  • OCC服务器和BCC服务器中文件同步
  • 工具系列:TimeGPT_(2)使用外生变量时间序列预测
  • 应用于前端的自然断点法:wasm应用示例
  • web前端javaScript笔记——(6)数组
  • vue的props
  • 【51单片机系列】DS18B20温度传感器模块
  • ubuntu20.04 conda环境配置Mask2former记录