捕获控制台且不影响日志行

问题描述 投票:0回答:1

我正在开发一个用于控制台日志记录的类,但每次调用都会将一个新对象添加到控制台历史记录数组中。我创建了一个类 ConsoleLogger


    export class ConsoleLogger {
      private static instance: ConsoleLogger | null = null;

      private logs: LogEntry[] = [];
      private maxLogs = 50;

      public static getInstance(): ConsoleLogger {
        if (this.instance === null) {
          this.instance = new ConsoleLogger();
        }
        return this.instance;
      }

      private addLog(type: LogType, message: string): void {
        if (this.logs.length >= this.maxLogs) {
          this.logs.shift();
        }
        this.logs.push({ type, message, timestamp: new Date() });
      }


      public log = (function () {
        return Function.prototype.bind.call(console.log, console);
      })();

 public error = (function () {
    return Function.prototype.bind.call(console.error, console);
  })();
}

我可以在 .vue 和 .ts 文件中使用它,例如

ConsoleLogger.getInstance().log('console msg');
并且行信息正确引用了我的 .ts 文件/.vue 文件。我不确定如何将 addLog 行连接到每个方法,因为我无法在这个确切的日志函数中引用 this.addLog ,如果我尝试更改日志方法,我将使 this.addLog 可用,那么我当它开始引用我的 consoleLogger.ts 中的行时,我丢失了正确的行信息。

如何才能不丢失线路信息并正确使用我的addLog方法?

javascript typescript vue.js
1个回答
0
投票

为了实现记录正确的文件和行信息的目标,同时仍将每个日志条目添加到

ConsoleLogger
的历史记录中,您需要在保留
console.log
console.error
的正确上下文与访问之间取得平衡记录器类中的
addLog
方法。

  1. 使用
    apply
    bind
    保留原始
    console.log
    /
    console.error
    行为。
  2. 将日志记录方法包装在一个函数中,该函数在将参数传递给原始控制台方法之前调用
    this.addLog
  3. 如果需要跟踪原始文件和行信息,请捕获堆栈跟踪。

这是您的

ConsoleLogger
课程的更新版本:

export class ConsoleLogger {
  private static instance: ConsoleLogger | null = null;

  private logs: LogEntry[] = [];
  private maxLogs = 50;

  public static getInstance(): ConsoleLogger {
    if (this.instance === null) {
      this.instance = new ConsoleLogger();
    }
    return this.instance;
  }

  private addLog(type: LogType, message: string): void {
    if (this.logs.length >= this.maxLogs) {
      this.logs.shift(); // Remove the oldest log if limit is reached
    }
    this.logs.push({ type, message, timestamp: new Date() });
  }

  private logInternal(type: LogType, originalConsoleFn: (...args: any[]) => void, ...args: any[]): void {
    // Log the message to the internal history
    const message = args.map(arg => (typeof arg === 'string' ? arg : JSON.stringify(arg))).join(' ');
    this.addLog(type, message);

    // Call the original console function
    originalConsoleFn.apply(console, args);
  }

  public log(...args: any[]): void {
    // Call the logInternal with log type and original console.log method
    this.logInternal('log', console.log, ...args);
  }

  public error(...args: any[]): void {
    // Call the logInternal with error type and original console.error method
    this.logInternal('error', console.error, ...args);
  }
}

在您的 .vue 或 .ts 文件中,您仍然可以像这样使用记录器:

ConsoleLogger.getInstance().log('This is a log message');
ConsoleLogger.getInstance().error('This is an error message');

日志条目将通过

ConsoleLogger
添加到
this.addLog
历史记录中。 正确的文件和行号仍将显示在浏览器的控制台中(因为
console.log
console.error
按预期通过 apply 调用)。

© www.soinside.com 2019 - 2024. All rights reserved.