@@ -200,18 +200,17 @@ struct PrometheusMetric<Value: fmt::Display> {
200
200
201
201
impl < Value : fmt:: Display > fmt:: Display for PrometheusMetric < Value > {
202
202
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
203
- let formatted_labels = self
204
- . labels
203
+ let mut sorted_labels: Vec < _ > = self . labels . iter ( ) . collect ( ) ;
204
+ sorted_labels. sort_by_key ( |& ( key, _) | key) ;
205
+ let formatted_labels = sorted_labels
205
206
. iter ( )
206
207
. map ( |( key, value) | format ! ( "{}=\" {}\" " , key, value) )
207
208
. collect :: < Vec < _ > > ( )
208
209
. join ( "," ) ;
209
210
write ! (
210
211
f,
211
- "# HELP {name} {help} \n # TYPE {name} {ty} \n {name}{{{ formatted_labels}}} {value}\n " ,
212
+ "{name}{{{ formatted_labels}}} {value}" ,
212
213
name = format_args!( "pgcat_{}" , self . name) ,
213
- help = self . help,
214
- ty = self . ty,
215
214
formatted_labels = formatted_labels,
216
215
value = self . value
217
216
)
@@ -247,7 +246,7 @@ impl<Value: fmt::Display> PrometheusMetric<Value> {
247
246
labels. insert ( "pool" , address. pool_name . clone ( ) ) ;
248
247
labels. insert ( "index" , address. address_index . to_string ( ) ) ;
249
248
labels. insert ( "database" , address. database . to_string ( ) ) ;
250
- labels. insert ( "user " , address. username . clone ( ) ) ;
249
+ labels. insert ( "username " , address. username . clone ( ) ) ;
251
250
252
251
Self :: from_name ( & format ! ( "databases_{}" , name) , value, labels)
253
252
}
@@ -264,7 +263,8 @@ impl<Value: fmt::Display> PrometheusMetric<Value> {
264
263
labels. insert ( "pool" , address. pool_name . clone ( ) ) ;
265
264
labels. insert ( "index" , address. address_index . to_string ( ) ) ;
266
265
labels. insert ( "database" , address. database . to_string ( ) ) ;
267
- labels. insert ( "user" , address. username . clone ( ) ) ;
266
+ labels. insert ( "username" , address. username . clone ( ) ) ;
267
+
268
268
Self :: from_name ( & format ! ( "servers_{}" , name) , value, labels)
269
269
}
270
270
@@ -276,7 +276,7 @@ impl<Value: fmt::Display> PrometheusMetric<Value> {
276
276
labels. insert ( "role" , address. role . to_string ( ) ) ;
277
277
labels. insert ( "index" , address. address_index . to_string ( ) ) ;
278
278
labels. insert ( "database" , address. database . to_string ( ) ) ;
279
- labels. insert ( "user " , address. username . clone ( ) ) ;
279
+ labels. insert ( "username " , address. username . clone ( ) ) ;
280
280
281
281
Self :: from_name ( & format ! ( "stats_{}" , name) , value, labels)
282
282
}
@@ -288,6 +288,15 @@ impl<Value: fmt::Display> PrometheusMetric<Value> {
288
288
289
289
Self :: from_name ( & format ! ( "pools_{}" , name) , value, labels)
290
290
}
291
+
292
+ fn get_header ( & self ) -> String {
293
+ format ! (
294
+ "\n # HELP {name} {help}\n # TYPE {name} {ty}" ,
295
+ name = format_args!( "pgcat_{}" , self . name) ,
296
+ help = self . help,
297
+ ty = self . ty,
298
+ )
299
+ }
291
300
}
292
301
293
302
async fn prometheus_stats (
@@ -313,6 +322,7 @@ async fn prometheus_stats(
313
322
314
323
// Adds metrics shown in a SHOW STATS admin command.
315
324
fn push_address_stats ( lines : & mut Vec < String > ) {
325
+ let mut grouped_metrics: HashMap < String , Vec < PrometheusMetric < u64 > > > = HashMap :: new ( ) ;
316
326
for ( _, pool) in get_all_pools ( ) {
317
327
for shard in 0 ..pool. shards ( ) {
318
328
for server in 0 ..pool. servers ( shard) {
@@ -322,41 +332,64 @@ fn push_address_stats(lines: &mut Vec<String>) {
322
332
if let Some ( prometheus_metric) =
323
333
PrometheusMetric :: < u64 > :: from_address ( address, & key, value)
324
334
{
325
- lines. push ( prometheus_metric. to_string ( ) ) ;
335
+ grouped_metrics
336
+ . entry ( key)
337
+ . or_default ( )
338
+ . push ( prometheus_metric) ;
326
339
} else {
327
340
debug ! ( "Metric {} not implemented for {}" , key, address. name( ) ) ;
328
341
}
329
342
}
330
343
}
331
344
}
332
345
}
346
+ for ( _key, metrics) in grouped_metrics {
347
+ if !metrics. is_empty ( ) {
348
+ lines. push ( metrics[ 0 ] . get_header ( ) ) ;
349
+ for metric in metrics {
350
+ lines. push ( metric. to_string ( ) ) ;
351
+ }
352
+ }
353
+ }
333
354
}
334
355
335
356
// Adds relevant metrics shown in a SHOW POOLS admin command.
336
357
fn push_pool_stats ( lines : & mut Vec < String > ) {
358
+ let mut grouped_metrics: HashMap < String , Vec < PrometheusMetric < u64 > > > = HashMap :: new ( ) ;
337
359
let pool_stats = PoolStats :: construct_pool_lookup ( ) ;
338
360
for ( pool_id, stats) in pool_stats. iter ( ) {
339
361
for ( name, value) in stats. clone ( ) {
340
362
if let Some ( prometheus_metric) =
341
363
PrometheusMetric :: < u64 > :: from_pool ( pool_id. clone ( ) , & name, value)
342
364
{
343
- lines. push ( prometheus_metric. to_string ( ) ) ;
365
+ grouped_metrics
366
+ . entry ( name)
367
+ . or_default ( )
368
+ . push ( prometheus_metric) ;
344
369
} else {
345
370
debug ! ( "Metric {} not implemented for ({})" , name, * pool_id) ;
346
371
}
347
372
}
348
373
}
374
+ for ( _key, metrics) in grouped_metrics {
375
+ if !metrics. is_empty ( ) {
376
+ lines. push ( metrics[ 0 ] . get_header ( ) ) ;
377
+ for metric in metrics {
378
+ lines. push ( metric. to_string ( ) ) ;
379
+ }
380
+ }
381
+ }
349
382
}
350
383
351
384
// Adds relevant metrics shown in a SHOW DATABASES admin command.
352
385
fn push_database_stats ( lines : & mut Vec < String > ) {
386
+ let mut grouped_metrics: HashMap < String , Vec < PrometheusMetric < u32 > > > = HashMap :: new ( ) ;
353
387
for ( _, pool) in get_all_pools ( ) {
354
388
let pool_config = pool. settings . clone ( ) ;
355
389
for shard in 0 ..pool. shards ( ) {
356
390
for server in 0 ..pool. servers ( shard) {
357
391
let address = pool. address ( shard, server) ;
358
392
let pool_state = pool. pool_state ( shard, server) ;
359
-
360
393
let metrics = vec ! [
361
394
( "pool_size" , pool_config. user. pool_size) ,
362
395
( "current_connections" , pool_state. connections) ,
@@ -365,14 +398,25 @@ fn push_database_stats(lines: &mut Vec<String>) {
365
398
if let Some ( prometheus_metric) =
366
399
PrometheusMetric :: < u32 > :: from_database_info ( address, key, value)
367
400
{
368
- lines. push ( prometheus_metric. to_string ( ) ) ;
401
+ grouped_metrics
402
+ . entry ( key. to_string ( ) )
403
+ . or_default ( )
404
+ . push ( prometheus_metric) ;
369
405
} else {
370
406
debug ! ( "Metric {} not implemented for {}" , key, address. name( ) ) ;
371
407
}
372
408
}
373
409
}
374
410
}
375
411
}
412
+ for ( _key, metrics) in grouped_metrics {
413
+ if !metrics. is_empty ( ) {
414
+ lines. push ( metrics[ 0 ] . get_header ( ) ) ;
415
+ for metric in metrics {
416
+ lines. push ( metric. to_string ( ) ) ;
417
+ }
418
+ }
419
+ }
376
420
}
377
421
378
422
// Adds relevant metrics shown in a SHOW SERVERS admin command.
@@ -405,7 +449,7 @@ fn push_server_stats(lines: &mut Vec<String>) {
405
449
crate :: stats:: ServerState :: Idle => entry. idle_count += 1 ,
406
450
}
407
451
}
408
-
452
+ let mut grouped_metrics : HashMap < String , Vec < PrometheusMetric < u64 > > > = HashMap :: new ( ) ;
409
453
for ( _, pool) in get_all_pools ( ) {
410
454
for shard in 0 ..pool. shards ( ) {
411
455
for server in 0 ..pool. servers ( shard) {
@@ -428,7 +472,10 @@ fn push_server_stats(lines: &mut Vec<String>) {
428
472
if let Some ( prometheus_metric) =
429
473
PrometheusMetric :: < u64 > :: from_server_info ( address, key, value)
430
474
{
431
- lines. push ( prometheus_metric. to_string ( ) ) ;
475
+ grouped_metrics
476
+ . entry ( key. to_string ( ) )
477
+ . or_default ( )
478
+ . push ( prometheus_metric) ;
432
479
} else {
433
480
debug ! ( "Metric {} not implemented for {}" , key, address. name( ) ) ;
434
481
}
@@ -437,6 +484,14 @@ fn push_server_stats(lines: &mut Vec<String>) {
437
484
}
438
485
}
439
486
}
487
+ for ( _key, metrics) in grouped_metrics {
488
+ if !metrics. is_empty ( ) {
489
+ lines. push ( metrics[ 0 ] . get_header ( ) ) ;
490
+ for metric in metrics {
491
+ lines. push ( metric. to_string ( ) ) ;
492
+ }
493
+ }
494
+ }
440
495
}
441
496
442
497
pub async fn start_metric_server ( http_addr : SocketAddr ) {
0 commit comments