@tracekit/node-apm 1.3.2 → 1.3.3
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.
- package/README.md +220 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Zero-config distributed tracing and performance monitoring for Express and NestJ
|
|
|
17
17
|
- **Client IP Capture** - Automatic IP detection for DDoS & traffic analysis
|
|
18
18
|
- **Error Tracking** - Capture exceptions with full context
|
|
19
19
|
- **Code Monitoring** - Live debugging with breakpoints and variable inspection
|
|
20
|
+
- **Metrics API** - Counter, Gauge, and Histogram metrics with automatic OTLP export
|
|
20
21
|
- **Low Overhead** - < 5% performance impact
|
|
21
22
|
|
|
22
23
|
## Installation
|
|
@@ -255,6 +256,225 @@ export class PaymentService {
|
|
|
255
256
|
|
|
256
257
|
Get your API key at [https://app.tracekit.dev](https://app.tracekit.dev)
|
|
257
258
|
|
|
259
|
+
## Metrics
|
|
260
|
+
|
|
261
|
+
TraceKit APM includes a powerful metrics API for tracking application performance and business metrics.
|
|
262
|
+
|
|
263
|
+
### Metric Types
|
|
264
|
+
|
|
265
|
+
TraceKit supports three types of metrics:
|
|
266
|
+
|
|
267
|
+
- **Counter**: Monotonically increasing values (requests, errors, events)
|
|
268
|
+
- **Gauge**: Point-in-time values that can go up or down (active connections, queue size)
|
|
269
|
+
- **Histogram**: Value distributions (request duration, payload sizes)
|
|
270
|
+
|
|
271
|
+
### Basic Usage
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
import * as tracekit from '@tracekit/node-apm';
|
|
275
|
+
|
|
276
|
+
const client = tracekit.init({
|
|
277
|
+
apiKey: process.env.TRACEKIT_API_KEY!,
|
|
278
|
+
serviceName: 'my-app',
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Create metrics
|
|
282
|
+
const requestCounter = client.counter('http.requests.total', {
|
|
283
|
+
service: 'my-app'
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
const activeRequestsGauge = client.gauge('http.requests.active', {
|
|
287
|
+
service: 'my-app'
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
const requestDurationHistogram = client.histogram('http.request.duration', {
|
|
291
|
+
unit: 'ms'
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// Use metrics in your handlers
|
|
295
|
+
app.use((req, res, next) => {
|
|
296
|
+
const startTime = Date.now();
|
|
297
|
+
|
|
298
|
+
activeRequestsGauge.inc();
|
|
299
|
+
|
|
300
|
+
res.on('finish', () => {
|
|
301
|
+
requestCounter.inc();
|
|
302
|
+
activeRequestsGauge.dec();
|
|
303
|
+
|
|
304
|
+
const duration = Date.now() - startTime;
|
|
305
|
+
requestDurationHistogram.record(duration);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
next();
|
|
309
|
+
});
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Counter
|
|
313
|
+
|
|
314
|
+
Counters track monotonically increasing values:
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
const counter = client.counter('events.processed', { type: 'order' });
|
|
318
|
+
|
|
319
|
+
// Increment by 1
|
|
320
|
+
counter.inc();
|
|
321
|
+
|
|
322
|
+
// Add custom amount
|
|
323
|
+
counter.add(5);
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Gauge
|
|
327
|
+
|
|
328
|
+
Gauges track values that can increase or decrease:
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
const gauge = client.gauge('queue.size', { queue: 'orders' });
|
|
332
|
+
|
|
333
|
+
// Set to specific value
|
|
334
|
+
gauge.set(42);
|
|
335
|
+
|
|
336
|
+
// Increment
|
|
337
|
+
gauge.inc();
|
|
338
|
+
|
|
339
|
+
// Decrement
|
|
340
|
+
gauge.dec();
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Histogram
|
|
344
|
+
|
|
345
|
+
Histograms track distributions of values:
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
const histogram = client.histogram('api.response.size', { unit: 'bytes' });
|
|
349
|
+
|
|
350
|
+
// Record a value
|
|
351
|
+
histogram.record(1024);
|
|
352
|
+
histogram.record(2048);
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Express Example
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
import express from 'express';
|
|
359
|
+
import * as tracekit from '@tracekit/node-apm';
|
|
360
|
+
|
|
361
|
+
const app = express();
|
|
362
|
+
const client = tracekit.init({
|
|
363
|
+
apiKey: process.env.TRACEKIT_API_KEY!,
|
|
364
|
+
serviceName: 'express-app',
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
app.use(tracekit.middleware());
|
|
368
|
+
|
|
369
|
+
// Initialize metrics
|
|
370
|
+
const requestCounter = client.counter('http.requests.total');
|
|
371
|
+
const activeRequests = client.gauge('http.requests.active');
|
|
372
|
+
const requestDuration = client.histogram('http.request.duration', { unit: 'ms' });
|
|
373
|
+
const errorCounter = client.counter('http.errors.total');
|
|
374
|
+
|
|
375
|
+
// Metrics middleware
|
|
376
|
+
app.use((req, res, next) => {
|
|
377
|
+
const start = Date.now();
|
|
378
|
+
activeRequests.inc();
|
|
379
|
+
|
|
380
|
+
res.on('finish', () => {
|
|
381
|
+
requestCounter.inc();
|
|
382
|
+
activeRequests.dec();
|
|
383
|
+
requestDuration.record(Date.now() - start);
|
|
384
|
+
|
|
385
|
+
if (res.statusCode >= 400) {
|
|
386
|
+
errorCounter.inc();
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
next();
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
app.get('/', (req, res) => {
|
|
394
|
+
res.send('Hello World');
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
app.listen(3000);
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### NestJS Example
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
import { Injectable, NestMiddleware } from '@nestjs/common';
|
|
404
|
+
import { Request, Response, NextFunction } from 'express';
|
|
405
|
+
import * as tracekit from '@tracekit/node-apm';
|
|
406
|
+
|
|
407
|
+
@Injectable()
|
|
408
|
+
export class MetricsMiddleware implements NestMiddleware {
|
|
409
|
+
private requestCounter = tracekit.getClient().counter('http.requests.total');
|
|
410
|
+
private activeRequests = tracekit.getClient().gauge('http.requests.active');
|
|
411
|
+
private requestDuration = tracekit.getClient().histogram('http.request.duration', { unit: 'ms' });
|
|
412
|
+
|
|
413
|
+
use(req: Request, res: Response, next: NextFunction) {
|
|
414
|
+
const start = Date.now();
|
|
415
|
+
this.activeRequests.inc();
|
|
416
|
+
|
|
417
|
+
res.on('finish', () => {
|
|
418
|
+
this.requestCounter.inc();
|
|
419
|
+
this.activeRequests.dec();
|
|
420
|
+
this.requestDuration.record(Date.now() - start);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
next();
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### Tags
|
|
429
|
+
|
|
430
|
+
Add tags to metrics for dimensional analysis:
|
|
431
|
+
|
|
432
|
+
```typescript
|
|
433
|
+
const counter = client.counter('api.requests', {
|
|
434
|
+
service: 'payment-api',
|
|
435
|
+
region: 'us-east-1',
|
|
436
|
+
environment: 'production'
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
counter.inc();
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Common Use Cases
|
|
443
|
+
|
|
444
|
+
#### HTTP Request Tracking
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
const requests = client.counter('http.requests', { method: 'POST', endpoint: '/api/orders' });
|
|
448
|
+
const duration = client.histogram('http.duration', { endpoint: '/api/orders' });
|
|
449
|
+
const errors = client.counter('http.errors', { code: '500' });
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
#### Database Metrics
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
const queries = client.counter('db.queries', { operation: 'SELECT' });
|
|
456
|
+
const queryDuration = client.histogram('db.query.duration', { unit: 'ms' });
|
|
457
|
+
const connections = client.gauge('db.connections.active');
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
#### Business Metrics
|
|
461
|
+
|
|
462
|
+
```typescript
|
|
463
|
+
const orders = client.counter('orders.created');
|
|
464
|
+
const revenue = client.histogram('orders.amount', { unit: 'usd' });
|
|
465
|
+
const inventory = client.gauge('inventory.stock', { product: 'laptop' });
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### Metric Export
|
|
469
|
+
|
|
470
|
+
Metrics are automatically buffered and exported in batches:
|
|
471
|
+
|
|
472
|
+
- **Buffer size**: 100 metrics
|
|
473
|
+
- **Flush interval**: 10 seconds
|
|
474
|
+
- **Endpoint**: Automatically resolved to `/v1/metrics`
|
|
475
|
+
|
|
476
|
+
Metrics are sent to TraceKit using OTLP format and appear in your dashboard with full dimensional analysis.
|
|
477
|
+
|
|
258
478
|
## Configuration
|
|
259
479
|
|
|
260
480
|
### Basic Configuration
|
package/package.json
CHANGED