首页 > 解决方案 > 将 Azure Applications Insights sdk 与 NestJS 记录器一起使用时出现问题

问题描述

在我们的 nestjs 应用程序中,我们尝试使用多个记录器,一个使用来自 nestjs 的 Logger,另一个是 Azure Application Insight client.trackTrace。当两个记录器都被调用时,我看到以下错误 1: 0x10003c597 node::Abort() [/usr/local/bin/node] 2: 0x1000bc617 node::Chdir(v8::FunctionCallbackInfo<v8::Value> const&) [/usr/local/bin/node] 3: 0x10023663f v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo*) [/usr/local/bin/node] 4: 0x100235b81 v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) [/usr/local/bin/node] 5: 0x100235220 v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) [/usr/local/bin/node] 6: 0x3196422dbe3d Abort trap: 6

如果只使用一个记录器,那么没有问题,两者都可以自己正常工作。

如果将nestjs Logger 替换为调用console.log、console.error ..etc 或process.env.stdout.write(..) 的记录器,那么它可以正常工作。因此,nestjs Logger 和 AppicationInsights 客户端之间似乎发生了一些事情。

工厂创建记录器

import * as appInsights from 'applicationinsights';
import {Logger, LoggerService} from '@nestjs/common';



  appInsights
    .setup()
    .setAutoCollectConsole(true, true)
    .setAutoDependencyCorrelation(true)
    .start();



export const getLogger = (prefix: string): LoggerService => {


    const appInsightLogger: LoggerService = new AppInsightLogger(
      prefix,
      appInsights.defaultClient,



    return new MultiLogger(appInsightLogger, new Logger(prefix));


  }

多记录器

import { LoggerService } from '@nestjs/common';

export class MultiLogger implements LoggerService {
  constructor(private readonly logger1: LoggerService, private readonly logger2:LoggerService) {}

  error(message: any, trace?: string, context?: string) {

    this.logger1.error(message, trace, context);
   this.logger2.error(message, trace, context);
  }
  log(message: any, context?: string) {

    this.logger1.log(message, context);
    this.logger2.log(message, context)
  }


  warn(message: any, context?: string) {

    this.logger1.warn(message, context);
    this.logger2.warn(message, context)
  }

  debug?(message: any, context?: string) {

    this.logger1.debug(message, context);
    this.logger2.debug(message, context);
  }
  verbose?(message: any, context?: string) {

    this.logger1.verbose(message, context);
    this.logger2.verbose(message, context)
  }
}

标签: typescriptazure-application-insightsnestjs

解决方案


而不是创建一个新的记录器来记录到默认的nestJs记录器和应用程序洞察,您所追求的解决方案是扩展默认记录器并在那里执行额外的记录到应用程序洞察(这将解决您遇到的问题)。

扩展后,您还可以注入记录器

为了访问应用洞察客户端,我在setClient记录器上创建了一个方法并在引导过程中调用它main.ts

const app = await NestFactory.create(AppModule);
const logger = await app.resolve(GcsLogger);
logger.setClient(appInsights.defaultClient);
app.useLogger(logger);

自定义,扩展记录器:

@Injectable({ scope: Scope.TRANSIENT })
export class GcsLogger extends Logger {
  private client: TelemetryClient;

  constructor() {
    super();
  }

  setClient(client: TelemetryClient) {
    this.client = client;
  }

  error(message: any, trace?: string, context?: string) {
    this.client.trackException({
      exception: message as Error,
      severity: SeverityLevel.Error,
      properties: [context, super.context, trace],
    } as ExceptionTelemetry);
    this.client.trackTrace({
      message,
      severity: SeverityLevel.Error,
    } as TraceTelemetry);
    super.error(message, trace);
  }

  warn = (message: string) => {
    this.client.trackTrace({
      message,
      severity: SeverityLevel.Warning,
      properties: [super.context],
    } as TraceTelemetry);
    super.warn(message);
  };

  debug(message: any, context?: string): any {
    this.client.trackTrace({
      message,
      severity: SeverityLevel.Information,
      properties: [context, super.context],
    } as TraceTelemetry);
    super.debug(message);
  }

  log(message: any, context?: string): any {
    this.client.trackTrace({
      message,
      severity: SeverityLevel.Information,
      properties: [context, super.context],
    } as TraceTelemetry);
    super.log(message);
  }

  verbose(message: any, context?: string): any {
    this.client.trackTrace({
      message,
      severity: SeverityLevel.Verbose,
      properties: [context, super.context],
    } as TraceTelemetry);
    super.verbose(message);
  }
}

推荐阅读