|
@@ -1,14 +1,33 @@
|
|
|
-import log4js, { DateFileAppender, ConsoleAppender } from 'log4js';
|
|
|
+import log4js, { DateFileAppender, ConsoleAppender, Logger } from 'log4js';
|
|
|
import path from 'path';
|
|
|
import { Context } from 'koa';
|
|
|
import config from '@config';
|
|
|
-export interface commonInfo {
|
|
|
+export interface interfaceLogInfo {
|
|
|
ip: string,
|
|
|
params?: any,
|
|
|
time?: number
|
|
|
}
|
|
|
-// 输出配置
|
|
|
-export const output = (ctx, message: string | null | undefined , commonInfo: commonInfo) => {
|
|
|
+export interface interfaceLogger {
|
|
|
+ (ctx: Context): interfaceLog
|
|
|
+}
|
|
|
+export interface interfaceLog {
|
|
|
+ trace: interfaceLogFn
|
|
|
+ debug: interfaceLogFn
|
|
|
+ info: interfaceLogFn
|
|
|
+ warn: interfaceLogFn
|
|
|
+ error: interfaceLogFn
|
|
|
+ fatal: interfaceLogFn
|
|
|
+ mark: interfaceLogFn
|
|
|
+}
|
|
|
+interface interfaceLogFn {
|
|
|
+ (message: any): void;
|
|
|
+}
|
|
|
+interface interfaceAppenders {
|
|
|
+ [key: string]: DateFileAppender | ConsoleAppender
|
|
|
+}
|
|
|
+
|
|
|
+// 输出格式化配置
|
|
|
+export const formatOutputHandle = (ctx, message: string | null | undefined , commonInfo: interfaceLogInfo) => {
|
|
|
const {
|
|
|
method, // 请求方式
|
|
|
headers, // 请求headers
|
|
@@ -34,8 +53,7 @@ export const output = (ctx, message: string | null | undefined , commonInfo: com
|
|
|
let text = `[${method}] ${ctx.status} [${origin}${originalUrl}] ${time ? time + 'ms' : ''}
|
|
|
req: ${JSON.stringify(Object.assign(client, newCommonInfo))}`;
|
|
|
|
|
|
- if (Object.prototype.toString.call(message) === '[object Object]'
|
|
|
- || Object.prototype.toString.call(message) === '[object Error]') {
|
|
|
+ if (['[object Object]', '[object Array]', '[object Error]'].includes(Object.prototype.toString.call(message))) {
|
|
|
message = JSON.stringify(message);
|
|
|
};
|
|
|
|
|
@@ -44,6 +62,7 @@ req: ${JSON.stringify(Object.assign(client, newCommonInfo))}`;
|
|
|
};
|
|
|
return text;
|
|
|
};
|
|
|
+
|
|
|
// 日志级别
|
|
|
const methods: string[] = ['trace', 'debug', 'info', 'warn', 'error', 'fatal', 'mark'];
|
|
|
|
|
@@ -54,108 +73,102 @@ const defaultConfig = {
|
|
|
env: 'development' // 指定当前环境,当开发时控制台也输出
|
|
|
};
|
|
|
|
|
|
-// log配置
|
|
|
-const opt = Object.assign({}, defaultConfig, config.logs);
|
|
|
-const { env, appLogLevel, dir } = opt;
|
|
|
-/**
|
|
|
- * 记录日志的方式
|
|
|
- * 指定要记录的日志分类 log
|
|
|
- * 展示方式为文件类型 dateFile
|
|
|
- * 日志输出的文件名 s-yyyy-MM-dd.log
|
|
|
- */
|
|
|
-// interface appenders {
|
|
|
-// [key: string]: {
|
|
|
-// type: string,
|
|
|
-// filename?: string,
|
|
|
-// pattern?: string,
|
|
|
-// alwaysIncludePattern?: boolean,
|
|
|
-// ip?: string,
|
|
|
-// layout: object
|
|
|
-// }
|
|
|
-// }
|
|
|
-interface appenders {
|
|
|
- [key: string]: DateFileAppender | ConsoleAppender
|
|
|
-}
|
|
|
-const appenders: appenders = {
|
|
|
- log: {
|
|
|
- // 按日期进行输出log
|
|
|
- type: 'dateFile',
|
|
|
- // 路径和文件名
|
|
|
- filename: `${dir}/z`,
|
|
|
- pattern: 'yyyy-MM-dd.log',
|
|
|
- alwaysIncludePattern: true,
|
|
|
- // 日志输出格式
|
|
|
- layout: {
|
|
|
- type: 'pattern',
|
|
|
- pattern: '[%d{yyyy-MM-dd hh:mm:ss}] [%p] %c %m%n'
|
|
|
- }
|
|
|
+export default class MyLogger {
|
|
|
+ // log配置
|
|
|
+ logConfig = Object.assign({}, defaultConfig, config.logs);
|
|
|
+ // 记录日志的方式
|
|
|
+ appenders: interfaceAppenders = {}
|
|
|
+ // 记录日志的类型
|
|
|
+ categories
|
|
|
+ // 是否是开发环境
|
|
|
+ isDev: boolean = false
|
|
|
+ // log4js实例
|
|
|
+ logger: Logger = {} as Logger
|
|
|
+ constructor() {
|
|
|
}
|
|
|
-};
|
|
|
-// 开发和本地同时启用console
|
|
|
-if (env === 'dev' || env === 'local' || env === 'development') {
|
|
|
- appenders.out = {
|
|
|
- type: 'console',
|
|
|
- layout: {
|
|
|
- type: 'pattern',
|
|
|
- pattern: '%[[%d{yyyy-MM-dd hh:mm:ss}] [%p] %c%] %m%n'
|
|
|
- }
|
|
|
- };
|
|
|
-};
|
|
|
-const isDev = env === 'dev' || env === 'local' || env === 'development';
|
|
|
-
|
|
|
-/**
|
|
|
- * 指定日志的默认配置项
|
|
|
- * 如果 log4js.getLogger 中没有指定,默认为 appenders中的日志配置项, 数组
|
|
|
- * 指定日志的记录内容显示 某级别 及 某级别 以上级别的信息
|
|
|
- */
|
|
|
-const categories = {
|
|
|
- default: {
|
|
|
- appenders: Object.keys(appenders),
|
|
|
- level: appLogLevel
|
|
|
+ init() {
|
|
|
+ const { env, appLogLevel, dir } = this.logConfig;
|
|
|
+ /**
|
|
|
+ * 记录日志的方式
|
|
|
+ * 指定要记录的日志分类 log
|
|
|
+ * 展示方式为文件类型 dateFile
|
|
|
+ * 日志输出的文件名 s-yyyy-MM-dd.log
|
|
|
+ */
|
|
|
+ // interface appenders {
|
|
|
+ // [key: string]: {
|
|
|
+ // type: string,
|
|
|
+ // filename?: string,
|
|
|
+ // pattern?: string,
|
|
|
+ // alwaysIncludePattern?: boolean,
|
|
|
+ // ip?: string,
|
|
|
+ // layout: object
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ const appenders: interfaceAppenders = {
|
|
|
+ log: {
|
|
|
+ // 按日期进行输出log
|
|
|
+ type: 'dateFile',
|
|
|
+ // 路径和文件名
|
|
|
+ filename: `${dir}/z`,
|
|
|
+ pattern: 'yyyy-MM-dd.log',
|
|
|
+ alwaysIncludePattern: true,
|
|
|
+ // 日志输出格式
|
|
|
+ layout: {
|
|
|
+ type: 'pattern',
|
|
|
+ pattern: '[%d{yyyy-MM-dd hh:mm:ss}] [%p] %c %m%n'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ // 开发和本地同时启用console
|
|
|
+ const isDev = env === 'dev' || env === 'local' || env === 'development';
|
|
|
+ if (isDev) {
|
|
|
+ appenders.out = {
|
|
|
+ type: 'console',
|
|
|
+ layout: {
|
|
|
+ type: 'pattern',
|
|
|
+ pattern: '%[[%d{yyyy-MM-dd hh:mm:ss}] [%p] %c%] %m%n'
|
|
|
+ }
|
|
|
+ };
|
|
|
+ };
|
|
|
+ this.isDev = isDev
|
|
|
+ this.appenders = appenders
|
|
|
+ /**
|
|
|
+ * 指定日志的默认配置项
|
|
|
+ * 如果 log4js.getLogger 中没有指定,默认为 appenders中的日志配置项, 数组
|
|
|
+ * 指定日志的记录内容显示 某级别 及 某级别 以上级别的信息
|
|
|
+ */
|
|
|
+ const categories = {
|
|
|
+ default: {
|
|
|
+ appenders: Object.keys(appenders),
|
|
|
+ level: appLogLevel
|
|
|
+ }
|
|
|
+ };
|
|
|
+ this.categories = categories
|
|
|
+ // log4js配置
|
|
|
+ log4js.configure({
|
|
|
+ appenders,
|
|
|
+ categories,
|
|
|
+ pm2: !isDev,
|
|
|
+ pm2InstanceVar: 'INSTANCE_ID'
|
|
|
+ });
|
|
|
+ // 初始化log4js
|
|
|
+ this.logger = log4js.getLogger('log');
|
|
|
}
|
|
|
-};
|
|
|
-
|
|
|
-// log4js配置
|
|
|
-log4js.configure({
|
|
|
- appenders,
|
|
|
- categories,
|
|
|
- pm2: !isDev,
|
|
|
- pm2InstanceVar: 'INSTANCE_ID'
|
|
|
-});
|
|
|
-// 初始化log4js
|
|
|
-const logger = log4js.getLogger('log');
|
|
|
-
|
|
|
-interface logFn {
|
|
|
- (message: any, ...args: any[]): void;
|
|
|
-}
|
|
|
-export interface InterfaceLog {
|
|
|
- trace: logFn
|
|
|
- debug: logFn
|
|
|
- info: logFn
|
|
|
- warn: logFn
|
|
|
- error: logFn
|
|
|
- fatal: logFn
|
|
|
- mark: logFn
|
|
|
-}
|
|
|
-
|
|
|
-export interface InterfaceLogger {
|
|
|
- (ctx: Context): InterfaceLog
|
|
|
-}
|
|
|
-
|
|
|
-export const loggerInstance: InterfaceLogger = (ctx: Context): InterfaceLog => {
|
|
|
- const $log: InterfaceLog = {
|
|
|
- trace: () => {},
|
|
|
- debug: () => {},
|
|
|
- info: () => {},
|
|
|
- warn: () => {},
|
|
|
- error: () => {},
|
|
|
- fatal: () => {},
|
|
|
- mark: () => {}
|
|
|
- };
|
|
|
- methods.map(el => {
|
|
|
- $log[el] = (message) => {
|
|
|
- logger[el](output(ctx, message, { ip: ctx.ip }));
|
|
|
+ middleware(ctx: Context): interfaceLog {
|
|
|
+ const $log: interfaceLog = {
|
|
|
+ trace: () => {},
|
|
|
+ debug: () => {},
|
|
|
+ info: () => {},
|
|
|
+ warn: () => {},
|
|
|
+ error: () => {},
|
|
|
+ fatal: () => {},
|
|
|
+ mark: () => {}
|
|
|
};
|
|
|
- });
|
|
|
- return $log;
|
|
|
+ methods.map(el => {
|
|
|
+ $log[el] = (message) => {
|
|
|
+ this.logger[el](formatOutputHandle(ctx, message, { ip: ctx.ip }));
|
|
|
+ };
|
|
|
+ });
|
|
|
+ return $log;
|
|
|
+ }
|
|
|
}
|