【问题标题】:Is there a way to get the details of a class in a typescipt program so that I can pass these details to a logger(winston)?有没有办法在打字稿程序中获取类的详细信息,以便我可以将这些详细信息传递给记录器(winston)?
【发布时间】:2020-03-19 20:32:30
【问题描述】:

我已经为winston 编写了一个包装器。为了对此进行测试,我还编写了一个“问候类”,其中我调用了logger.info()。我希望我的日志也显示类名。 为此,当我调用 logger.info() 时,我还必须传递类的名称,以便我的包装器知道在哪个类中调用了记录器。但问题是我不希望程序员指定它。我想要创建一个抽象级别。我的包装器应该是用户友好的。 有没有办法做到这一点? 如果上述问题无法解决,是否有办法获取类及其方法的所有详细信息。我尝试传递“this”,但我得到类似 {greeting:world} 对不起,如果我没有使用正确的术语。我是 javascript 和 node.js 的新手。

包装器:

import "reflect-metadata";
import { injectable } from "inversify";
import { createLogger, format, transports, Logger as Iwinston } from "winston";

const { combine, timestamp, metadata, json, errors, label, printf } = format;

@injectable()
export default class Logger {
  public logger: Iwinston;

  private selfInfo: string;

  constructor() {
    this.selfInfo = "winston version >= 3.x";
    this.logger = createLogger(this.readOptions());
    this.addTransportConsole(this.getTransportConsoleOptions());
  }

  public info(message: string, data?: any): void {
    console.log(data);
    this.logger.info(message,data);
  }

  public error(message: string, data?: any): void {
    this.logger.error(message, data);
  }

  public getCoreVersion(): string {
    return this.selfInfo;
  }

  private readOptions(): Object {
    return {
      format: combine(
        label({ label: process.env.APP_NAME || "Unknown App" }),
        errors({ stack: true }),
        timestamp(),
        json(),
      ),
      transports:[
        new transports.File({filename:'error.log',level:'info'})
      ]
    };
  }

  private getTransportConsoleOptions(): transports.ConsoleTransportOptions {
    return {
      debugStdout: false
    };
  }

  private addTransportConsole(
    options?: transports.ConsoleTransportOptions
  ): void {
    this.logger.add(new transports.Console(options));
  }
}

我的测试:

import Logger from '../lib/component/logger/appLogger/winstonLogger'
let logger:Logger
logger = new Logger()

test('Winston Logger Test',() => {
class Greeter {
  greeting: string;
  constructor(message: string) {
      this.greeting = message;
      logger.info('hello',this)
  }
  greet() {
    console.log(globalThis.Document)
      logger.info('in greet')
      return "Hello, " + this.greeting;
  }
}
let greeter = new Greeter("world");
greeter.greet()
})

//{"level":"info","message":"hello","metadata":{},"label":"Unknown App","timestamp":"2019-11-22T09:30:07.256Z"}

【问题讨论】:

    标签: javascript typescript winston


    【解决方案1】:

    所以我在这里要做的是让他们在创建记录器的实例时将类作为参数传递:

    const logger = new Logger<Greeter>(Greeter)
    
    test('Winston Logger Test',() => {
    class Greeter {
    ....
    

    这意味着这个记录器实例现在在使用它的整个过程中都链接到这个类。在您的记录器类中,您可以在构造函数中设置我在 nameByInstance 方法中抽象出来的类的名称。

    import "reflect-metadata";
    import { injectable } from "inversify";
    import { createLogger, format, transports, Logger as Iwinston } from "winston";
    
    const { combine, timestamp, metadata, json, errors, label, printf } = format;
    
    @injectable()
    export default class Logger<TInstance> {
      public logger: Iwinston;
    
      private selfInfo: string;
    
      private loggerInstanceName: string;
    
      constructor(instance: TInstance) {
        this.selfInfo = "winston version >= 3.x";
        this.logger = createLogger(this.readOptions());
        this.addTransportConsole(this.getTransportConsoleOptions());
        this.loggerInstanceName = this.nameByInstance(instance);
    
        console.log(this.loggerInstanceName) // Greeter :)
      }
    
      public info(message: string, data?: any): void {
        console.log(data);
        this.logger.info(message,data);
      }
    
      public error(message: string, data?: any): void {
        this.logger.error(message, data);
      }
    
      public getCoreVersion(): string {
        return this.selfInfo;
      }
    
      private readOptions(): Object {
        return {
          format: combine(
            label({ label: process.env.APP_NAME || "Unknown App" }),
            errors({ stack: true }),
            timestamp(),
            json(),
          ),
          transports:[
            new transports.File({filename:'error.log',level:'info'})
          ]
        };
      }
    
      private getTransportConsoleOptions(): transports.ConsoleTransportOptions {
        return {
          debugStdout: false
        };
      }
    
      private addTransportConsole(
        options?: transports.ConsoleTransportOptions
      ): void {
        this.logger.add(new transports.Console(options));
      }
    
      private nameByInstance(type: TInstance): string {
        return type.prototype["constructor"]["name"];
      }
    }
    

    这意味着您现在可以让他们执行logger.info('hello') 并且您在记录器实例loggerInstanceName 中具有类名的上下文,以将其添加到他们在info 中的info 方法中传递的消息@没有他们必须这样做..很好,嘿?!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      相关资源
      最近更新 更多