@@ -332,13 +332,14 @@ createDistribution name store = do
332
332
-- function.
333
333
334
334
#if MIN_VERSION_base(4,10,0)
335
- -- | Convert nanoseconds to milliseconds.
336
- nsToMs :: Int64 -> Int64
337
- nsToMs s = round (realToFrac s / (1000000.0 :: Double ))
338
335
#else
339
336
-- | Convert seconds to milliseconds.
340
337
sToMs :: Double -> Int64
341
338
sToMs s = round (s * 1000.0 )
339
+
340
+ -- | Convert seconds to nanoseconds.
341
+ sToNs :: Double -> Int64
342
+ sToNs s = round (s * 1000000000.0 )
342
343
#endif
343
344
344
345
-- | Register a number of metrics related to garbage collector
@@ -355,121 +356,125 @@ sToMs s = round (s * 1000.0)
355
356
-- The runtime overhead of @-T@ is very small so it's safe to always
356
357
-- leave it enabled.
357
358
--
358
- -- Registered counters:
359
- --
360
- -- [@rts.gc.bytes_allocated@] Total number of bytes allocated
361
- --
362
- -- [@rts.gc.num_gcs@] Number of garbage collections performed
363
- --
364
- -- [@rts.gc.num_bytes_usage_samples@] Number of byte usage samples taken
365
- --
366
- -- [@rts.gc.cumulative_bytes_used@] Sum of all byte usage samples, can be
367
- -- used with @numByteUsageSamples@ to calculate averages with
368
- -- arbitrary weighting (if you are sampling this record multiple
369
- -- times).
370
- --
371
- -- [@rts.gc.bytes_copied@] Number of bytes copied during GC
372
- --
373
- -- [@rts.gc.init_cpu_ms@] CPU time used by the init phase, in
374
- -- milliseconds. GHC 8.6+ only.
375
- --
376
- -- [@rts.gc.init_wall_ms@] Wall clock time spent running the init
377
- -- phase, in milliseconds. GHC 8.6+ only.
378
- --
379
- -- [@rts.gc.mutator_cpu_ms@] CPU time spent running mutator threads,
380
- -- in milliseconds. This does not include any profiling overhead or
381
- -- initialization.
382
- --
383
- -- [@rts.gc.mutator_wall_ms@] Wall clock time spent running mutator
384
- -- threads, in milliseconds. This does not include initialization.
385
- --
386
- -- [@rts.gc.gc_cpu_ms@] CPU time spent running GC, in milliseconds.
387
- --
388
- -- [@rts.gc.gc_wall_ms@] Wall clock time spent running GC, in
389
- -- milliseconds.
390
- --
391
- -- [@rts.gc.cpu_ms@] Total CPU time elapsed since program start, in
392
- -- milliseconds.
393
- --
394
- -- [@rts.gc.wall_ms@] Total wall clock time elapsed since start, in
395
- -- milliseconds.
396
- --
397
- -- Registered gauges:
398
- --
399
- -- [@rts.gc.max_bytes_used@] Maximum number of live bytes seen so far
400
- --
401
- -- [@rts.gc.current_bytes_used@] Current number of live bytes
402
- --
403
- -- [@rts.gc.current_bytes_slop@] Current number of bytes lost to slop
404
- --
405
- -- [@rts.gc.max_bytes_slop@] Maximum number of bytes lost to slop at any one time so far
406
- --
407
- -- [@rts.gc.peak_megabytes_allocated@] Maximum number of megabytes allocated
408
- --
409
- -- [@rts.gc.par_tot_bytes_copied@] Number of bytes copied during GC, minus
410
- -- space held by mutable lists held by the capabilities. Can be used
411
- -- with 'parMaxBytesCopied' to determine how well parallel GC utilized
412
- -- all cores.
413
- --
414
- -- [@rts.gc.par_avg_bytes_copied@] Deprecated alias for
415
- -- @par_tot_bytes_copied@.
416
- --
417
- -- [@rts.gc.par_max_bytes_copied@] Sum of number of bytes copied each GC by
418
- -- the most active GC thread each GC. The ratio of
419
- -- @par_tot_bytes_copied@ divided by @par_max_bytes_copied@ approaches
420
- -- 1 for a maximally sequential run and approaches the number of
421
- -- threads (set by the RTS flag @-N@) for a maximally parallel run.
359
+ -- Registered counters (see "GHC.Stats" for their meanings:
360
+ --
361
+ -- > rts.gcs
362
+ -- > rts.major_gcs
363
+ -- > rts.allocated_bytes
364
+ -- > rts.max_live_bytes
365
+ -- > rts.max_large_objects_bytes
366
+ -- > rts.max_compact_bytes
367
+ -- > rts.max_slop_bytes
368
+ -- > rts.max_mem_in_use_bytes
369
+ -- > rts.cumulative_live_bytes
370
+ -- > rts.copied_bytes
371
+ -- > rts.par_copied_bytes
372
+ -- > rts.cumulative_par_max_copied_bytes
373
+ -- > rts.cumulative_par_balanced_copied_bytes
374
+ -- > rts.init_cpu_ns
375
+ -- > rts.init_elapsed_ns
376
+ -- > rts.mutator_cpu_ns
377
+ -- > rts.mutator_elapsed_ns
378
+ -- > rts.gc_cpu_ns
379
+ -- > rts.gc_elapsed_ns
380
+ -- > rts.cpu_ns
381
+ -- > rts.elapsed_ns
382
+ -- > rts.gc.gen
383
+ -- > rts.gc.threads
384
+ -- > rts.gc.allocated_bytes
385
+ -- > rts.gc.live_bytes
386
+ -- > rts.gc.large_objects_bytes
387
+ -- > rts.gc.compact_bytes
388
+ -- > rts.gc.slop_bytes
389
+ -- > rts.gc.mem_in_use_bytes
390
+ -- > rts.gc.copied_bytes
391
+ -- > rts.gc.par_max_copied_bytes
392
+ -- > rts.gc.sync_elapsed_ns
393
+ -- > rts.gc.cpu_ns
394
+ -- > rts.gc.elapsed_ns
422
395
registerGcMetrics :: Store -> IO ()
423
396
registerGcMetrics store =
424
397
registerGroup
425
398
#if MIN_VERSION_base(4,10,0)
426
399
(M. fromList
427
- [ (" rts.gc.bytes_allocated" , Counter . fromIntegral . Stats. allocated_bytes)
428
- , (" rts.gc.num_gcs" , Counter . fromIntegral . Stats. gcs)
429
- , (" rts.gc.num_bytes_usage_samples" , Counter . fromIntegral . Stats. major_gcs)
430
- , (" rts.gc.cumulative_bytes_used" , Counter . fromIntegral . Stats. cumulative_live_bytes)
431
- , (" rts.gc.bytes_copied" , Counter . fromIntegral . Stats. copied_bytes)
400
+ -- We order them the same way as they are in GHC.Stats for easy comparison.
401
+ [ (" rts.gcs" , Counter . fromIntegral . Stats. gcs)
402
+ , (" rts.major_gcs" , Counter . fromIntegral . Stats. major_gcs)
403
+ , (" rts.allocated_bytes" , Counter . fromIntegral . Stats. allocated_bytes)
404
+ , (" rts.max_live_bytes" , Gauge . fromIntegral . Stats. max_live_bytes)
405
+ , (" rts.max_large_objects_bytes" , Gauge . fromIntegral . Stats. max_large_objects_bytes)
406
+ , (" rts.max_compact_bytes" , Gauge . fromIntegral . Stats. max_compact_bytes)
407
+ , (" rts.max_slop_bytes" , Gauge . fromIntegral . Stats. max_slop_bytes)
408
+ , (" rts.max_mem_in_use_bytes" , Gauge . fromIntegral . Stats. max_mem_in_use_bytes)
409
+ , (" rts.cumulative_live_bytes" , Counter . fromIntegral . Stats. cumulative_live_bytes)
410
+ , (" rts.copied_bytes" , Counter . fromIntegral . Stats. copied_bytes)
411
+ , (" rts.par_copied_bytes" , Gauge . fromIntegral . Stats. par_copied_bytes)
412
+ , (" rts.cumulative_par_max_copied_bytes" , Gauge . fromIntegral . Stats. cumulative_par_max_copied_bytes)
413
+ #if MIN_VERSION_base(4,11,0)
414
+ , (" rts.cumulative_par_balanced_copied_bytes" , Gauge . fromIntegral . Stats. cumulative_par_balanced_copied_bytes)
415
+ #endif
432
416
#if MIN_VERSION_base(4,12,0)
433
- , (" rts.gc.init_cpu_ms " , Counter . nsToMs . Stats. init_cpu_ns)
434
- , (" rts.gc.init_wall_ms " , Counter . nsToMs . Stats. init_elapsed_ns)
417
+ , (" rts.init_cpu_ns " , Counter . Stats. init_cpu_ns)
418
+ , (" rts.init_elapsed_ns " , Counter . Stats. init_elapsed_ns)
435
419
#endif
436
- , (" rts.gc.mutator_cpu_ms" , Counter . nsToMs . Stats. mutator_cpu_ns)
437
- , (" rts.gc.mutator_wall_ms" , Counter . nsToMs . Stats. mutator_elapsed_ns)
438
- , (" rts.gc.gc_cpu_ms" , Counter . nsToMs . Stats. gc_cpu_ns)
439
- , (" rts.gc.gc_wall_ms" , Counter . nsToMs . Stats. gc_elapsed_ns)
440
- , (" rts.gc.cpu_ms" , Counter . nsToMs . Stats. cpu_ns)
441
- , (" rts.gc.wall_ms" , Counter . nsToMs . Stats. elapsed_ns)
442
- , (" rts.gc.max_bytes_used" , Gauge . fromIntegral . Stats. max_live_bytes)
443
- , (" rts.gc.current_bytes_used" , Gauge . fromIntegral . Stats. gcdetails_live_bytes . Stats. gc)
444
- , (" rts.gc.current_bytes_slop" , Gauge . fromIntegral . Stats. gcdetails_slop_bytes . Stats. gc)
445
- , (" rts.gc.max_bytes_slop" , Gauge . fromIntegral . Stats. max_slop_bytes)
446
- , (" rts.gc.peak_megabytes_allocated" , Gauge . fromIntegral . (`quot` (1024 * 1024 )) . Stats. max_mem_in_use_bytes)
447
- , (" rts.gc.par_tot_bytes_copied" , Gauge . fromIntegral . Stats. par_copied_bytes)
448
- , (" rts.gc.par_avg_bytes_copied" , Gauge . fromIntegral . Stats. par_copied_bytes)
449
- , (" rts.gc.par_max_bytes_copied" , Gauge . fromIntegral . Stats. cumulative_par_max_copied_bytes)
420
+ , (" rts.mutator_cpu_ns" , Counter . Stats. mutator_cpu_ns)
421
+ , (" rts.mutator_elapsed_ns" , Counter . Stats. mutator_elapsed_ns)
422
+ , (" rts.gc_cpu_ns" , Counter . Stats. gc_cpu_ns)
423
+ , (" rts.gc_elapsed_ns" , Counter . Stats. gc_elapsed_ns)
424
+ , (" rts.cpu_ns" , Counter . Stats. cpu_ns)
425
+ , (" rts.elapsed_ns" , Counter . Stats. elapsed_ns)
426
+ -- GCDetails
427
+ , (" rts.gc.gen" , Gauge . fromIntegral . Stats. gcdetails_gen . Stats. gc)
428
+ , (" rts.gc.threads" , Gauge . fromIntegral . Stats. gcdetails_threads . Stats. gc)
429
+ , (" rts.gc.allocated_bytes" , Gauge . fromIntegral . Stats. gcdetails_allocated_bytes . Stats. gc)
430
+ , (" rts.gc.live_bytes" , Gauge . fromIntegral . Stats. gcdetails_live_bytes . Stats. gc)
431
+ , (" rts.gc.large_objects_bytes" , Gauge . fromIntegral . Stats. gcdetails_large_objects_bytes . Stats. gc)
432
+ , (" rts.gc.compact_bytes" , Gauge . fromIntegral . Stats. gcdetails_compact_bytes . Stats. gc)
433
+ , (" rts.gc.slop_bytes" , Gauge . fromIntegral . Stats. gcdetails_slop_bytes . Stats. gc)
434
+ , (" rts.gc.mem_in_use_bytes" , Gauge . fromIntegral . Stats. gcdetails_mem_in_use_bytes . Stats. gc)
435
+ , (" rts.gc.copied_bytes" , Gauge . fromIntegral . Stats. gcdetails_copied_bytes . Stats. gc)
436
+ , (" rts.gc.par_max_copied_bytes" , Gauge . fromIntegral . Stats. gcdetails_par_max_copied_bytes . Stats. gc)
437
+ , (" rts.gc.sync_elapsed_ns" , Gauge . fromIntegral . Stats. gcdetails_sync_elapsed_ns . Stats. gc)
438
+ , (" rts.gc.cpu_ns" , Gauge . fromIntegral . Stats. gcdetails_cpu_ns . Stats. gc)
439
+ , (" rts.gc.elapsed_ns" , Gauge . fromIntegral . Stats. gcdetails_elapsed_ns . Stats. gc)
450
440
])
451
441
getRTSStats
452
442
#else
443
+ -- For pre-base-4.10 we translate the names from before GHC commit
444
+ -- 24e6594cc7890babe69b8ba122d171affabad2d1 to their newer equivalents
445
+ -- so that ekg-core always presents the same names (given that e.g.
446
+ -- the ekg Javascript expects them to exist).
447
+ -- The mapping is obtained obtained from
448
+ -- https://hackage.haskell.org/package/base-4.10.0.0/docs/GHC-Stats.html
449
+ -- which has both the old and the new interface, as well as from
450
+ -- the commit diff implementation in `Stats.c`.
453
451
(M. fromList
454
- [ (" rts.gc.bytes_allocated" , Counter . Stats. bytesAllocated)
455
- , (" rts.gc.num_gcs" , Counter . Stats. numGcs)
456
- , (" rts.gc.num_bytes_usage_samples" , Counter . Stats. numByteUsageSamples)
457
- , (" rts.gc.cumulative_bytes_used" , Counter . Stats. cumulativeBytesUsed)
458
- , (" rts.gc.bytes_copied" , Counter . Stats. bytesCopied)
459
- , (" rts.gc.mutator_cpu_ms" , Counter . sToMs . Stats. mutatorCpuSeconds)
460
- , (" rts.gc.mutator_wall_ms" , Counter . sToMs . Stats. mutatorWallSeconds)
461
- , (" rts.gc.gc_cpu_ms" , Counter . sToMs . Stats. gcCpuSeconds)
462
- , (" rts.gc.gc_wall_ms" , Counter . sToMs . Stats. gcWallSeconds)
463
- , (" rts.gc.cpu_ms" , Counter . sToMs . Stats. cpuSeconds)
464
- , (" rts.gc.wall_ms" , Counter . sToMs . Stats. wallSeconds)
465
- , (" rts.gc.max_bytes_used" , Gauge . Stats. maxBytesUsed)
466
- , (" rts.gc.current_bytes_used" , Gauge . Stats. currentBytesUsed)
467
- , (" rts.gc.current_bytes_slop" , Gauge . Stats. currentBytesSlop)
468
- , (" rts.gc.max_bytes_slop" , Gauge . Stats. maxBytesSlop)
469
- , (" rts.gc.peak_megabytes_allocated" , Gauge . Stats. peakMegabytesAllocated)
470
- , (" rts.gc.par_tot_bytes_copied" , Gauge . gcParTotBytesCopied)
471
- , (" rts.gc.par_avg_bytes_copied" , Gauge . gcParTotBytesCopied)
472
- , (" rts.gc.par_max_bytes_copied" , Gauge . Stats. parMaxBytesCopied)
452
+ [ (" rts.allocated_bytes" , Counter . Stats. bytesAllocated)
453
+ , (" rts.gcs" , Counter . Stats. numGcs)
454
+ , (" rts.major_gcs" , Counter . Stats. numByteUsageSamples)
455
+ , (" rts.cumulative_live_bytes" , Counter . Stats. cumulativeBytesUsed)
456
+ , (" rts.copied_bytes" , Counter . Stats. bytesCopied)
457
+ , (" rts.mutator_cpu_ns" , Counter . sToNs . Stats. mutatorCpuSeconds)
458
+ , (" rts.mutator_elapsed_ns" , Counter . sToNs . Stats. mutatorWallSeconds)
459
+ , (" rts.gc_cpu_ns" , Counter . sToNs . Stats. gcCpuSeconds)
460
+ , (" rts.gc_elapsed_ns" , Counter . sToNs . Stats. gcWallSeconds)
461
+ , (" rts.cpu_ns" , Counter . sToNs . Stats. cpuSeconds)
462
+ , (" rts.elapsed_ns" , Counter . sToNs . Stats. wallSeconds)
463
+ , (" rts.max_live_bytes" , Gauge . Stats. maxBytesUsed)
464
+ , (" rts.gc.live_bytes" , Gauge . Stats. currentBytesUsed)
465
+ , (" rts.gc.slop_bytes" , Gauge . Stats. currentBytesSlop)
466
+ , (" rts.max_slop_bytes" , Gauge . Stats. maxBytesSlop)
467
+ , (" rts.max_mem_in_use_bytes" , Gauge . Stats. peakMegabytesAllocated)
468
+ -- Note that historically, the values
469
+ -- par_tot_bytes_copied were both
470
+ -- par_avg_bytes_copied
471
+ -- were both taken from
472
+ -- gcParTotBytesCopied
473
+ -- after `parAvgBytesCopied` was renamed to `gcParTotBytesCopied`;
474
+ -- see `ekg` commit
475
+ -- 27467a61 - parAvgBytesCopied was renamed in GHC 7.6.1
476
+ , (" rts.par_copied_bytes" , Gauge . gcParTotBytesCopied)
477
+ , (" rts.gc.par_max_copied_bytes" , Gauge . Stats. parMaxBytesCopied)
473
478
])
474
479
getGcStats
475
480
#endif
0 commit comments