nestjs-profiler 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +123 -0
  2. package/dist/libs/nestjs-profiler/package.json +34 -0
  3. package/dist/libs/nestjs-profiler/src/analyzers/explain-analyzer.d.ts +5 -0
  4. package/dist/libs/nestjs-profiler/src/analyzers/explain-analyzer.js +39 -0
  5. package/dist/libs/nestjs-profiler/src/analyzers/explain-analyzer.js.map +1 -0
  6. package/dist/libs/nestjs-profiler/src/assets/favicon.ico +0 -0
  7. package/dist/libs/nestjs-profiler/src/assets/logo.png +0 -0
  8. package/dist/libs/nestjs-profiler/src/collectors/cache-collector.d.ts +18 -0
  9. package/dist/libs/nestjs-profiler/src/collectors/cache-collector.js +178 -0
  10. package/dist/libs/nestjs-profiler/src/collectors/cache-collector.js.map +1 -0
  11. package/dist/libs/nestjs-profiler/src/collectors/log-collector.d.ts +12 -0
  12. package/dist/libs/nestjs-profiler/src/collectors/log-collector.js +68 -0
  13. package/dist/libs/nestjs-profiler/src/collectors/log-collector.js.map +1 -0
  14. package/dist/libs/nestjs-profiler/src/collectors/mongo-collector.d.ts +19 -0
  15. package/dist/libs/nestjs-profiler/src/collectors/mongo-collector.js +203 -0
  16. package/dist/libs/nestjs-profiler/src/collectors/mongo-collector.js.map +1 -0
  17. package/dist/libs/nestjs-profiler/src/collectors/mysql-collector.d.ts +12 -0
  18. package/dist/libs/nestjs-profiler/src/collectors/mysql-collector.js +131 -0
  19. package/dist/libs/nestjs-profiler/src/collectors/mysql-collector.js.map +1 -0
  20. package/dist/libs/nestjs-profiler/src/collectors/postgres-collector.d.ts +15 -0
  21. package/dist/libs/nestjs-profiler/src/collectors/postgres-collector.js +205 -0
  22. package/dist/libs/nestjs-profiler/src/collectors/postgres-collector.js.map +1 -0
  23. package/dist/libs/nestjs-profiler/src/common/profiler-options.interface.d.ts +20 -0
  24. package/dist/libs/nestjs-profiler/src/common/profiler-options.interface.js +3 -0
  25. package/dist/libs/nestjs-profiler/src/common/profiler-options.interface.js.map +1 -0
  26. package/dist/libs/nestjs-profiler/src/common/profiler.model.d.ts +67 -0
  27. package/dist/libs/nestjs-profiler/src/common/profiler.model.js +3 -0
  28. package/dist/libs/nestjs-profiler/src/common/profiler.model.js.map +1 -0
  29. package/dist/libs/nestjs-profiler/src/controllers/profiler.controller.d.ts +33 -0
  30. package/dist/libs/nestjs-profiler/src/controllers/profiler.controller.js +237 -0
  31. package/dist/libs/nestjs-profiler/src/controllers/profiler.controller.js.map +1 -0
  32. package/dist/libs/nestjs-profiler/src/index.d.ts +5 -0
  33. package/dist/libs/nestjs-profiler/src/index.js +22 -0
  34. package/dist/libs/nestjs-profiler/src/index.js.map +1 -0
  35. package/dist/libs/nestjs-profiler/src/interceptors/request-profiler.interceptor.d.ts +11 -0
  36. package/dist/libs/nestjs-profiler/src/interceptors/request-profiler.interceptor.js +104 -0
  37. package/dist/libs/nestjs-profiler/src/interceptors/request-profiler.interceptor.js.map +1 -0
  38. package/dist/libs/nestjs-profiler/src/middleware/profiler.middleware.d.ts +4 -0
  39. package/dist/libs/nestjs-profiler/src/middleware/profiler.middleware.js +21 -0
  40. package/dist/libs/nestjs-profiler/src/middleware/profiler.middleware.js.map +1 -0
  41. package/dist/libs/nestjs-profiler/src/profiler-logger.d.ts +12 -0
  42. package/dist/libs/nestjs-profiler/src/profiler-logger.js +61 -0
  43. package/dist/libs/nestjs-profiler/src/profiler-logger.js.map +1 -0
  44. package/dist/libs/nestjs-profiler/src/profiler.module.d.ts +7 -0
  45. package/dist/libs/nestjs-profiler/src/profiler.module.js +105 -0
  46. package/dist/libs/nestjs-profiler/src/profiler.module.js.map +1 -0
  47. package/dist/libs/nestjs-profiler/src/services/entity-explorer.service.d.ts +19 -0
  48. package/dist/libs/nestjs-profiler/src/services/entity-explorer.service.js +110 -0
  49. package/dist/libs/nestjs-profiler/src/services/entity-explorer.service.js.map +1 -0
  50. package/dist/libs/nestjs-profiler/src/services/profiler.service.d.ts +31 -0
  51. package/dist/libs/nestjs-profiler/src/services/profiler.service.js +218 -0
  52. package/dist/libs/nestjs-profiler/src/services/profiler.service.js.map +1 -0
  53. package/dist/libs/nestjs-profiler/src/services/route-explorer.service.d.ts +15 -0
  54. package/dist/libs/nestjs-profiler/src/services/route-explorer.service.js +93 -0
  55. package/dist/libs/nestjs-profiler/src/services/route-explorer.service.js.map +1 -0
  56. package/dist/libs/nestjs-profiler/src/services/template-builder.service.d.ts +27 -0
  57. package/dist/libs/nestjs-profiler/src/services/template-builder.service.js +349 -0
  58. package/dist/libs/nestjs-profiler/src/services/template-builder.service.js.map +1 -0
  59. package/dist/libs/nestjs-profiler/src/services/view.service.d.ts +17 -0
  60. package/dist/libs/nestjs-profiler/src/services/view.service.js +197 -0
  61. package/dist/libs/nestjs-profiler/src/services/view.service.js.map +1 -0
  62. package/dist/libs/nestjs-profiler/src/storage/in-memory-profiler-storage.d.ts +9 -0
  63. package/dist/libs/nestjs-profiler/src/storage/in-memory-profiler-storage.js +27 -0
  64. package/dist/libs/nestjs-profiler/src/storage/in-memory-profiler-storage.js.map +1 -0
  65. package/dist/libs/nestjs-profiler/src/storage/profiler-storage.interface.d.ts +6 -0
  66. package/dist/libs/nestjs-profiler/src/storage/profiler-storage.interface.js +3 -0
  67. package/dist/libs/nestjs-profiler/src/storage/profiler-storage.interface.js.map +1 -0
  68. package/dist/libs/nestjs-profiler/src/views/cache.html +50 -0
  69. package/dist/libs/nestjs-profiler/src/views/dashboard.html +73 -0
  70. package/dist/libs/nestjs-profiler/src/views/detail.html +66 -0
  71. package/dist/libs/nestjs-profiler/src/views/entities.html +76 -0
  72. package/dist/libs/nestjs-profiler/src/views/js/dashboard.js +24 -0
  73. package/dist/libs/nestjs-profiler/src/views/js/entities.js +37 -0
  74. package/dist/libs/nestjs-profiler/src/views/js/layout-config.js +15 -0
  75. package/dist/libs/nestjs-profiler/src/views/js/layout.js +143 -0
  76. package/dist/libs/nestjs-profiler/src/views/js/queries.js +28 -0
  77. package/dist/libs/nestjs-profiler/src/views/layout.html +252 -0
  78. package/dist/libs/nestjs-profiler/src/views/logs.html +37 -0
  79. package/dist/libs/nestjs-profiler/src/views/not_found.html +15 -0
  80. package/dist/libs/nestjs-profiler/src/views/partials/cache_row.html +20 -0
  81. package/dist/libs/nestjs-profiler/src/views/partials/detail_query_row.html +33 -0
  82. package/dist/libs/nestjs-profiler/src/views/partials/entity_row.html +39 -0
  83. package/dist/libs/nestjs-profiler/src/views/partials/log_row.html +19 -0
  84. package/dist/libs/nestjs-profiler/src/views/partials/metadata_sidebar.html +27 -0
  85. package/dist/libs/nestjs-profiler/src/views/partials/pagination.html +9 -0
  86. package/dist/libs/nestjs-profiler/src/views/partials/query_row.html +34 -0
  87. package/dist/libs/nestjs-profiler/src/views/partials/request_row.html +25 -0
  88. package/dist/libs/nestjs-profiler/src/views/partials/route_row.html +12 -0
  89. package/dist/libs/nestjs-profiler/src/views/queries.html +65 -0
  90. package/dist/libs/nestjs-profiler/src/views/routes.html +41 -0
  91. package/package.json +125 -0
