typescript - 将 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)
}
}
解决方案
而不是创建一个新的记录器来记录到默认的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);
}
}
推荐阅读
- html - 未捕获的类型错误:$(...).datetimepicker 不是函数错误
- python - 取消透视数据框并加入熊猫
- python - Python 行继续导致 DeprecationWarning
- scikit-learn - GaussianProcessClassifier 中的 max_iter_predict=1 和 max_iter_predict=10 给出相同的结果
- c# - C#用阴影为图像着色
- mysql - 搭建一个节点用户访问控制管理模块,与MySQL协同工作,表达为中间件
- java - E/RecyclerView:没有附加适配器;跳过布局 (Android)
- css - Bootstrap 动态药丸只能使用一次?
- java - 如何从查询中获取结果?(MySQL)
- java - 有人可以解释一下递归功能是如何在工作树数据结构上工作的吗