@pawells/nestjs-prometheus 1.0.0-dev.dd031b4 → 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 (24) hide show
  1. package/package.json +39 -78
  2. package/build/LICENSE +0 -21
  3. package/build/README.md +0 -290
  4. package/build/package.json +0 -63
  5. /package/{build/controllers → controllers}/metrics.controller.d.ts +0 -0
  6. /package/{build/controllers → controllers}/metrics.controller.d.ts.map +0 -0
  7. /package/{build/controllers → controllers}/metrics.controller.js +0 -0
  8. /package/{build/controllers → controllers}/metrics.controller.js.map +0 -0
  9. /package/{build/index.d.ts → index.d.ts} +0 -0
  10. /package/{build/index.d.ts.map → index.d.ts.map} +0 -0
  11. /package/{build/index.js → index.js} +0 -0
  12. /package/{build/index.js.map → index.js.map} +0 -0
  13. /package/{build/prometheus.exporter.d.ts → prometheus.exporter.d.ts} +0 -0
  14. /package/{build/prometheus.exporter.d.ts.map → prometheus.exporter.d.ts.map} +0 -0
  15. /package/{build/prometheus.exporter.js → prometheus.exporter.js} +0 -0
  16. /package/{build/prometheus.exporter.js.map → prometheus.exporter.js.map} +0 -0
  17. /package/{build/prometheus.module.d.ts → prometheus.module.d.ts} +0 -0
  18. /package/{build/prometheus.module.d.ts.map → prometheus.module.d.ts.map} +0 -0
  19. /package/{build/prometheus.module.js → prometheus.module.js} +0 -0
  20. /package/{build/prometheus.module.js.map → prometheus.module.js.map} +0 -0
  21. /package/{build/test-setup.d.ts → test-setup.d.ts} +0 -0
  22. /package/{build/test-setup.d.ts.map → test-setup.d.ts.map} +0 -0
  23. /package/{build/test-setup.js → test-setup.js} +0 -0
  24. /package/{build/test-setup.js.map → test-setup.js.map} +0 -0
package/package.json CHANGED
@@ -1,80 +1,41 @@
1
1
  {
2
- "name": "@pawells/nestjs-prometheus",
3
- "displayName": "@pawells/nestjs-prometheus",
4
- "version": "1.0.0-dev.dd031b4",
5
- "description": "NestJS Prometheus metrics module with endpoint controller",
6
- "type": "module",
7
- "main": "./build/index.js",
8
- "types": "./build/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./build/index.d.ts",
12
- "import": "./build/index.js"
13
- }
14
- },
15
- "scripts": {
16
- "build": "tsc --project tsconfig.build.json",
17
- "typecheck": "tsc --noEmit",
18
- "lint": "eslint src/",
19
- "lint:fix": "eslint src/ --fix",
20
- "test": "vitest run",
21
- "test:coverage": "vitest --coverage",
22
- "pipeline": "yarn typecheck && yarn lint && yarn test && yarn build"
23
- },
24
- "peerDependencies": {
25
- "@nestjs/common": ">=10.0.0",
26
- "@nestjs/config": ">=3.0.0",
27
- "@nestjs/core": ">=10.0.0",
28
- "@nestjs/throttler": ">=5.0.0",
29
- "@opentelemetry/api": ">=1.0.0",
30
- "class-transformer": ">=0.5.0",
31
- "class-validator": ">=0.14.0",
32
- "compression": ">=1.0.0",
33
- "csrf-csrf": ">=3.0.0",
34
- "express": ">=4.0.0",
35
- "helmet": ">=7.0.0",
36
- "joi": ">=17.0.0",
37
- "prom-client": ">=15.0.0",
38
- "rxjs": ">=7.0.0",
39
- "xss": ">=1.0.0"
40
- },
41
- "dependencies": {
42
- "@pawells/nestjs-shared": "^1.0.0"
43
- },
44
- "devDependencies": {
45
- "@nestjs/common": "^11.0.0",
46
- "@nestjs/config": "^3.3.0",
47
- "@nestjs/core": "^11.0.0",
48
- "@nestjs/throttler": "^6.4.0",
49
- "@opentelemetry/api": "^1.9.0",
50
- "class-transformer": "^0.5.1",
51
- "class-validator": "^0.14.1",
52
- "compression": "^1.7.4",
53
- "csrf-csrf": "^3.2.0",
54
- "express": "^4.21.0",
55
- "helmet": "^8.0.0",
56
- "joi": "^17.13.0",
57
- "prom-client": "^15.1.0",
58
- "reflect-metadata": "^0.2.2",
59
- "rxjs": "^7.8.0",
60
- "xss": "^1.0.15"
61
- },
62
- "engines": {
63
- "node": ">=22.0.0"
64
- },
65
- "packageManager": "yarn@4.12.0",
66
- "author": "Aaron Wells <69355326+PhillipAWells@users.noreply.github.com>",
67
- "license": "MIT",
68
- "repository": {
69
- "type": "git",
70
- "url": "https://github.com/PhillipAWells/nestjs-common"
71
- },
72
- "files": [
73
- "build/",
74
- "README.md",
75
- "LICENSE"
76
- ],
77
- "publishConfig": {
78
- "access": "public"
79
- }
2
+ "name": "@pawells/nestjs-prometheus",
3
+ "displayName": "@pawells/nestjs-prometheus",
4
+ "version": "1.0.0",
5
+ "description": "NestJS Prometheus metrics module with endpoint controller",
6
+ "type": "module",
7
+ "main": "./index.js",
8
+ "types": "./index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./index.d.ts",
12
+ "import": "./index.js"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsc --project tsconfig.build.json",
17
+ "typecheck": "tsc --noEmit",
18
+ "lint": "eslint src/",
19
+ "lint:fix": "eslint src/ --fix",
20
+ "test": "vitest run",
21
+ "test:coverage": "vitest --coverage",
22
+ "pipeline": "yarn typecheck && yarn lint && yarn test && yarn build"
23
+ },
24
+ "peerDependencies": {
25
+ "@nestjs/common": ">=10.0.0",
26
+ "prom-client": ">=15.0.0"
27
+ },
28
+ "dependencies": {
29
+ "@pawells/nestjs-shared": "1.0.0"
30
+ },
31
+ "engines": {
32
+ "node": ">=24.0.0"
33
+ },
34
+ "packageManager": "yarn@4.12.0",
35
+ "author": "Aaron Wells <69355326+PhillipAWells@users.noreply.github.com>",
36
+ "license": "MIT",
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "module": "./index.js"
80
41
  }