package/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # nestjs-profiler
2
+
3
+ A NestJS module for profiling HTTP requests, database queries, and cache operations. Inspired by Symfony Profiler, it provides a web-based dashboard to inspect request duration, executed queries, log messages, and explain plans for slow queries.
4
+
5
+ ## Features
6
+
7
+ - **HTTP Request Tracing**: Tracks method, URL, controller handler, duration, and status code.
8
+ - **Database Profiling**:
9
+ - **PostgreSQL**: Captures queries executed via `pg` (compatible with TypeORM, MikroORM, raw pg). Supports **Auto-Explain** to running `EXPLAIN` or `EXPLAIN ANALYZE` on slow queries.
10
+ - **MongoDB**: Profiles MongoDB commands and queries.
11
+ - **MySQL**: Profiles MySQL queries.
12
+ - **Cache Profiling**: Tracks cache operations (get, set, del) when using `@nestjs/cache-manager`.
13
+ - **Logger Profiling**: Captures application logs associated with the request context.
14
+ - **Web UI**: Built-in lightweight dashboard at `/__profiler` to view traces.
15
+ - **Zero Hard Dependencies**: Core functionality works out of the box; database drivers are optional peer dependencies.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install nestjs-profiler
21
+ ```
22
+
23
+ ### Peer Dependencies (Optional)
24
+
25
+ Install the dependencies relevant to your project:
26
+
27
+ ```bash
28
+ # For PostgreSQL
29
+ npm install pg
30
+
31
+ # For MongoDB
32
+ npm install mongodb
33
+
34
+ # For MySQL
35
+ npm install mysql2
36
+
37
+ # For Cache Profiling
38
+ npm install @nestjs/cache-manager cache-manager
39
+ ```
40
+
41
+ ## Configuration
42
+
43
+ Import `ProfilerModule` in your root `AppModule`.
44
+
45
+ ```typescript
46
+ import { Module } from '@nestjs/common';
47
+ import { ProfilerModule } from 'nestjs-profiler';
48
+
49
+ @Module({
50
+ imports: [
51
+ ProfilerModule.forRoot({
52
+ // Global enable/disable (default: true)
53
+ enabled: process.env.NODE_ENV !== 'production',
54
+
55
+ // PostgreSQL Profiling
56
+ collectQueries: true,
57
+ explain: {
58
+ enabled: true,
59
+ thresholdMs: 50, // Only explain queries taking > 50ms
60
+ analyze: false, // If true, runs EXPLAIN ANALYZE (execution!)
61
+ },
62
+ // Add pgDriver
63
+ pgDriver: pg,
64
+
65
+ // MongoDB Profiling (default: true)
66
+ collectMongo: true,
67
+
68
+ // MySQL Profiling (default: true)
69
+ collectMysql: true,
70
+
71
+ // Cache Profiling (default: true)
72
+ collectCache: true,
73
+
74
+ // Log Profiling (default: true)
75
+ collectLogs: true,
76
+
77
+ // Storage backend (default: InMemory)
78
+ // You can implement custom storage by passing an object implementing ProfilerStorage
79
+ storage: 'memory',
80
+ }),
81
+ ],
82
+ })
83
+ export class AppModule {}
84
+ ```
85
+
86
+ ## Usage
87
+
88
+ ### 1. Initialize Explorers (Optional but Recommended)
89
+
90
+ To enable the **Entity Explorer** and **Route Explorer** features in the dashboard, initialize the profiler in your `main.ts` file right after creating the application.
91
+
92
+ ```typescript
93
+ // main.ts
94
+ import { NestFactory } from '@nestjs/core';
95
+ import { AppModule } from './app.module';
96
+ import { ProfilerModule } from 'nestjs-profiler';
97
+
98
+ async function bootstrap() {
99
+ const app = await NestFactory.create(AppModule);
100
+
101
+ // Initialize Profiler Explorers
102
+ ProfilerModule.initialize(app);
103
+
104
+ await app.listen(3000);
105
+ }
106
+ bootstrap();
107
+ ```
108
+
109
+ ### 2. Accessing the Dashboard
110
+
111
+ Once configured, start your application. The profiler automatically intercepts requests and queries.
112
+
113
+ Navigate to `http://localhost:3000/__profiler` (or your app's port).
114
+
115
+ ### 3. JSON API
116
+
117
+ You can also retrieve profile data programmatically:
118
+ - `GET /__profiler/json` - List recent requests
119
+ - `GET /__profiler/:id/json` - Get details for a specific request
120
+
121
+ ## License
122
+
123
+ MIT
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "nestjs-profiler",
3
+ "version": "0.0.1",
4
+ "description": "NestJS PostgreSQL Profiler",
5
+ "main": "./src/index.js",
6
+ "types": "./src/index.d.ts",
7
+ "dependencies": {},
8
+ "peerDependencies": {
9
+ "@nestjs/common": "^10.0.0 || ^11.0.0",
10
+ "@nestjs/core": "^10.0.0 || ^11.0.0",
11
+ "pg": ">=8.0.0",
12
+ "mongodb": ">=4.0.0",
13
+ "mysql2": ">=2.0.0",
14
+ "rxjs": "^7.0.0"
15
+ },
16
+ "peerDependenciesMeta": {
17
+ "mongodb": {
18
+ "optional": true
19
+ },
20
+ "mysql2": {
21
+ "optional": true
22
+ },
23
+ "@nestjs/cache-manager": {
24
+ "optional": true
25
+ },
26
+ "cache-manager": {
27
+ "optional": true
28
+ }
29
+ },
30
+ "devDependencies": {
31
+ "@nestjs/cache-manager": "^2.0.0",
32
+ "cache-manager": "^5.0.0"
33
+ }
34
+ }
@@ -0,0 +1,5 @@
1
+ import * as pg from 'pg';
2
+ export declare class ExplainAnalyzer {
3
+ private readonly logger;
4
+ analyze(client: pg.Client | pg.PoolClient, query: string, params: any[], useAnalyze?: boolean): Promise<any>;
5
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var ExplainAnalyzer_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ExplainAnalyzer = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ let ExplainAnalyzer = ExplainAnalyzer_1 = class ExplainAnalyzer {
13
+ logger = new common_1.Logger(ExplainAnalyzer_1.name);
14
+ async analyze(client, query, params, useAnalyze = false) {
15
+ try {
16
+ const cmd = useAnalyze ? 'EXPLAIN (ANALYZE, FORMAT JSON)' : 'EXPLAIN (FORMAT JSON)';
17
+ const explainSql = `${cmd} ${query}`;
18
+ const result = await client.query(explainSql, params);
19
+ if (result.rows && result.rows.length > 0) {
20
+ return result.rows[0]['QUERY PLAN'];
21
+ }
22
+ return null;
23
+ }
24
+ catch (e) {
25
+ if (e.message.includes('closed') || e.message.includes('terminated')) {
26
+ return null;
27
+ }
28
+ if (process.env.PROFILER_DEBUG) {
29
+ this.logger.warn(`Failed to run EXPLAIN: ${e.message}`);
30
+ }
31
+ return null;
32
+ }
33
+ }
34
+ };
35
+ exports.ExplainAnalyzer = ExplainAnalyzer;
36
+ exports.ExplainAnalyzer = ExplainAnalyzer = ExplainAnalyzer_1 = __decorate([
37
+ (0, common_1.Injectable)()
38
+ ], ExplainAnalyzer);
39
+ //# sourceMappingURL=explain-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain-analyzer.js","sourceRoot":"","sources":["../../../../../libs/nestjs-profiler/src/analyzers/explain-analyzer.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAoD;AAI7C,IAAM,eAAe,uBAArB,MAAM,eAAe;IACP,MAAM,GAAG,IAAI,eAAM,CAAC,iBAAe,CAAC,IAAI,CAAC,CAAC;IAE3D,KAAK,CAAC,OAAO,CACT,MAAiC,EACjC,KAAa,EACb,MAAa,EACb,aAAsB,KAAK;QAE3B,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,uBAAuB,CAAC;YACpF,MAAM,UAAU,GAAG,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;YAErC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACtD,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;YACxC,CAAC;YACD,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YACd,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBAEnE,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;gBAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;CACJ,CAAA;AA7BY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;GACA,eAAe,CA6B3B"}
@@ -0,0 +1,18 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { ProfilerService } from '../services/profiler.service';
3
+ import type { ProfilerOptions } from '../common/profiler-options.interface';
4
+ import type { Cache } from 'cache-manager';
5
+ export declare class CacheCollector implements OnModuleInit {
6
+ private readonly profiler;
7
+ private readonly options;
8
+ private readonly cacheManager;
9
+ private readonly logger;
10
+ constructor(profiler: ProfilerService, options: ProfilerOptions, cacheManager: Cache);
11
+ onModuleInit(): void;
12
+ private wrapCacheManager;
13
+ private wrapGet;
14
+ private wrapSet;
15
+ private wrapDel;
16
+ private wrapReset;
17
+ private captureOperation;
18
+ }
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var CacheCollector_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.CacheCollector = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const profiler_service_1 = require("../services/profiler.service");
19
+ let CacheCollector = CacheCollector_1 = class CacheCollector {
20
+ profiler;
21
+ options;
22
+ cacheManager;
23
+ logger = new common_1.Logger(CacheCollector_1.name);
24
+ constructor(profiler, options, cacheManager) {
25
+ this.profiler = profiler;
26
+ this.options = options;
27
+ this.cacheManager = cacheManager;
28
+ }
29
+ onModuleInit() {
30
+ if (this.options.collectCache === false) {
31
+ return;
32
+ }
33
+ if (!this.cacheManager) {
34
+ this.logger.warn('No CACHE_MANAGER found, skipping Cache profiling. Ensure CacheModule is imported globally or available to ProfilerModule.');
35
+ return;
36
+ }
37
+ this.logger.log('CacheCollector initialized: Wrapping CACHE_MANAGER');
38
+ this.wrapCacheManager();
39
+ }
40
+ wrapCacheManager() {
41
+ const cm = this.cacheManager;
42
+ this.logger.log(`CacheCollector: Inspecting CacheManager keys: ${Object.keys(cm)}`);
43
+ if (cm.store && cm.store.get) {
44
+ this.logger.log('CacheCollector: Underlying store found: ' + (cm.store.name || cm.store.constructor?.name));
45
+ }
46
+ this.wrapGet(cm);
47
+ this.wrapSet(cm);
48
+ this.wrapDel(cm);
49
+ this.wrapReset(cm);
50
+ }
51
+ wrapGet(cm) {
52
+ const self = this;
53
+ const originalGet = cm.get;
54
+ if (originalGet) {
55
+ this.logger.log('CacheCollector: Wrapping "get" method');
56
+ cm.get = async function (...args) {
57
+ const startTime = Date.now();
58
+ const key = args[0];
59
+ try {
60
+ const result = await originalGet.apply(this, args);
61
+ const endTime = Date.now();
62
+ self.captureOperation('get', key, result !== undefined && result !== null ? 'hit' : 'miss', startTime, endTime);
63
+ return result;
64
+ }
65
+ catch (error) {
66
+ const endTime = Date.now();
67
+ self.captureOperation('get', key, 'fail', startTime, endTime);
68
+ throw error;
69
+ }
70
+ };
71
+ }
72
+ else {
73
+ this.logger.warn('CacheCollector: "get" method not found on CacheManager');
74
+ }
75
+ }
76
+ wrapSet(cm) {
77
+ const self = this;
78
+ const originalSet = cm.set;
79
+ if (originalSet) {
80
+ this.logger.log('CacheCollector: Wrapping "set" method');
81
+ cm.set = async function (...args) {
82
+ const startTime = Date.now();
83
+ const key = args[0];
84
+ const ttl = args[2];
85
+ try {
86
+ const result = await originalSet.apply(this, args);
87
+ const endTime = Date.now();
88
+ self.captureOperation('set', key, 'success', startTime, endTime, ttl);
89
+ return result;
90
+ }
91
+ catch (error) {
92
+ const endTime = Date.now();
93
+ self.captureOperation('set', key, 'fail', startTime, endTime);
94
+ throw error;
95
+ }
96
+ };
97
+ }
98
+ else {
99
+ this.logger.warn('CacheCollector: "set" method not found on CacheManager');
100
+ }
101
+ }
102
+ wrapDel(cm) {
103
+ const self = this;
104
+ const originalDel = cm.del;
105
+ if (originalDel) {
106
+ cm.del = async function (...args) {
107
+ const startTime = Date.now();
108
+ const key = args[0];
109
+ try {
110
+ const result = await originalDel.apply(this, args);
111
+ const endTime = Date.now();
112
+ self.captureOperation('del', key, 'success', startTime, endTime);
113
+ return result;
114
+ }
115
+ catch (error) {
116
+ const endTime = Date.now();
117
+ self.captureOperation('del', key, 'fail', startTime, endTime);
118
+ throw error;
119
+ }
120
+ };
121
+ }
122
+ }
123
+ wrapReset(cm) {
124
+ const self = this;
125
+ const originalReset = cm.reset;
126
+ if (originalReset) {
127
+ cm.reset = async function (...args) {
128
+ const startTime = Date.now();
129
+ try {
130
+ const result = await originalReset.apply(this, args);
131
+ const endTime = Date.now();
132
+ self.captureOperation('reset', '*', 'success', startTime, endTime);
133
+ return result;
134
+ }
135
+ catch (error) {
136
+ const endTime = Date.now();
137
+ self.captureOperation('reset', '*', 'fail', startTime, endTime);
138
+ throw error;
139
+ }
140
+ };
141
+ }
142
+ }
143
+ captureOperation(operation, key, result, startTime, endTime, ttl) {
144
+ try {
145
+ let storeName = 'unknown';
146
+ const cm = this.cacheManager;
147
+ if (cm.store) {
148
+ if (cm.store.name)
149
+ storeName = cm.store.name;
150
+ else if (cm.store.constructor && cm.store.constructor.name)
151
+ storeName = cm.store.constructor.name;
152
+ }
153
+ const profile = {
154
+ key: String(key),
155
+ store: storeName,
156
+ operation,
157
+ result,
158
+ ttl,
159
+ duration: endTime - startTime,
160
+ startTime,
161
+ };
162
+ this.logger.debug(`CacheCollector: Captured ${operation} on ${key}. Duration: ${profile.duration}ms`);
163
+ this.profiler.addCache(profile);
164
+ }
165
+ catch (e) {
166
+ this.logger.error('Error capturing cache operation', e);
167
+ }
168
+ }
169
+ };
170
+ exports.CacheCollector = CacheCollector;
171
+ exports.CacheCollector = CacheCollector = CacheCollector_1 = __decorate([
172
+ (0, common_1.Injectable)(),
173
+ __param(1, (0, common_1.Inject)('PROFILER_OPTIONS')),
174
+ __param(2, (0, common_1.Optional)()),
175
+ __param(2, (0, common_1.Inject)('CACHE_MANAGER')),
176
+ __metadata("design:paramtypes", [profiler_service_1.ProfilerService, Object, Object])
177
+ ], CacheCollector);
178
+ //# sourceMappingURL=cache-collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-collector.js","sourceRoot":"","sources":["../../../../../libs/nestjs-profiler/src/collectors/cache-collector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { ProfilerService } from '../services/profiler.service';
3
+ import type { ProfilerOptions } from '../common/profiler-options.interface';
4
+ export declare class LogCollector implements OnModuleInit {
5
+ private profiler;
6
+ private options;
7
+ private logger;
8
+ constructor(profiler: ProfilerService, options: ProfilerOptions);
9
+ onModuleInit(): void;
10
+ private patchProcessStream;
11
+ private capture;
12
+ }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var LogCollector_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.LogCollector = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const profiler_service_1 = require("../services/profiler.service");
19
+ let LogCollector = LogCollector_1 = class LogCollector {
20
+ profiler;
21
+ options;
22
+ logger = new common_1.Logger(LogCollector_1.name);
23
+ constructor(profiler, options) {
24
+ this.profiler = profiler;
25
+ this.options = options;
26
+ }
27
+ onModuleInit() {
28
+ if (this.options.collectLogs === false) {
29
+ return;
30
+ }
31
+ this.patchProcessStream('stdout');
32
+ this.patchProcessStream('stderr');
33
+ this.logger.log('LogCollector initialized: Patching process.stdout/stderr');
34
+ }
35
+ patchProcessStream(streamName) {
36
+ const stream = process[streamName];
37
+ const originalWrite = stream.write;
38
+ const self = this;
39
+ stream.write = function (chunk, encodingOrCb, cb) {
40
+ const result = originalWrite.apply(this, arguments);
41
+ try {
42
+ const msg = chunk.toString();
43
+ if (msg.includes('[LogCollector]'))
44
+ return result;
45
+ self.capture(streamName === 'stderr' ? 'error' : 'log', msg);
46
+ }
47
+ catch (e) {
48
+ }
49
+ return result;
50
+ };
51
+ }
52
+ capture(level, message) {
53
+ if (!message.trim())
54
+ return;
55
+ this.profiler.addLog({
56
+ level,
57
+ message: message.trim(),
58
+ timestamp: Date.now()
59
+ });
60
+ }
61
+ };
62
+ exports.LogCollector = LogCollector;
63
+ exports.LogCollector = LogCollector = LogCollector_1 = __decorate([
64
+ (0, common_1.Injectable)(),
65
+ __param(1, (0, common_1.Inject)('PROFILER_OPTIONS')),
66
+ __metadata("design:paramtypes", [profiler_service_1.ProfilerService, Object])
67
+ ], LogCollector);
68
+ //# sourceMappingURL=log-collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-collector.js","sourceRoot":"","sources":["../../../../../libs/nestjs-profiler/src/collectors/log-collector.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyF;AACzF,mEAA+D;AAIxD,IAAM,YAAY,oBAAlB,MAAM,YAAY;IAIT;IAC4B;IAJhC,MAAM,GAAG,IAAI,eAAM,CAAC,cAAY,CAAC,IAAI,CAAC,CAAC;IAE/C,YACY,QAAyB,EACG,OAAwB;QADpD,aAAQ,GAAR,QAAQ,CAAiB;QACG,YAAO,GAAP,OAAO,CAAiB;IAC5D,CAAC;IAEL,YAAY;QACR,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;YACrC,OAAO;QACX,CAAC;QAED,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;IAChF,CAAC;IAEO,kBAAkB,CAAC,UAA+B;QACtD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACnC,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC;QAElB,MAAM,CAAC,KAAK,GAAG,UACX,KAA0B,EAC1B,YAAuD,EACvD,EAA0B;YAE1B,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,SAAgB,CAAC,CAAC;YAE3D,IAAI,CAAC;gBACD,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC7B,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC;oBAAE,OAAO,MAAM,CAAC;gBAElD,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACjE,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;YACb,CAAC;YAED,OAAO,MAAM,CAAC;QAClB,CAAC,CAAC;IACN,CAAC;IAEO,OAAO,CAAC,KAAa,EAAE,OAAe;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,OAAO;QAE5B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YACjB,KAAK;YACL,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;YACvB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACxB,CAAC,CAAC;IACP,CAAC;CACJ,CAAA;AAnDY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;IAMJ,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCADT,kCAAe;GAJ5B,YAAY,CAmDxB"}
@@ -0,0 +1,19 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { ProfilerService } from '../services/profiler.service';
3
+ import type { ProfilerOptions } from '../common/profiler-options.interface';
4
+ export declare class MongoCollector implements OnModuleInit {
5
+ private profiler;
6
+ private options;
7
+ private logger;
8
+ private mongodb;
9
+ constructor(profiler: ProfilerService, options: ProfilerOptions);
10
+ onModuleInit(): void;
11
+ private patchMongo;
12
+ private handleQueryOperation;
13
+ private handleInsertOperation;
14
+ private handleAggregateOperation;
15
+ private buildFilter;
16
+ private captureQuery;
17
+ private rowCountResolvers;
18
+ private getRowCount;
19
+ }