@zenvark/prom 1.2.0 → 1.3.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.
- package/README.md +44 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/prometheus-semaphore-metrics.d.ts +46 -0
- package/dist/prometheus-semaphore-metrics.js +89 -0
- package/dist/prometheus-semaphore-metrics.js.map +1 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @zenvark/prom
|
|
2
2
|
|
|
3
|
-
Prometheus metrics integration for [Zenvark
|
|
3
|
+
Prometheus metrics integration for the [Zenvark](https://www.npmjs.com/package/zenvark) circuit breaker and adaptive semaphore.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -40,19 +40,56 @@ const circuitBreaker = new CircuitBreaker({
|
|
|
40
40
|
await circuitBreaker.start();
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
For the adaptive semaphore, pass `PrometheusSemaphoreMetrics` the same way:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { AdaptiveSemaphore } from "zenvark";
|
|
47
|
+
import { PrometheusSemaphoreMetrics } from "@zenvark/prom";
|
|
48
|
+
import { register } from "prom-client";
|
|
49
|
+
|
|
50
|
+
const semaphore = new AdaptiveSemaphore({
|
|
51
|
+
id: "my-provider-api",
|
|
52
|
+
redis,
|
|
53
|
+
initialLimit: 10,
|
|
54
|
+
maxLimit: 1000,
|
|
55
|
+
metrics: new PrometheusSemaphoreMetrics({
|
|
56
|
+
registry: register,
|
|
57
|
+
customLabels: { service: "my-api", environment: "production" },
|
|
58
|
+
}),
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
43
62
|
## Available Metrics
|
|
44
63
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
| `
|
|
64
|
+
### Circuit breaker
|
|
65
|
+
|
|
66
|
+
| Metric | Type | Description | Labels |
|
|
67
|
+
| -------------------------------------- | --------- | -------------------------------------------- | ------------------------------ |
|
|
68
|
+
| `zenvark_call_duration_seconds` | Histogram | Duration of protected calls | `breaker_id`, `result` |
|
|
69
|
+
| `zenvark_blocked_requests_total` | Counter | Requests blocked by open circuit | `breaker_id` |
|
|
70
|
+
| `zenvark_healthcheck_duration_seconds` | Histogram | Health check attempt duration | `breaker_id`, `type`, `result` |
|
|
71
|
+
| `zenvark_state` | Gauge | Circuit state (active state 1, all others 0) | `breaker_id`, `state` |
|
|
72
|
+
|
|
73
|
+
### Semaphore
|
|
74
|
+
|
|
75
|
+
| Metric | Type | Description | Labels |
|
|
76
|
+
| ----------------------------------------- | --------- | ------------------------------------------- | ---------------------------------- |
|
|
77
|
+
| `zenvark_semaphore_acquire_wait_seconds` | Histogram | Time spent waiting for a lease | `semaphore_id`, `class`, `result` |
|
|
78
|
+
| `zenvark_semaphore_hold_duration_seconds` | Histogram | Time a lease was held | `semaphore_id`, `class`, `outcome` |
|
|
79
|
+
| `zenvark_semaphore_limit` | Gauge | This process's view of the fleet-wide limit | `semaphore_id` |
|
|
80
|
+
| `zenvark_semaphore_throttle_events_total` | Counter | Caller-reported throttle events | `semaphore_id` |
|
|
81
|
+
|
|
82
|
+
The limit gauge is set on every process whose cached view changes, so a scrape of any instance reads the current fleet-wide limit. Sum or average across instances accordingly.
|
|
50
83
|
|
|
51
84
|
### Label Values
|
|
52
85
|
|
|
53
86
|
- `breaker_id` - Circuit breaker instance identifier
|
|
54
87
|
- `type` - Health check type: `recovery` or `idle`
|
|
55
|
-
- `result` -
|
|
88
|
+
- `result` - Breaker call outcome (`success` or `failure`), or semaphore acquire outcome (`acquired` or `timeout`)
|
|
89
|
+
- `state` - Circuit state: `closed` or `open`
|
|
90
|
+
- `semaphore_id` - Semaphore instance identifier
|
|
91
|
+
- `class` - Semaphore priority class (empty when acquired without a class)
|
|
92
|
+
- `outcome` - Lease release outcome: `success`, `throttled` or `failure`
|
|
56
93
|
- Custom labels - Additional key-value pairs from configuration
|
|
57
94
|
|
|
58
95
|
## Custom Labels
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { getOrCreateCounter, getOrCreateHistogram, } from './get-or-create-metric.ts';
|
|
2
2
|
export { PrometheusBreakerMetrics, type PrometheusBreakerMetricsOptions, } from './prometheus-breaker-metrics.ts';
|
|
3
|
+
export { PrometheusSemaphoreMetrics, type PrometheusSemaphoreMetricsOptions, } from './prometheus-semaphore-metrics.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { getOrCreateCounter, getOrCreateHistogram, } from "./get-or-create-metric.js";
|
|
2
2
|
export { PrometheusBreakerMetrics, } from "./prometheus-breaker-metrics.js";
|
|
3
|
+
export { PrometheusSemaphoreMetrics, } from "./prometheus-semaphore-metrics.js";
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,wBAAwB,GAEzB,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,wBAAwB,GAEzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,0BAA0B,GAE3B,MAAM,mCAAmC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Registry } from 'prom-client';
|
|
2
|
+
import type { RecordAcquireParams, RecordLimitChangeParams, RecordReleaseParams, RecordThrottleParams, SemaphoreMetricsRecorder } from 'zenvark';
|
|
3
|
+
export type PrometheusSemaphoreMetricsOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* Prometheus registry instance
|
|
6
|
+
*/
|
|
7
|
+
registry: Registry;
|
|
8
|
+
/**
|
|
9
|
+
* Prefix for all metric names (default: 'zenvark')
|
|
10
|
+
*/
|
|
11
|
+
prefix?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Custom labels to add to all metrics
|
|
14
|
+
*/
|
|
15
|
+
customLabels?: Record<string, string>;
|
|
16
|
+
};
|
|
17
|
+
export declare class PrometheusSemaphoreMetrics implements SemaphoreMetricsRecorder {
|
|
18
|
+
private readonly customLabels;
|
|
19
|
+
private readonly acquireWaitHistogram;
|
|
20
|
+
private readonly holdDurationHistogram;
|
|
21
|
+
private readonly limitGauge;
|
|
22
|
+
private readonly throttleEventsCounter;
|
|
23
|
+
constructor(options: PrometheusSemaphoreMetricsOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Initialize metrics for a semaphore.
|
|
26
|
+
* Sets the throttle counter to 0 so the metric appears in scrapes immediately.
|
|
27
|
+
*/
|
|
28
|
+
initialize(id: string): void;
|
|
29
|
+
private getLabels;
|
|
30
|
+
/**
|
|
31
|
+
* Record the outcome of an acquire attempt and the time spent waiting
|
|
32
|
+
*/
|
|
33
|
+
recordAcquire(params: RecordAcquireParams): void;
|
|
34
|
+
/**
|
|
35
|
+
* Record a lease release with its outcome and hold duration
|
|
36
|
+
*/
|
|
37
|
+
recordRelease(params: RecordReleaseParams): void;
|
|
38
|
+
/**
|
|
39
|
+
* Record a change of the cached fleet-wide limit
|
|
40
|
+
*/
|
|
41
|
+
recordLimitChange(params: RecordLimitChangeParams): void;
|
|
42
|
+
/**
|
|
43
|
+
* Record a caller-reported throttle event
|
|
44
|
+
*/
|
|
45
|
+
recordThrottle(params: RecordThrottleParams): void;
|
|
46
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { getOrCreateCounter, getOrCreateGauge, getOrCreateHistogram, } from "./get-or-create-metric.js";
|
|
2
|
+
export class PrometheusSemaphoreMetrics {
|
|
3
|
+
customLabels;
|
|
4
|
+
acquireWaitHistogram;
|
|
5
|
+
holdDurationHistogram;
|
|
6
|
+
limitGauge;
|
|
7
|
+
throttleEventsCounter;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
const prefix = options.prefix ?? 'zenvark';
|
|
10
|
+
this.customLabels = options.customLabels ?? {};
|
|
11
|
+
const customLabelNames = Object.keys(this.customLabels);
|
|
12
|
+
this.acquireWaitHistogram = getOrCreateHistogram(options.registry, {
|
|
13
|
+
name: `${prefix}_semaphore_acquire_wait_seconds`,
|
|
14
|
+
help: 'Time spent waiting for a semaphore lease in seconds, by acquire result.',
|
|
15
|
+
labelNames: ['semaphore_id', 'class', 'result', ...customLabelNames],
|
|
16
|
+
buckets: [0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
|
|
17
|
+
registers: [options.registry],
|
|
18
|
+
});
|
|
19
|
+
this.holdDurationHistogram = getOrCreateHistogram(options.registry, {
|
|
20
|
+
name: `${prefix}_semaphore_hold_duration_seconds`,
|
|
21
|
+
help: 'Time a semaphore lease was held in seconds, by release outcome.',
|
|
22
|
+
labelNames: ['semaphore_id', 'class', 'outcome', ...customLabelNames],
|
|
23
|
+
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60],
|
|
24
|
+
registers: [options.registry],
|
|
25
|
+
});
|
|
26
|
+
this.limitGauge = getOrCreateGauge(options.registry, {
|
|
27
|
+
name: `${prefix}_semaphore_limit`,
|
|
28
|
+
help: "This process's cached view of the fleet-wide semaphore limit.",
|
|
29
|
+
labelNames: ['semaphore_id', ...customLabelNames],
|
|
30
|
+
registers: [options.registry],
|
|
31
|
+
});
|
|
32
|
+
this.throttleEventsCounter = getOrCreateCounter(options.registry, {
|
|
33
|
+
name: `${prefix}_semaphore_throttle_events_total`,
|
|
34
|
+
help: 'Total number of THROTTLED releases reported by callers.',
|
|
35
|
+
labelNames: ['semaphore_id', ...customLabelNames],
|
|
36
|
+
registers: [options.registry],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Initialize metrics for a semaphore.
|
|
41
|
+
* Sets the throttle counter to 0 so the metric appears in scrapes immediately.
|
|
42
|
+
*/
|
|
43
|
+
initialize(id) {
|
|
44
|
+
const labels = this.getLabels(id);
|
|
45
|
+
this.throttleEventsCounter.inc(labels, 0);
|
|
46
|
+
}
|
|
47
|
+
getLabels(semaphoreId, additionalLabels = {}) {
|
|
48
|
+
return {
|
|
49
|
+
...this.customLabels,
|
|
50
|
+
semaphore_id: semaphoreId,
|
|
51
|
+
...additionalLabels,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Record the outcome of an acquire attempt and the time spent waiting
|
|
56
|
+
*/
|
|
57
|
+
recordAcquire(params) {
|
|
58
|
+
const labels = this.getLabels(params.id, {
|
|
59
|
+
class: params.class ?? '',
|
|
60
|
+
result: params.result,
|
|
61
|
+
});
|
|
62
|
+
this.acquireWaitHistogram.observe(labels, params.waitMs / 1000);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Record a lease release with its outcome and hold duration
|
|
66
|
+
*/
|
|
67
|
+
recordRelease(params) {
|
|
68
|
+
const labels = this.getLabels(params.id, {
|
|
69
|
+
class: params.class ?? '',
|
|
70
|
+
outcome: params.outcome,
|
|
71
|
+
});
|
|
72
|
+
this.holdDurationHistogram.observe(labels, params.heldMs / 1000);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Record a change of the cached fleet-wide limit
|
|
76
|
+
*/
|
|
77
|
+
recordLimitChange(params) {
|
|
78
|
+
const labels = this.getLabels(params.id);
|
|
79
|
+
this.limitGauge.set(labels, params.limit);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Record a caller-reported throttle event
|
|
83
|
+
*/
|
|
84
|
+
recordThrottle(params) {
|
|
85
|
+
const labels = this.getLabels(params.id);
|
|
86
|
+
this.throttleEventsCounter.inc(labels, 1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=prometheus-semaphore-metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prometheus-semaphore-metrics.js","sourceRoot":"","sources":["../src/prometheus-semaphore-metrics.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenvark/prom",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Prometheus metrics for Zenvark Circuit Breaker",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"zenvark",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"rimraf": "^6.0.1",
|
|
55
55
|
"typescript": "5.9.3",
|
|
56
56
|
"vitest": "^4.0.15",
|
|
57
|
-
"zenvark": "^1.
|
|
57
|
+
"zenvark": "^1.3.0"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"prom-client": "^15.0.0",
|
|
61
|
-
"zenvark": "^1.
|
|
61
|
+
"zenvark": "^1.2.0"
|
|
62
62
|
}
|
|
63
63
|
}
|