From fd1c7edeb943390e673fba6118d17db74e419325 Mon Sep 17 00:00:00 2001 From: Tushar Choudhari Date: Wed, 27 Dec 2023 12:57:18 +0530 Subject: [PATCH 1/2] Add application start evet for Nest.js --- src/OpenAPM.ts | 4 ++-- src/clients/nestjs.ts | 27 +++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/OpenAPM.ts b/src/OpenAPM.ts index 5492a76..4bee74d 100644 --- a/src/OpenAPM.ts +++ b/src/OpenAPM.ts @@ -266,7 +266,7 @@ export class OpenAPM extends LevitateEvents { // Skip the OPTIONS requests not to blow up cardinality. Express does not provide // information about the route for OPTIONS requests, which makes it very // hard to detect correct PATH. Until we fix it properly, the requests are skipped - // to not blow up the cardinality. + // to not blow up the cardinality. if (!req.route && req.method === 'OPTIONS') { return; } @@ -315,7 +315,7 @@ export class OpenAPM extends LevitateEvents { } if (moduleName === 'nestjs') { const { NestFactory } = require('@nestjs/core'); - instrumentNestFactory(NestFactory, this._REDMiddleware); + instrumentNestFactory(NestFactory, this._REDMiddleware, this); } } catch (error) { if (Object.keys(moduleNames).includes(moduleName)) { diff --git a/src/clients/nestjs.ts b/src/clients/nestjs.ts index a761d6c..b957d69 100644 --- a/src/clients/nestjs.ts +++ b/src/clients/nestjs.ts @@ -1,9 +1,13 @@ -import type { NestFactoryStatic } from '@nestjs/core/nest-factory'; +import * as os from 'os'; import { isWrapped, wrap } from '../shimmer'; +import type { NestFactoryStatic } from '@nestjs/core/nest-factory'; +import type { NestApplication } from '@nestjs/core'; +import type OpenAPM from '../OpenAPM'; export const instrumentNestFactory = ( nestFactory: NestFactoryStatic, - redMiddleware: Function + redMiddleware: Function, + openapm: OpenAPM ) => { // Check if the NestFactory is already wrapped if (!isWrapped(nestFactory, 'create')) { @@ -19,6 +23,25 @@ export const instrumentNestFactory = ( ); // Add a global RED Middleware to the application app.use(redMiddleware); + + wrap(app, 'listen', (ogListen: NestApplication['listen']) => { + return function ( + this: NestApplication['listen'], + ...args: Parameters + ) { + openapm.emit('application_started', { + timestamp: new Date().toISOString(), + event_name: `${openapm.program}_app`, + event_state: 'start', + entity_type: 'app', + workspace: os.hostname(), + namespace: openapm.environment, + data_source_name: openapm.levitateConfig?.dataSourceName ?? '' + }); + return ogListen.apply(this, args); + } as NestApplication['listen']; + }); + return app; }; } From 4543ee7b5b91e905aed681c328783ab184cac8b7 Mon Sep 17 00:00:00 2001 From: Tushar Choudhari Date: Wed, 17 Jan 2024 12:51:05 +0530 Subject: [PATCH 2/2] Add stop event --- package-lock.json | 12 ++---------- src/OpenAPM.ts | 1 - src/clients/nestjs.ts | 15 +++++++++++++++ src/levitate/events.ts | 12 ++++++++++++ 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index ccfa7b0..fa71134 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,20 +1,12 @@ { "name": "@last9/openapm", -<<<<<<< HEAD - "version": "0.5.2-alpha-1", -======= - "version": "0.5.1-alpha.2", ->>>>>>> fef21961797c357f05cdc70919ce3330ba1f8c70 + "version": "0.6.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@last9/openapm", -<<<<<<< HEAD - "version": "0.5.2-alpha-1", -======= - "version": "0.5.1-alpha.2", ->>>>>>> fef21961797c357f05cdc70919ce3330ba1f8c70 + "version": "0.6.1", "license": "Apache-2.0", "dependencies": { "chalk": "^4.1.2", diff --git a/src/OpenAPM.ts b/src/OpenAPM.ts index 4bee74d..85a94f2 100644 --- a/src/OpenAPM.ts +++ b/src/OpenAPM.ts @@ -2,7 +2,6 @@ import * as os from 'os'; import http from 'http'; import ResponseTime from 'response-time'; import promClient from 'prom-client'; - import type { Counter, CounterConfiguration, diff --git a/src/clients/nestjs.ts b/src/clients/nestjs.ts index b957d69..9b8eca3 100644 --- a/src/clients/nestjs.ts +++ b/src/clients/nestjs.ts @@ -46,5 +46,20 @@ export const instrumentNestFactory = ( }; } ); + + const stopEvent = () => { + openapm.emit('application_stopped', { + timestamp: new Date().toISOString(), + event_name: `${openapm.program}_app`, + event_state: 'stop', + entity_type: 'app', + workspace: os.hostname(), + namespace: openapm.environment, + data_source_name: openapm.levitateConfig?.dataSourceName ?? '' + }); + }; + + process.on('SIGINT', stopEvent); + process.on('SIGTERM', stopEvent); } }; diff --git a/src/levitate/events.ts b/src/levitate/events.ts index 51ded2a..6db9514 100644 --- a/src/levitate/events.ts +++ b/src/levitate/events.ts @@ -42,6 +42,10 @@ export class LevitateEvents extends EventEmitter { event: 'application_started', ...args: (DomainEventsBody | any)[] ): boolean; + public emit( + event: 'application_stopped', + ...args: (DomainEventsBody | any)[] + ): boolean; public emit(event: any, ...args: any[]): any { return super.emit(event, ...args); } @@ -50,6 +54,10 @@ export class LevitateEvents extends EventEmitter { event: 'application_started', listener: (...args: (DomainEventsBody | any)[]) => void ): this; + public on( + event: 'application_stopped', + listener: (...args: (DomainEventsBody | any)[]) => void + ): this; public on(event: any, listener: (...args: any[]) => void): this { return super.on(event, listener); } @@ -58,6 +66,10 @@ export class LevitateEvents extends EventEmitter { event: 'application_started', listener: (...args: (DomainEventsBody | any)[]) => void ): this; + public once( + event: 'application_stopped', + listener: (...args: (DomainEventsBody | any)[]) => void + ): this; public once(event: any, listener: (...args: any[]) => void): this { return super.on(event, listener); }