prometheus-metrics-ghc 0.3.0 → 1.0.0
raw patch · 2 files changed
+203/−15 lines, 2 filesdep +textdep ~prometheus-clientnew-uploaderPVP ok
version bump matches the API change (PVP)
Dependencies added: text
Dependency ranges changed: prometheus-client
API changes (from Hackage documentation)
Files
- prometheus-metrics-ghc.cabal +3/−2
- src/Prometheus/Metric/GHC.hs +200/−13
prometheus-metrics-ghc.cabal view
@@ -1,5 +1,5 @@ name: prometheus-metrics-ghc-version: 0.3.0+version: 1.0.0 synopsis: Metrics exposing GHC runtime information for use with prometheus-client. description:@@ -25,8 +25,9 @@ Prometheus.Metric.GHC build-depends: base >=4.7 && <5- , prometheus-client+ , prometheus-client >=1.0.0 && <1.1 , utf8-string >=0.3+ , text ghc-options: -Wall test-suite doctest
src/Prometheus/Metric/GHC.hs view
@@ -1,3 +1,7 @@+{-# language OverloadedStrings #-}+{-# language CPP #-}+{-# language NumDecimals #-}+ -- | This module defines a metrics that exposes statistics from the GHC runtime -- system ("GHC.Conc", "GHC.Stats"). --@@ -12,20 +16,25 @@ ) where import Control.Applicative ((<$>))+import qualified Data.ByteString.UTF8 as BS+import Data.Text (Text)+import Data.Fixed (Fixed, E9)+#if __GLASGOW_HASKELL__ < 804 import GHC.Conc (numSparks, getNumCapabilities)-import GHC.Stats+import GHC.Stats (GCStats(..), getGCStatsEnabled, getGCStats)+#else+import GHC.Stats (RTSStats(..), GCDetails(..), getRTSStatsEnabled, getRTSStats)+#endif+import qualified GHC.Stats as Stats import Prometheus-import qualified Data.ByteString.UTF8 as BS -newtype GHCMetrics = GHCMetrics ()+data GHCMetrics = GHCMetrics ghcMetrics :: Metric GHCMetrics-ghcMetrics = Metric {- handle = GHCMetrics ()- , collect = concat <$> sequence ghcCollectors- }+ghcMetrics = Metric (return (GHCMetrics, concat <$> sequence ghcCollectors)) +#if __GLASGOW_HASKELL__ < 804 ghcCollectors :: [IO [SampleGroup]] ghcCollectors = [ showCollector@@ -115,27 +124,205 @@ wallSeconds , statsCollector "ghc_parallel_copied_bytes_total"- ("Number of bytes copied during GC, minus space held by mutable "- ++ "lists held by the capabilities.")+ "Number of bytes copied during GC, minus space held by mutable lists held by the capabilities." CounterType parTotBytesCopied , statsCollector "ghc_parallel_max_copied_bytes_total"- ("Sum of number of bytes copied each GC by the most active GC "- ++ "thread each GC.")+ "Sum of number of bytes copied each GC by the most active GC thread each GC." CounterType parMaxBytesCopied ] +#else++ghcCollectors :: [IO [SampleGroup]]+ghcCollectors = [+ statsCollector+ "ghc_gcs_total"+ "Total number of GCs"+ CounterType+ gcs+ , statsCollector+ "ghc_major_gcs_total"+ "Total number of major (oldest generation) GCs"+ CounterType+ major_gcs+ , statsCollector+ "ghc_allocated_bytes_total"+ "Total bytes allocated"+ CounterType+ allocated_bytes+ , statsCollector+ "ghc_max_live_bytes"+ "Maximum live data (including large objects + compact regions)"+ GaugeType+ max_live_bytes+ , statsCollector+ "ghc_max_large_objects_bytes"+ "Maximum live data in large objects"+ GaugeType+ max_large_objects_bytes+ , statsCollector+ "ghc_max_compact_bytes"+ "Maximum live data in compact regions"+ GaugeType+ max_compact_bytes+ , statsCollector+ "ghc_max_slop_bytes"+ "Maximum slop"+ GaugeType+ max_slop_bytes+ , statsCollector+ "ghc_max_mem_in_use_bytes"+ "Maximum memory in use by the RTS"+ GaugeType+ max_mem_in_use_bytes+ , statsCollector+ "ghc_cumulative_live_bytes_total"+ "Sum of live bytes across all major GCs. Divided by major_gcs gives the average live data over the lifetime of the program."+ CounterType+ cumulative_live_bytes+ , statsCollector+ "ghc_copied_bytes_total"+ "Sum of copied_bytes across all GCs"+ CounterType+ copied_bytes+ , statsCollector+ "ghc_par_copied_bytes_total"+ "Sum of copied_bytes across all parallel GCs"+ CounterType+ par_copied_bytes+ , statsCollector+ "ghc_cumulative_par_max_copied_bytes_total"+ "Sum of par_max_copied_bytes across all parallel GCs"+ CounterType+ cumulative_par_max_copied_bytes+ , statsCollector+ "ghc_mutator_cpu_seconds_total"+ "Total CPU time used by the mutator"+ CounterType+ (rtsTimeToSeconds . mutator_cpu_ns)+ , statsCollector+ "ghc_mutator_elapsed_seconds_total"+ "Total elapsed time used by the mutator"+ CounterType+ (rtsTimeToSeconds . mutator_elapsed_ns)+ , statsCollector+ "ghc_gc_cpu_seconds_total"+ "Total CPU time used by the GC"+ CounterType+ (rtsTimeToSeconds . gc_cpu_ns)+ , statsCollector+ "ghc_gc_elapsed_seconds_total"+ "Total elapsed time used by the GC"+ CounterType+ (rtsTimeToSeconds . gc_elapsed_ns)+ , statsCollector+ "ghc_cpu_seconds_total"+ "Total CPU time (at the previous GC)"+ CounterType+ (rtsTimeToSeconds . cpu_ns)+ , statsCollector+ "ghc_elapsed_seconds_total"+ "Total elapsed time (at the previous GC)"+ CounterType+ (rtsTimeToSeconds . elapsed_ns)++ , statsCollector+ "ghc_gcdetails_gen"+ "The generation number of this GC"+ HistogramType -- TODO: is this correct?+ -- Gauge makes little sense here.+ -- With Histogram we'll be able to see which+ -- generations are collected most often.+ (gcdetails_gen . gc)+ , statsCollector+ "ghc_gcdetails_threads"+ "Number of threads used in this GC"+ GaugeType+ (gcdetails_threads . gc)+ , statsCollector+ "ghc_gcdetails_allocated_bytes"+ "Number of bytes allocated since the previous GC"+ GaugeType -- TODO: this doesn't seem very meaningful.+ (gcdetails_allocated_bytes . gc)+ , statsCollector+ "ghc_gcdetails_live_bytes"+ "Total amount of live data in the heap (including large + compact data)"+ GaugeType+ (gcdetails_live_bytes . gc)+ , statsCollector+ "ghc_gcdetails_large_objects_bytes"+ "Total amount of live data in large objects"+ GaugeType+ (gcdetails_large_objects_bytes . gc)+ , statsCollector+ "ghc_gcdetails_compact_bytes"+ "Total amount of live data in compact regions"+ GaugeType+ (gcdetails_compact_bytes . gc)+ , statsCollector+ "ghc_gcdetails_slop_bytes"+ "Total amount of slop (wasted memory)"+ GaugeType+ (gcdetails_slop_bytes . gc)+ , statsCollector+ "ghc_gcdetails_mem_in_use_bytes"+ "Total amount of memory in use by the RTS"+ CounterType+ (gcdetails_mem_in_use_bytes . gc)+ , statsCollector+ "ghc_gcdetails_copied_bytes"+ "Total amount of data copied during this GC"+ GaugeType -- TODO: this will also vary wildly between GCs of different generations.+ (gcdetails_copied_bytes . gc)+ , statsCollector+ "ghc_gcdetails_par_max_copied_bytes"+ "In parallel GC, the max amount of data copied by any one thread"+ GaugeType+ (gcdetails_par_max_copied_bytes . gc)+ , statsCollector+ "ghc_gcdetails_sync_elapsed_seconds"+ "The time elapsed during synchronisation before GC"+ GaugeType+ (rtsTimeToSeconds . gcdetails_sync_elapsed_ns . gc)+ , statsCollector+ "ghc_gcdetails_cpu_seconds"+ "The CPU time used during GC itself"+ GaugeType+ (rtsTimeToSeconds . gcdetails_cpu_ns . gc)+ , statsCollector+ "ghc_gcdetails_elapsed_seconds"+ "The time elapsed during GC itself"+ GaugeType+ (rtsTimeToSeconds . gcdetails_elapsed_ns . gc)+ ]++-- | Convert from 'RtsTime' (nanoseconds) to seconds with nanosecond precision.+rtsTimeToSeconds :: Stats.RtsTime -> Fixed E9+rtsTimeToSeconds = (/ 1e9) . fromIntegral+#endif++#if __GLASGOW_HASKELL__ < 804 statsCollector :: Show a- => String -> String -> SampleType -> (GCStats -> a) -> IO [SampleGroup]+ => Text -> Text -> SampleType -> (GCStats -> a) -> IO [SampleGroup] statsCollector name help sampleType stat = do statsEnabled <- getGCStatsEnabled if statsEnabled then showCollector name help sampleType (stat <$> getGCStats) else return []+#else+statsCollector :: Show a+ => Text -> Text -> SampleType -> (RTSStats -> a) -> IO [SampleGroup]+statsCollector name help sampleType stat = do+ statsEnabled <- getRTSStatsEnabled+ if statsEnabled+ then showCollector name help sampleType (stat <$> getRTSStats)+ else return []+#endif -showCollector :: Show a => String -> String -> SampleType -> IO a -> IO [SampleGroup]+showCollector :: Show a => Text -> Text -> SampleType -> IO a -> IO [SampleGroup] showCollector name help sampleType ioInt = do value <- ioInt let info = Info name help