nestjs系列笔记
nestjs系列笔记
nest笔记二:使用log4js替换nest默认日志
- 个人比较喜欢log4js,nest自带的日志,时间格式又不是我想要的,所以我这里实现一个替换nest日志的日志
基本上要求
- 时间格式为: YYYY-MM-DD hh:mm:ss.ddd
- 可以明确知道输出日志的是哪一个源文件
- 日志文件支持数量配置,大小配置
- 日志文件支持自动压缩
- 有专门的普通的日志文件和错误日志文件以及彩色的控制台输出。
基于上述几点,我这里选择了log4js
配置说明
log4js配置说明
- 具体如下,我这里是放工程的config/log4js.js文件里面,使用js可以支持注释,比较方便
module.exports = exports = {
appenders: {
log: {
type : 'file',
filename : './logs/log.log',
maxLogSize : 1024 * 1024 * 50,
encoding : 'utf-8',
backups : 100,
compress : true,
keepFileExt: true,
layout : {
type: 'messagePassThrough'
}
},
err: {
type : 'file',
filename : './logs/err.log',
maxLogSize : 1024 * 1024 * 50,
encoding : 'utf-8',
backups : 100,
compress : true,
keepFileExt: true,
layout : {
type: 'messagePassThrough'
}
},
console: {
type: 'stdout',
layout: { type: "messagePassThrough"}
}
},
categories: {
default: { appenders: ['log'], level: 'ALL' },
error : { appenders: ['err'], level: 'ALL' },
console: { appenders: ['console'], level: 'ALL' }
}
}
日志类实现
- 我这里文件名是./src/log/log4js.ts
import * as path from 'path';
import * as log4js from 'log4js';
import * as util from 'util';
import {GetLogManager, ILog, datetimeUtils} from 'xmcommon';
let normalLog : log4js.Logger;
let errorLog : log4js.Logger;
let consoleLog: log4js.Logger;
export enum EnumLogLevel {
TRACE = 'TRACE',
DEBUG = 'DEBUG',
LOG = ' LOG',
INFO = ' INFO',
ERROR = 'ERROR',
WARN = ' WARN',
}
const styles = {
bold: [1, 22],
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
white: [37, 39],
grey: [90, 39],
black: [90, 39],
blue: [34, 39],
cyan: [36, 39],
green: [32, 39],
magenta: [35, 39],
red: [91, 39],
yellow: [33, 39]
};
function colored(msg: {head: string, info: string}, paramColorStyle?: number[]): string {
if(paramColorStyle) {
return `\x1B[${paramColorStyle[0]}m${msg.head}\x1B[${paramColorStyle[1]}m ${msg.info}`;
} else {
return `${msg.head} ${msg.info}`;
}
}
function buildLog(categoryName: string, level: string, ...data: any[]) {
return {head:`[${datetimeUtils.nowDateString()} ${level}][${categoryName}]`, info: util.format(...data)};
}
class XLogFor4js implements ILog{
private m_name: string;
public constructor(paramName: string) {
this.m_name = paramName;
}
public get name() {
return this.m_name;
}
public trace(...paramLog: any[]): void {
const logInfo = buildLog(this.name, EnumLogLevel.TRACE, ...paramLog)
normalLog.trace(colored(logInfo));
consoleLog.trace(colored(logInfo, styles.blue));
}
public debug(...paramLog: any[]): void {
const logInfo = buildLog(this.name, EnumLogLevel.DEBUG, ...paramLog)
normalLog.debug(colored(logInfo));
consoleLog.debug(colored(logInfo, styles.cyan));
}
public log(...paramLog: any[]): void {
const logInfo = buildLog(this.name, EnumLogLevel.LOG, ...paramLog)
normalLog.info(colored(logInfo));
consoleLog.info(colored(logInfo, styles.magenta));
}
public info(...paramLog: any[]): void {
const logInfo = buildLog(this.name, EnumLogLevel.INFO, ...paramLog)
normalLog.info(colored(logInfo));
consoleLog.info(colored(logInfo, styles.green));
}
public error(...paramLog: any[]): void {
const logInfo = buildLog(this.name, EnumLogLevel.ERROR, ...paramLog);
const logMsg = colored(logInfo);
normalLog.error(logMsg);
errorLog.error(logMsg)
consoleLog.error(colored(logInfo, styles.red));
}
public warn(...paramLog: any[]): void {
const logInfo = buildLog(this.name, EnumLogLevel.WARN, ...paramLog)
const logMsg = colored(logInfo);
normalLog.warn(logMsg);
errorLog.warn(logMsg)
consoleLog.warn(colored(logInfo, styles.yellow));
}
}
function InitLog(paramConfigName: string) {
const cfg = require(paramConfigName);
log4js.configure(cfg);
normalLog = log4js.getLogger('default');
errorLog = log4js.getLogger('error');
consoleLog = log4js.getLogger('console');
const LogManager = GetLogManager();
LogManager.setCreateLog((paramTag:string) => new XLogFor4js(paramTag));
LogManager.setDefaultLog(new XLogFor4js('default'));
const conLog = LogManager.getLogger('console');
console.log = conLog.info.bind(conLog);
console.error = conLog.error.bind(conLog);
console.debug = conLog.debug.bind(conLog);
console.warn = conLog.warn.bind(conLog);
console.trace = conLog.trace.bind(conLog);
}
const configFile = path.join(process.cwd(), 'config', 'log4js.js');
InitLog(configFile);
替换nest的默认日志
- 在nest工程的启动文件src/main.ts,加入这个
- 在创建nest application的地方,指定日志文件
替换nest日志的类
import { LoggerService } from '@nestjs/common';
import { getLogger } from 'xmcommon';
const log = getLogger('nest');
export class NestLogger implements LoggerService {
log(...msg: any[]) {
log.info(...msg);
}
error(...msg:any[]) {
log.error(...msg);
}
warn(...msg:any[]) {
log.warn(...msg);
}
debug(...msg:any[]) {
log.debug(...msg);
}
verbose(...msg:any[]) {
log.trace(...msg);
}
}
在启动地方替换
import './log/log4js';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { getLogger } from 'xmcommon';
import { NestLogger } from './nest.logger';
const log = getLogger(__filename);
log.info('程序开始启动...');
async function bootstrap() {
const app = await NestFactory.create(AppModule,
{
logger: new NestLogger()
});
await app.listen(3000);
log.info('开始侦听:3000...')
}
bootstrap();