|  | @@ -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;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 |