AppSignal APM을 NestJS와 통합하여 얻은 교훈
23320 단어 apmjavascriptnodenestjs
이 블로그 게시물에서는 AppSignal이 NestJS와 작동하도록 관리하는 방법을 공유합니다.
이 블로그 게시물에 사용된 코드 스니펫은 example project 의 일부입니다.
AppSignal 초기화 및 구성
AppSignal은 Node.js 도구 및 프레임워크(Express, Koa, PostgreSQL, Redis 등)에 후크를 연결하고 호출할 특정 함수를 관찰하는 자동 계측을 사용합니다. 함수가 호출되면 계측은 애플리케이션을 대신하여 추적 범위를 자동으로 수집합니다.
AppSignal에는 자동 계측 작업을 수행하기 위한 다음 요구 사항(AppSignaldocs에서 가져옴)이 있습니다.
To auto-instrument modules, the
Appsignal
module must be both required and initialized before any other package.
NestJS에서 개체를 인스턴스화하는 표준 방법은 종속성 주입(DI) 컨테이너를 사용하는 것입니다.
요구 사항을 충족하기 위해 NestJS DI 컨테이너를 사용하여 AppSignal을 인스턴스화할 수 없습니다. AppSignal은 전역 변수로 인스턴스화되어야 합니다. 즉, NestJS를 활용할 수 없습니다
ConfigModule
.환경 변수를 사용한 AppSignal 인스턴스화 및 구성의 예:
//source file: src/appsignal.ts
const name = process.env.APPSIGNAL_NAME;
const pushApiKey = process.env.APPSIGNAL_PUSH_API_KEY;
const active =
process.env.APPSIGNAL_ACTIVE === '1' ||
process.env.APPSIGNAL_ACTIVE === 'true';
export const appsignal = new Appsignal({
active,
name,
pushApiKey,
});
source code
또한 NestJS 애플리케이션 부트스트랩 코드에서 Express를 초기화할 때 AppSignal 미들웨어를 등록해야 합니다.
//source file: src/main.ts
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.use(appsignalExpressMiddleware(appsignal));
await app.listen(3000);
}
bootstrap();
source code
즉,
APPSIGNAL_PUSH_API_KEY
환경 변수를 유효한 AppSignal 키로 설정하고 APPSIGNAL_NAME
, APPSIGNAL_ACTIVE
환경 변수를 구성하면 AppSignal이 애플리케이션에서 처리하는 모든 HTTP 요청에서 메트릭 수집을 시작합니다.오류 추적
Nest에는 애플리케이션 전체에서 처리되지 않은 모든 예외 처리를 담당하는 기본 제공 예외 레이어가 함께 제공됩니다. 자세한 내용은 NestException filters docs를 참조하십시오.
Nest 예외 필터에서 처리하는 오류를 추적하기 위해 Nest
AppsignalExceptionFilter
인터페이스를 구현하는ExceptionFilter
을 만들었습니다.//source file: src/exception_filters/appsignal_exception.filter.ts
@Catch()
export class AppsignalExceptionFilter<T extends Error>
implements ExceptionFilter
{
catch(error: T, _host: ArgumentsHost) {
let status: number;
const tracer = appsignal.tracer();
if (!tracer) {
return;
}
if (error instanceof HttpException) {
status = error.getStatus();
}
if (error && (!status || (status && status >= 500))) {
tracer.setError(error);
}
}
}
source code
AppsignalExceptionFilter
는 상태 코드 5xx 및 기타 예외 유형이 있는 HttpException
예외를 추적합니다.사용자 정의 예외 필터 구현에서 확장하여
AppsignalExceptionFilter
를 사용하고 Nest 앱에서 예외 필터를 등록할 수 있습니다.확장의 예
AppsignalExceptionFilter
://source file: src/exception_filters/all_exception.filter.ts
@Catch()
export class AllExceptionFilter extends AppsignalExceptionFilter<Error> {
catch(error: Error, host: ArgumentsHost) {
super.catch(error, host);
const ctx = host.switchToHttp();
const req = ctx.getRequest<Request>();
const res = ctx.getResponse<Response>();
const status = 500;
const problem = {
status,
title: 'Internal server error',
instance: req.path,
};
res.status(status).contentType('application/problem+json').json(problem);
}
}
source code
전역 필터 등록의 예:
//source file: src/main.ts
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.use(appsignalExpressMiddleware(appsignal));
app.useGlobalFilters(new AllExceptionFilter());
await app.listen(3000);
}
bootstrap();
source code
@nestjs/bull 프로세스 모니터링
NestJS 외에도 백그라운드 작업 처리를 위해 Bull을 사용합니다. NestJS는 Bull의 래퍼로
@nestjs/bull
패키지를 제공합니다.AppSignal은 Bull 작업을 자동으로 추적하지 않습니다. 다행스럽게도 Appsignal custom instrumentation을 사용하여 추적을 처리할 수 있습니다.
Bull 작업을 추적하기 위해 Bull 프로세스 데코레이터
ProcessMonitor
를 만들었습니다.//source file: src/bull/process_monitor.decorator.ts
export function ProcessMonitor(): MethodDecorator {
return function (
target,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const method = descriptor.value;
descriptor.value = async function (...args: any) {
const tracer = appsignal.tracer();
const span = tracer.createSpan({
namespace: 'worker',
});
span.setName(`JOB ${this.constructor.name}.${propertyKey}`);
span.setCategory('job.handler');
const job = args[0];
if (job) {
span.setSampleData('custom_data', { jobId: job.id });
}
let result;
await tracer.withSpan(span, async span => {
try {
result = await method.bind(this).apply(target, args);
} catch (error) {
span.setError(error);
throw error;
} finally {
span.close();
}
});
return result;
};
};
}
source code
ProcessMonitor
메서드 데코레이터는 worker
네임스페이스에 새 스팬을 만들고, 작업 ID를 수집하고, 예외가 발생할 경우 오류가 있는 스팬을 설정합니다.ProcessMonitor
데코레이터를 코드 베이스에 추가하면 Bull 큐 프로세서 메서드를 데코레이션하여 사용을 시작합니다.export const MAILING_QUEUE = 'mails';
export const SEND_EMAIL = 'send_email';
@Processor(MAILING_QUEUE)
export class MailingProcessor {
@Process(SEND_EMAIL)
@ProcessMonitor()
async sendEmail(job: Job) {
...
}
}
우아한 AppSignal 중지
기본적으로
@appsignal/nodejs
는 Node.js V8 힙 통계를 추적하는 minutely probes을 시작합니다. 이 기능은 Node.js 내부에 대한 통찰력을 제공합니다.아쉽게도 미세 프로브가 활성화된 경우
stop
메서드를 호출하여 명시적으로 프로브를 중지해야 합니다. 그렇지 않으면 지원 프로세스가 정상적으로 중지되지 않습니다.Nest는
onApplicationShutdown
lifecycle event 와 함께 제공되며 AppSignal 중지 방법을 호출하기에 적합한 위치입니다. 아래의 AppsignalShutdownService
구현 예를 참조하십시오.//source file: src/appsignal_shutdown.service.ts
@Injectable()
export class AppsignalShutdownService implements OnApplicationShutdown {
onApplicationShutdown(_signal: string) {
appsignal.stop();
}
}
source code
Nest 애플리케이션 모듈에
AppsignalShutdownService
를 추가하는 것을 잊지 마십시오.//source file: src/app.module.ts
@Module({
providers: [AppsignalShutdownService],
})
export class AppModule {}
source code
Reference
이 문제에 관하여(AppSignal APM을 NestJS와 통합하여 얻은 교훈), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/superface/lessons-learned-integrating-appsignal-apm-with-nestjs-he7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)