@@ -56,6 +56,7 @@ import { logger } from "~/services/logger.server";
56
56
import { flattenAttributes } from "@trigger.dev/core/v3" ;
57
57
import { prisma } from "~/db.server" ;
58
58
import { metricsRegister } from "~/metrics.server" ;
59
+ import type { Prisma } from "@trigger.dev/database" ;
59
60
60
61
export const SEMINTATTRS_FORCE_RECORDING = "forceRecording" ;
61
62
@@ -336,6 +337,33 @@ function setupMetrics() {
336
337
}
337
338
338
339
function configurePrismaMetrics ( { meter } : { meter : Meter } ) {
340
+ // Counters
341
+ const queriesTotal = meter . createObservableCounter ( "db.client.queries.total" , {
342
+ description : "Total number of Prisma Client queries executed" ,
343
+ unit : "queries" ,
344
+ } ) ;
345
+ const datasourceQueriesTotal = meter . createObservableCounter ( "db.datasource.queries.total" , {
346
+ description : "Total number of datasource queries executed" ,
347
+ unit : "queries" ,
348
+ } ) ;
349
+ const connectionsOpenedTotal = meter . createObservableCounter ( "db.pool.connections.opened.total" , {
350
+ description : "Total number of pool connections opened" ,
351
+ unit : "connections" ,
352
+ } ) ;
353
+ const connectionsClosedTotal = meter . createObservableCounter ( "db.pool.connections.closed.total" , {
354
+ description : "Total number of pool connections closed" ,
355
+ unit : "connections" ,
356
+ } ) ;
357
+
358
+ // Gauges
359
+ const queriesActive = meter . createObservableGauge ( "db.client.queries.active" , {
360
+ description : "Number of currently active Prisma Client queries" ,
361
+ unit : "queries" ,
362
+ } ) ;
363
+ const queriesWait = meter . createObservableGauge ( "db.client.queries.wait" , {
364
+ description : "Number of queries currently waiting for a connection" ,
365
+ unit : "queries" ,
366
+ } ) ;
339
367
const totalGauge = meter . createObservableGauge ( "db.pool.connections.total" , {
340
368
description : "Open Prisma-pool connections" ,
341
369
unit : "connections" ,
@@ -349,26 +377,170 @@ function configurePrismaMetrics({ meter }: { meter: Meter }) {
349
377
unit : "connections" ,
350
378
} ) ;
351
379
380
+ // Histogram statistics as gauges
381
+ const queriesWaitTimeCount = meter . createObservableGauge ( "db.client.queries.wait_time.count" , {
382
+ description : "Number of wait time observations" ,
383
+ unit : "observations" ,
384
+ } ) ;
385
+ const queriesWaitTimeSum = meter . createObservableGauge ( "db.client.queries.wait_time.sum" , {
386
+ description : "Total wait time across all observations" ,
387
+ unit : "ms" ,
388
+ } ) ;
389
+ const queriesWaitTimeMean = meter . createObservableGauge ( "db.client.queries.wait_time.mean" , {
390
+ description : "Average wait time for a connection" ,
391
+ unit : "ms" ,
392
+ } ) ;
393
+
394
+ const queriesDurationCount = meter . createObservableGauge ( "db.client.queries.duration.count" , {
395
+ description : "Number of query duration observations" ,
396
+ unit : "observations" ,
397
+ } ) ;
398
+ const queriesDurationSum = meter . createObservableGauge ( "db.client.queries.duration.sum" , {
399
+ description : "Total query duration across all observations" ,
400
+ unit : "ms" ,
401
+ } ) ;
402
+ const queriesDurationMean = meter . createObservableGauge ( "db.client.queries.duration.mean" , {
403
+ description : "Average duration of Prisma Client queries" ,
404
+ unit : "ms" ,
405
+ } ) ;
406
+
407
+ const datasourceQueriesDurationCount = meter . createObservableGauge (
408
+ "db.datasource.queries.duration.count" ,
409
+ {
410
+ description : "Number of datasource query duration observations" ,
411
+ unit : "observations" ,
412
+ }
413
+ ) ;
414
+ const datasourceQueriesDurationSum = meter . createObservableGauge (
415
+ "db.datasource.queries.duration.sum" ,
416
+ {
417
+ description : "Total datasource query duration across all observations" ,
418
+ unit : "ms" ,
419
+ }
420
+ ) ;
421
+ const datasourceQueriesDurationMean = meter . createObservableGauge (
422
+ "db.datasource.queries.duration.mean" ,
423
+ {
424
+ description : "Average duration of datasource queries" ,
425
+ unit : "ms" ,
426
+ }
427
+ ) ;
428
+
352
429
// Single helper so we hit Prisma only once per scrape ---------------------
353
- async function readPoolCounters ( ) {
354
- const { gauges } = await prisma . $metrics . json ( ) ;
430
+ async function readPrismaMetrics ( ) {
431
+ const metrics = await prisma . $metrics . json ( ) ;
432
+
433
+ // Extract counter values
434
+ const counters : Record < string , number > = { } ;
435
+ for ( const counter of metrics . counters ) {
436
+ counters [ counter . key ] = counter . value ;
437
+ }
355
438
356
- const busy = gauges . find ( ( g ) => g . key === "prisma_pool_connections_busy" ) ?. value ?? 0 ;
357
- const free = gauges . find ( ( g ) => g . key === "prisma_pool_connections_idle" ) ?. value ?? 0 ;
358
- const total =
359
- gauges . find ( ( g ) => g . key === "prisma_pool_connections_open" ) ?. value ?? busy + free ; // fallback compute
439
+ // Extract gauge values
440
+ const gauges : Record < string , number > = { } ;
441
+ for ( const gauge of metrics . gauges ) {
442
+ gauges [ gauge . key ] = gauge . value ;
443
+ }
444
+
445
+ // Extract histogram values
446
+ const histograms : Record < string , Prisma . MetricHistogram > = { } ;
447
+ for ( const histogram of metrics . histograms ) {
448
+ histograms [ histogram . key ] = histogram . value ;
449
+ }
360
450
361
- return { total, busy, free } ;
451
+ return {
452
+ counters : {
453
+ queriesTotal : counters [ "prisma_client_queries_total" ] ?? 0 ,
454
+ datasourceQueriesTotal : counters [ "prisma_datasource_queries_total" ] ?? 0 ,
455
+ connectionsOpenedTotal : counters [ "prisma_pool_connections_opened_total" ] ?? 0 ,
456
+ connectionsClosedTotal : counters [ "prisma_pool_connections_closed_total" ] ?? 0 ,
457
+ } ,
458
+ gauges : {
459
+ queriesActive : gauges [ "prisma_client_queries_active" ] ?? 0 ,
460
+ queriesWait : gauges [ "prisma_client_queries_wait" ] ?? 0 ,
461
+ connectionsOpen : gauges [ "prisma_pool_connections_open" ] ?? 0 ,
462
+ connectionsBusy : gauges [ "prisma_pool_connections_busy" ] ?? 0 ,
463
+ connectionsIdle : gauges [ "prisma_pool_connections_idle" ] ?? 0 ,
464
+ } ,
465
+ histograms : {
466
+ queriesWait : histograms [ "prisma_client_queries_wait_histogram_ms" ] ,
467
+ queriesDuration : histograms [ "prisma_client_queries_duration_histogram_ms" ] ,
468
+ datasourceQueriesDuration : histograms [ "prisma_datasource_queries_duration_histogram_ms" ] ,
469
+ } ,
470
+ } ;
362
471
}
363
472
364
473
meter . addBatchObservableCallback (
365
474
async ( res ) => {
366
- const { total, busy, free } = await readPoolCounters ( ) ;
367
- res . observe ( totalGauge , total ) ;
368
- res . observe ( busyGauge , busy ) ;
369
- res . observe ( freeGauge , free ) ;
475
+ const { counters, gauges, histograms } = await readPrismaMetrics ( ) ;
476
+
477
+ // Observe counters
478
+ res . observe ( queriesTotal , counters . queriesTotal ) ;
479
+ res . observe ( datasourceQueriesTotal , counters . datasourceQueriesTotal ) ;
480
+ res . observe ( connectionsOpenedTotal , counters . connectionsOpenedTotal ) ;
481
+ res . observe ( connectionsClosedTotal , counters . connectionsClosedTotal ) ;
482
+
483
+ // Observe gauges
484
+ res . observe ( queriesActive , gauges . queriesActive ) ;
485
+ res . observe ( queriesWait , gauges . queriesWait ) ;
486
+ res . observe ( totalGauge , gauges . connectionsOpen ) ;
487
+ res . observe ( busyGauge , gauges . connectionsBusy ) ;
488
+ res . observe ( freeGauge , gauges . connectionsIdle ) ;
489
+
490
+ // Observe histogram statistics as gauges
491
+ if ( histograms . queriesWait ) {
492
+ res . observe ( queriesWaitTimeCount , histograms . queriesWait . count ) ;
493
+ res . observe ( queriesWaitTimeSum , histograms . queriesWait . sum ) ;
494
+ res . observe (
495
+ queriesWaitTimeMean ,
496
+ histograms . queriesWait . count > 0
497
+ ? histograms . queriesWait . sum / histograms . queriesWait . count
498
+ : 0
499
+ ) ;
500
+ }
501
+
502
+ if ( histograms . queriesDuration ) {
503
+ res . observe ( queriesDurationCount , histograms . queriesDuration . count ) ;
504
+ res . observe ( queriesDurationSum , histograms . queriesDuration . sum ) ;
505
+ res . observe (
506
+ queriesDurationMean ,
507
+ histograms . queriesDuration . count > 0
508
+ ? histograms . queriesDuration . sum / histograms . queriesDuration . count
509
+ : 0
510
+ ) ;
511
+ }
512
+
513
+ if ( histograms . datasourceQueriesDuration ) {
514
+ res . observe ( datasourceQueriesDurationCount , histograms . datasourceQueriesDuration . count ) ;
515
+ res . observe ( datasourceQueriesDurationSum , histograms . datasourceQueriesDuration . sum ) ;
516
+ res . observe (
517
+ datasourceQueriesDurationMean ,
518
+ histograms . datasourceQueriesDuration . count > 0
519
+ ? histograms . datasourceQueriesDuration . sum / histograms . datasourceQueriesDuration . count
520
+ : 0
521
+ ) ;
522
+ }
370
523
} ,
371
- [ totalGauge , busyGauge , freeGauge ]
524
+ [
525
+ queriesTotal ,
526
+ datasourceQueriesTotal ,
527
+ connectionsOpenedTotal ,
528
+ connectionsClosedTotal ,
529
+ queriesActive ,
530
+ queriesWait ,
531
+ totalGauge ,
532
+ busyGauge ,
533
+ freeGauge ,
534
+ queriesWaitTimeCount ,
535
+ queriesWaitTimeSum ,
536
+ queriesWaitTimeMean ,
537
+ queriesDurationCount ,
538
+ queriesDurationSum ,
539
+ queriesDurationMean ,
540
+ datasourceQueriesDurationCount ,
541
+ datasourceQueriesDurationSum ,
542
+ datasourceQueriesDurationMean ,
543
+ ]
372
544
) ;
373
545
}
374
546
0 commit comments