package/build/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Aaron Wells
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/build/README.md DELETED
@@ -1,290 +0,0 @@
1
- # NestJS Prometheus Module
2
-
3
- [![GitHub Release](https://img.shields.io/github/v/release/PhillipAWells/nestjs-common)](https://github.com/PhillipAWells/nestjs-common/releases)
4
- [![CI](https://github.com/PhillipAWells/nestjs-common/actions/workflows/ci.yml/badge.svg)](https://github.com/PhillipAWells/nestjs-common/actions/workflows/ci.yml)
5
- [![npm version](https://img.shields.io/npm/v/@pawells/nestjs-prometheus.svg?style=flat)](https://www.npmjs.com/package/@pawells/nestjs-prometheus)
6
- [![Node](https://img.shields.io/badge/node-%3E%3D24-brightgreen)](https://nodejs.org)
7
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
8
- [![GitHub Sponsors](https://img.shields.io/github/sponsors/PhillipAWells?style=social)](https://github.com/sponsors/PhillipAWells)
9
-
10
- Prometheus metrics exporter for NestJS with `/metrics` endpoint, integrated with `@pawells/nestjs-shared` InstrumentationRegistry for event-based metric collection.
11
-
12
- ## Installation
13
-
14
- ```bash
15
- yarn add @pawells/nestjs-prometheus prom-client
16
- ```
17
-
18
- ## Requirements
19
-
20
- - **Node.js**: >= 24.0.0
21
- - **NestJS**: >= 10.0.0
22
- - **prom-client**: >= 15.0.0
23
- - **@pawells/nestjs-shared**: same version
24
-
25
- ## Peer Dependencies
26
-
27
- ```json
28
- {
29
- "@nestjs/common": ">=10.0.0",
30
- "prom-client": ">=15.0.0"
31
- }
32
- ```
33
-
34
- ## Quick Start
35
-
36
- ### Module Setup
37
-
38
- Import `PrometheusModule` in your application module:
39
-
40
- ```typescript
41
- import { Module } from '@nestjs/common';
42
- import { PrometheusModule } from '@pawells/nestjs-prometheus';
43
-
44
- @Module({
45
- imports: [PrometheusModule.forRoot()],
46
- })
47
- export class AppModule {}
48
- ```
49
-
50
- This automatically registers the PrometheusExporter globally and exposes metrics at `GET /metrics` in Prometheus text format.
51
-
52
- ## How It Works
53
-
54
- The module integrates with `@pawells/nestjs-shared`'s `InstrumentationRegistry` to:
55
-
56
- 1. **Register descriptors**: When a metric is registered with the InstrumentationRegistry, PrometheusExporter pre-creates the corresponding prom-client instrument (Counter, Gauge, or Histogram)
57
- 2. **Buffer values**: Metric values are buffered in memory as they are recorded
58
- 3. **Flush on pull**: When the `/metrics` endpoint is scraped, all pending values are flushed into prom-client instruments and returned in Prometheus text format
59
- 4. **Cleanup**: On shutdown, the registry and internal caches are cleared
60
-
61
- This event-based design decouples metric recording from Prometheus scraping, preventing performance overhead on high-frequency metrics.
62
-
63
- ## The /metrics Endpoint
64
-
65
- The module automatically exposes:
66
-
67
- - **Endpoint**: `GET /metrics`
68
- - **Content-Type**: `text/plain; version=0.0.4; charset=utf-8`
69
- - **Headers**: `X-Robots-Tag: noindex, nofollow` (prevents indexing)
70
- - **Authentication**: Protected by `MetricsGuard` from `@pawells/nestjs-shared`
71
-
72
- ### Authentication
73
-
74
- The `/metrics` endpoint respects the optional `METRICS_API_KEY` environment variable:
75
-
76
- - If **not set**: All requests are allowed
77
- - If **set**: Requires Bearer token, X-API-Key header, or `?key=` query parameter
78
-
79
- ```bash
80
- # With METRICS_API_KEY=secret123
81
- curl -H "Authorization: Bearer secret123" http://localhost:3000/metrics
82
- curl -H "X-API-Key: secret123" http://localhost:3000/metrics
83
- curl "http://localhost:3000/metrics?key=secret123"
84
- ```
85
-
86
- ## Exported Metrics
87
-
88
- The exporter provides three types of metrics:
89
-
90
- ### Node.js Default Metrics
91
- Automatically collected via `prom-client`:
92
- - `process_cpu_user_seconds_total` - User CPU time
93
- - `process_cpu_system_seconds_total` - System CPU time
94
- - `process_resident_memory_bytes` - RSS memory usage
95
- - `nodejs_eventloop_delay_seconds` - Event loop delay
96
- - `nodejs_gc_duration_seconds` - Garbage collection duration
97
- - And many more...
98
-
99
- ### Custom Metrics
100
- Applications can register custom metrics with the InstrumentationRegistry and they will be exported automatically.
101
-
102
- ### Example Metrics Output
103
-
104
- ```
105
- # HELP process_cpu_user_seconds_total Total user CPU time spent in seconds.
106
- # TYPE process_cpu_user_seconds_total counter
107
- process_cpu_user_seconds_total 12.345
108
-
109
- # HELP http_request_duration_seconds HTTP request duration in seconds
110
- # TYPE http_request_duration_seconds histogram
111
- http_request_duration_seconds_bucket{le="0.001",method="GET",route="/api/users"} 0
112
- http_request_duration_seconds_bucket{le="0.01",method="GET",route="/api/users"} 5
113
- http_request_duration_seconds_bucket{le="0.1",method="GET",route="/api/users"} 42
114
- ```
115
-
116
- ## Accessing Metrics
117
-
118
- ### Via Prometheus Scraper
119
-
120
- Configure Prometheus to scrape your application:
121
-
122
- ```yaml
123
- # prometheus.yml
124
- scrape_configs:
125
- - job_name: 'my-app'
126
- static_configs:
127
- - targets: ['localhost:3000']
128
- metrics_path: '/metrics'
129
- scrape_interval: 15s
130
- # Optional: Add auth if METRICS_API_KEY is set
131
- authorization:
132
- credentials: 'secret123'
133
- type: Bearer
134
- ```
135
-
136
- ### Manual HTTP Request
137
-
138
- ```bash
139
- curl http://localhost:3000/metrics
140
-
141
- # With authentication
142
- curl -H "Authorization: Bearer secret123" http://localhost:3000/metrics
143
- ```
144
-
145
- ## Integration with @pawells/nestjs-shared HTTPMetricsInterceptor
146
-
147
- Combine PrometheusModule with HTTPMetricsInterceptor for automatic HTTP metrics:
148
-
149
- ```typescript
150
- import { Module } from '@nestjs/common';
151
- import { APP_INTERCEPTOR } from '@nestjs/core';
152
- import { PrometheusModule } from '@pawells/nestjs-prometheus';
153
- import { HTTPMetricsInterceptor } from '@pawells/nestjs-shared';
154
-
155
- @Module({
156
- imports: [PrometheusModule.forRoot()],
157
- providers: [
158
- {
159
- provide: APP_INTERCEPTOR,
160
- useClass: HTTPMetricsInterceptor,
161
- },
162
- ],
163
- })
164
- export class AppModule {}
165
- ```
166
-
167
- This automatically tracks:
168
- - **Request count** by method and route
169
- - **Request duration** (histogram with default buckets)
170
- - **Response status codes**
171
- - **Path normalization** (dynamic segments like UUIDs are normalized to `:id`)
172
-
173
- ## Module API
174
-
175
- ### PrometheusModule.forRoot()
176
-
177
- Returns a DynamicModule configured as global, enabling single import at the top level:
178
-
179
- ```typescript
180
- @Module({
181
- imports: [PrometheusModule.forRoot()],
182
- })
183
- export class AppModule {}
184
- ```
185
-
186
- ## Class Reference
187
-
188
- ### PrometheusModule
189
-
190
- The main NestJS module. Implements `OnModuleInit` and `OnApplicationShutdown`.
191
-
192
- **Static Methods:**
193
- - `forRoot()` - Create global module with automatic registration
194
-
195
- **Lifecycle Methods:**
196
- - `onModuleInit()` - Registers the exporter with InstrumentationRegistry
197
- - `onApplicationShutdown()` - Calls exporter.shutdown() to clean up resources
198
-
199
- ### PrometheusExporter
200
-
201
- Implements `IMetricsExporter` from `@pawells/nestjs-shared`.
202
-
203
- **Properties:**
204
- - `supportsEventBased` - `true` (buffers metric values)
205
- - `supportsPull` - `true` (supports pull-based retrieval)
206
-
207
- **Methods:**
208
- - `onDescriptorRegistered(descriptor: MetricDescriptor)` - Called when a metric is registered; creates the appropriate prom-client instrument
209
- - `onMetricRecorded(value: MetricValue)` - Buffers a metric value to be flushed on next pull
210
- - `getMetrics(): Promise<string>` - Flushes pending values and returns metrics in Prometheus text format
211
- - `shutdown(): Promise<void>` - Clears registry and releases resources
212
-
213
- **Internals:**
214
- - Maintains a prom-client `Registry` for instrument management
215
- - Buffers metric values per metric (max 1000 per metric to prevent unbounded memory growth)
216
- - Atomically swaps pending arrays during flush to prevent data loss on concurrent records
217
-
218
- ### MetricsController
219
-
220
- HTTP controller with single endpoint.
221
-
222
- **Methods:**
223
- - `getMetrics(response: Response): Promise<void>` - GET /metrics, protected by MetricsGuard
224
-
225
- ## Advanced Patterns
226
-
227
- ### Custom Metrics via InstrumentationRegistry
228
-
229
- Register custom metrics with `@pawells/nestjs-shared`:
230
-
231
- ```typescript
232
- import { Injectable } from '@nestjs/common';
233
- import { InstrumentationRegistry } from '@pawells/nestjs-shared';
234
-
235
- @Injectable()
236
- export class OrderService {
237
- constructor(private readonly registry: InstrumentationRegistry) {}
238
-
239
- trackOrderCreation(status: string) {
240
- // Register descriptor (once)
241
- this.registry.registerDescriptor({
242
- name: 'orders_created_total',
243
- type: 'counter',
244
- help: 'Total orders created',
245
- labelNames: ['status'],
246
- });
247
-
248
- // Record value
249
- this.registry.recordMetric({
250
- descriptor: { name: 'orders_created_total' } as MetricDescriptor,
251
- value: 1,
252
- labels: { status },
253
- });
254
- }
255
- }
256
- ```
257
-
258
- When metrics are pulled from `/metrics`, they are automatically exported in Prometheus format.
259
-
260
- ## Metric Types
261
-
262
- The PrometheusExporter supports these metric types (as defined in MetricDescriptor):
263
-
264
- | Type | Mapping | Usage |
265
- |------|---------|-------|
266
- | `counter` | prom-client Counter | Monotonically increasing values (e.g., request count) |
267
- | `gauge` | prom-client Gauge | Point-in-time values (e.g., memory usage) |
268
- | `updown_counter` | prom-client Gauge | Values that can increase or decrease |
269
- | `histogram` | prom-client Histogram | Distribution of values (e.g., request latency) |
270
-
271
- ### Gauge and UpDownCounter Accumulation Behavior
272
-
273
- **Gauge (`gauge`)**: Records a point-in-time snapshot value. Each recorded value overwrites the previous one for a given label set.
274
-
275
- **UpDownCounter (`updown_counter`)**: Accumulates values across scrapes. The PrometheusExporter maintains a running-total Map (`gaugeValues`) for each updown_counter metric, keyed by normalized label set. When a value is recorded:
276
- 1. All values for the same label set within a single scrape interval are accumulated together
277
- 2. The accumulated sum is then added to the persistent running total
278
- 3. This running total persists across Prometheus scrapes (resets only on exporter shutdown)
279
-
280
- Example: If you record `+5` then `+3` for the same labels in one scrape cycle, the running total increases by `8` (not just `3`). On the next scrape, if you record `+2`, the running total increases by another `2`.
281
-
282
- ## Related Packages
283
-
284
- - **[@pawells/nestjs-shared](https://www.npmjs.com/package/@pawells/nestjs-shared)** - Foundation: InstrumentationRegistry, HTTPMetricsInterceptor, MetricsGuard
285
- - **[@pawells/nestjs-open-telemetry](https://www.npmjs.com/package/@pawells/nestjs-open-telemetry)** - OpenTelemetry tracing and metrics integration
286
- - **[prom-client](https://github.com/siimon/prom-client)** - Official Prometheus client library for Node.js
287
-
288
- ## License
289
-
290
- MIT
@@ -1,63 +0,0 @@
1
- {
2
- "name": "@pawells/nestjs-prometheus",
3
- "displayName": "@pawells/nestjs-prometheus",
4
- "version": "1.0.0-dev.dd031b4",
5
- "description": "NestJS Prometheus metrics module with endpoint controller",
6
- "type": "module",
7
- "main": "./build/index.js",
8
- "types": "./build/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./build/index.d.ts",
12
- "import": "./build/index.js"
13
- }
14
- },
15
- "scripts": {
16
- "build": "tsc --project tsconfig.build.json",
17
- "typecheck": "tsc --noEmit",
18
- "lint": "eslint src/",
19
- "lint:fix": "eslint src/ --fix",
20
- "test": "vitest run",
21
- "test:coverage": "vitest --coverage",
22
- "pipeline": "yarn typecheck && yarn lint && yarn test && yarn build"
23
- },
24
- "peerDependencies": {
25
- "@nestjs/common": ">=10.0.0",
26
- "@nestjs/config": ">=3.0.0",
27
- "@nestjs/core": ">=10.0.0",
28
- "@nestjs/throttler": ">=5.0.0",
29
- "@opentelemetry/api": ">=1.0.0",
30
- "class-transformer": ">=0.5.0",
31
- "class-validator": ">=0.14.0",
32
- "compression": ">=1.0.0",
33
- "csrf-csrf": ">=3.0.0",
34
- "express": ">=4.0.0",
35
- "helmet": ">=7.0.0",
36
- "joi": ">=17.0.0",
37
- "prom-client": ">=15.0.0",
38
- "rxjs": ">=7.0.0",
39
- "xss": ">=1.0.0"
40
- },
41
- "dependencies": {
42
- "@pawells/nestjs-shared": "^1.0.0"
43
- },
44
- "engines": {
45
- "node": ">=22.0.0"
46
- },
47
- "packageManager": "yarn@4.12.0",
48
- "author": "Aaron Wells <69355326+PhillipAWells@users.noreply.github.com>",
49
- "license": "MIT",
50
- "repository": {
51
- "type": "git",
52
- "url": "https://github.com/PhillipAWells/nestjs-common"
53
- },
54
- "files": [
55
- "build/",
56
- "README.md",
57
- "LICENSE"
58
- ],
59
- "publishConfig": {
60
- "access": "public"
61
- },
62
- "module": "./index.js"
63
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes