@lokalise/prisma-utils 3.2.0 → 3.2.1
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.
|
@@ -5,7 +5,7 @@ export type PrometheusMetricsDefinitions = {
|
|
|
5
5
|
counters: Record<string, prometheus.Counter<'prisma' | 'connection-pool'>>;
|
|
6
6
|
gauges: Record<string, prometheus.Gauge<'prisma' | 'connection-pool'>>;
|
|
7
7
|
histograms: Record<string, prometheus.Histogram<'prisma' | 'connection-pool'>>;
|
|
8
|
-
|
|
8
|
+
keys: string[];
|
|
9
9
|
};
|
|
10
10
|
export type MetricCollectorOptions = {
|
|
11
11
|
metricsPrefix: string;
|
|
@@ -15,17 +15,22 @@ export declare class MetricsCollector {
|
|
|
15
15
|
private readonly options;
|
|
16
16
|
private readonly registry;
|
|
17
17
|
private readonly logger;
|
|
18
|
-
private metrics
|
|
18
|
+
private metrics;
|
|
19
19
|
constructor(prisma: PrismaClient, options: MetricCollectorOptions, registry: prometheus.Registry, logger: FastifyBaseLogger);
|
|
20
20
|
/**
|
|
21
|
-
* Updates metrics for prisma
|
|
21
|
+
* Updates metrics for prisma.
|
|
22
|
+
* If metric was not registered before it will be registered here.
|
|
22
23
|
*/
|
|
23
|
-
collect(): Promise<void>;
|
|
24
|
+
collect(prefix: string): Promise<void>;
|
|
25
|
+
private registerNewMetrics;
|
|
24
26
|
/**
|
|
25
27
|
* Stops the metrics collection and cleans up resources
|
|
26
28
|
*/
|
|
27
29
|
dispose(): Promise<void>;
|
|
28
30
|
private registerMetrics;
|
|
31
|
+
/**
|
|
32
|
+
* If metrics are already registered, we just return them to avoid triggering a Prometheus error.
|
|
33
|
+
*/
|
|
29
34
|
private getRegisteredMetrics;
|
|
30
35
|
private getJsonMetrics;
|
|
31
36
|
}
|
|
@@ -8,7 +8,7 @@ function registerMetrics(_prefix, jsonMetrics) {
|
|
|
8
8
|
counters: {},
|
|
9
9
|
gauges: {},
|
|
10
10
|
histograms: {},
|
|
11
|
-
|
|
11
|
+
keys: [],
|
|
12
12
|
};
|
|
13
13
|
for (const metric of jsonMetrics.counters) {
|
|
14
14
|
metrics.counters[metric.key] = new prometheus.Counter({
|
|
@@ -16,7 +16,7 @@ function registerMetrics(_prefix, jsonMetrics) {
|
|
|
16
16
|
help: metric.description,
|
|
17
17
|
labelNames: ['prisma', 'connection_pool'],
|
|
18
18
|
});
|
|
19
|
-
metrics.
|
|
19
|
+
metrics.keys.push(metric.key);
|
|
20
20
|
}
|
|
21
21
|
for (const metric of jsonMetrics.gauges) {
|
|
22
22
|
metrics.gauges[metric.key] = new prometheus.Gauge({
|
|
@@ -24,7 +24,7 @@ function registerMetrics(_prefix, jsonMetrics) {
|
|
|
24
24
|
help: metric.description,
|
|
25
25
|
labelNames: ['prisma', 'connection_pool'],
|
|
26
26
|
});
|
|
27
|
-
metrics.
|
|
27
|
+
metrics.keys.push(metric.key);
|
|
28
28
|
}
|
|
29
29
|
for (const metric of jsonMetrics.histograms) {
|
|
30
30
|
metrics.histograms[metric.key] = new prometheus.Histogram({
|
|
@@ -33,7 +33,7 @@ function registerMetrics(_prefix, jsonMetrics) {
|
|
|
33
33
|
buckets: metric.value.buckets.filter((bucket) => bucket[1] === 0).map((bucket) => bucket[0]),
|
|
34
34
|
labelNames: ['prisma', 'connection_pool'],
|
|
35
35
|
});
|
|
36
|
-
metrics.
|
|
36
|
+
metrics.keys.push(metric.key);
|
|
37
37
|
}
|
|
38
38
|
return metrics;
|
|
39
39
|
}
|
|
@@ -55,30 +55,62 @@ class MetricsCollector {
|
|
|
55
55
|
this.options = options;
|
|
56
56
|
this.registry = registry;
|
|
57
57
|
this.logger = logger;
|
|
58
|
+
this.metrics = {
|
|
59
|
+
counters: {},
|
|
60
|
+
gauges: {},
|
|
61
|
+
histograms: {},
|
|
62
|
+
keys: [],
|
|
63
|
+
};
|
|
58
64
|
this.registerMetrics(this.registry, this.options).then((result) => {
|
|
59
65
|
this.metrics = result;
|
|
66
|
+
this.logger.debug({}, `Prisma metrics registered ${result.keys}`);
|
|
60
67
|
});
|
|
61
68
|
}
|
|
62
69
|
/**
|
|
63
|
-
* Updates metrics for prisma
|
|
70
|
+
* Updates metrics for prisma.
|
|
71
|
+
* If metric was not registered before it will be registered here.
|
|
64
72
|
*/
|
|
65
|
-
async collect() {
|
|
66
|
-
if (!this.metrics) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
73
|
+
async collect(prefix) {
|
|
69
74
|
try {
|
|
75
|
+
const nonRegisteredMetrics = {
|
|
76
|
+
counters: [],
|
|
77
|
+
gauges: [],
|
|
78
|
+
histograms: [],
|
|
79
|
+
};
|
|
70
80
|
const jsonMetrics = await this.getJsonMetrics();
|
|
71
81
|
for (const counterMetric of jsonMetrics.counters) {
|
|
82
|
+
const existingMetric = this.metrics.counters[counterMetric.key];
|
|
83
|
+
/* c8 ignore start */
|
|
84
|
+
if (!existingMetric) {
|
|
85
|
+
nonRegisteredMetrics.counters.push(counterMetric);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
/* c8 ignore stop */
|
|
72
89
|
// we need to reset counter since prisma returns already the accumulated counter value
|
|
73
|
-
|
|
74
|
-
|
|
90
|
+
existingMetric.reset();
|
|
91
|
+
existingMetric.inc(counterMetric.value);
|
|
75
92
|
}
|
|
76
93
|
for (const gaugeMetric of jsonMetrics.gauges) {
|
|
77
|
-
this.metrics.gauges[gaugeMetric.key]
|
|
94
|
+
const existingMetric = this.metrics.gauges[gaugeMetric.key];
|
|
95
|
+
/* c8 ignore start */
|
|
96
|
+
if (!existingMetric) {
|
|
97
|
+
nonRegisteredMetrics.gauges.push(gaugeMetric);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
/* c8 ignore stop */
|
|
101
|
+
existingMetric.set(gaugeMetric.value);
|
|
78
102
|
}
|
|
79
103
|
for (const histogramMetric of jsonMetrics.histograms) {
|
|
80
|
-
this.metrics.histograms[histogramMetric.key]
|
|
104
|
+
const existingMetric = this.metrics.histograms[histogramMetric.key];
|
|
105
|
+
/* c8 ignore start */
|
|
106
|
+
if (!existingMetric) {
|
|
107
|
+
nonRegisteredMetrics.histograms.push(histogramMetric);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
/* c8 ignore stop */
|
|
111
|
+
existingMetric.observe(histogramMetric.value.count);
|
|
81
112
|
}
|
|
113
|
+
this.registerNewMetrics(prefix, nonRegisteredMetrics);
|
|
82
114
|
}
|
|
83
115
|
catch (err) {
|
|
84
116
|
/* c8 ignore start */
|
|
@@ -86,6 +118,26 @@ class MetricsCollector {
|
|
|
86
118
|
}
|
|
87
119
|
/* c8 ignore stop */
|
|
88
120
|
}
|
|
121
|
+
registerNewMetrics(prefix, nonRegisteredMetrics) {
|
|
122
|
+
if (!nonRegisteredMetrics.counters.length &&
|
|
123
|
+
!nonRegisteredMetrics.gauges.length &&
|
|
124
|
+
!nonRegisteredMetrics.histograms.length) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
/* c8 ignore start */
|
|
128
|
+
const newMetrics = registerMetrics(prefix, nonRegisteredMetrics);
|
|
129
|
+
for (const [key, value] of Object.entries(newMetrics.counters)) {
|
|
130
|
+
this.metrics.counters[key] = value;
|
|
131
|
+
}
|
|
132
|
+
for (const [key, value] of Object.entries(newMetrics.gauges)) {
|
|
133
|
+
this.metrics.gauges[key] = value;
|
|
134
|
+
}
|
|
135
|
+
for (const [key, value] of Object.entries(newMetrics.histograms)) {
|
|
136
|
+
this.metrics.histograms[key] = value;
|
|
137
|
+
}
|
|
138
|
+
this.logger.debug({}, `Prisma metrics registered ${newMetrics.keys}`);
|
|
139
|
+
/* c8 ignore stop */
|
|
140
|
+
}
|
|
89
141
|
/**
|
|
90
142
|
* Stops the metrics collection and cleans up resources
|
|
91
143
|
*/
|
|
@@ -93,7 +145,6 @@ class MetricsCollector {
|
|
|
93
145
|
async registerMetrics(registry, { metricsPrefix }) {
|
|
94
146
|
const jsonMetrics = await this.getJsonMetrics();
|
|
95
147
|
const metricNames = getMetricKeys(metricsPrefix, jsonMetrics);
|
|
96
|
-
// If metrics are already registered, just return them to avoid triggering a Prometheus error
|
|
97
148
|
const existingMetrics = this.getRegisteredMetrics(registry, metricNames);
|
|
98
149
|
if (existingMetrics) {
|
|
99
150
|
/* c8 ignore start */
|
|
@@ -102,8 +153,10 @@ class MetricsCollector {
|
|
|
102
153
|
/* c8 ignore stop */
|
|
103
154
|
return registerMetrics(metricsPrefix, jsonMetrics);
|
|
104
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* If metrics are already registered, we just return them to avoid triggering a Prometheus error.
|
|
158
|
+
*/
|
|
105
159
|
getRegisteredMetrics(registry, metricNames) {
|
|
106
|
-
// If metrics are already registered, just return them to avoid triggering a Prometheus error
|
|
107
160
|
if (!metricNames.length || !registry.getSingleMetric(metricNames[0])) {
|
|
108
161
|
return;
|
|
109
162
|
}
|
|
@@ -20,7 +20,7 @@ function plugin(fastify, pluginOptions, next) {
|
|
|
20
20
|
};
|
|
21
21
|
try {
|
|
22
22
|
const collector = new MetricsCollector_1.MetricsCollector(options.prisma, options, fastify.metrics.client.register, fastify.log);
|
|
23
|
-
const collectFn = async () => await collector.collect();
|
|
23
|
+
const collectFn = async () => await collector.collect(options.metricsPrefix);
|
|
24
24
|
let scheduler;
|
|
25
25
|
if (options.collectionOptions.type === 'interval') {
|
|
26
26
|
scheduler = new CollectionScheduler_1.PromiseBasedCollectionScheduler(options.collectionOptions.intervalInMs, collectFn);
|
|
@@ -37,14 +37,14 @@ function plugin(fastify, pluginOptions, next) {
|
|
|
37
37
|
collect: collectFn,
|
|
38
38
|
});
|
|
39
39
|
next();
|
|
40
|
+
/* c8 ignore start */
|
|
40
41
|
}
|
|
41
42
|
catch (err) {
|
|
42
|
-
/* c8 ignore start */
|
|
43
43
|
return next(err instanceof Error
|
|
44
44
|
? err
|
|
45
45
|
: new Error('Unknown error in prisma-metrics-plugin', { cause: err }));
|
|
46
|
-
/* c8 ignore stop */
|
|
47
46
|
}
|
|
47
|
+
/* c8 ignore stop */
|
|
48
48
|
}
|
|
49
49
|
exports.prismaMetricsPlugin = (0, fastify_plugin_1.default)(plugin, {
|
|
50
50
|
fastify: '5.x',
|