1
1
{-# language OverloadedStrings #-}
2
+ {-# language CPP #-}
3
+ {-# language NumDecimals #-}
2
4
3
5
-- | This module defines a metrics that exposes statistics from the GHC runtime
4
6
-- system ("GHC.Conc", "GHC.Stats").
@@ -16,8 +18,14 @@ module Prometheus.Metric.GHC (
16
18
import Control.Applicative ((<$>) )
17
19
import qualified Data.ByteString.UTF8 as BS
18
20
import Data.Text (Text )
21
+ import Data.Fixed (Fixed , E9 )
22
+ #if __GLASGOW_HASKELL__ < 804
19
23
import GHC.Conc (numSparks , getNumCapabilities )
20
- import GHC.Stats
24
+ import GHC.Stats (GCStats (.. ), getGCStatsEnabled , getGCStats )
25
+ #else
26
+ import GHC.Stats (RTSStats (.. ), GCDetails (.. ), getRTSStatsEnabled , getRTSStats )
27
+ #endif
28
+ import qualified GHC.Stats as Stats
21
29
import Prometheus
22
30
23
31
@@ -26,6 +34,7 @@ data GHCMetrics = GHCMetrics
26
34
ghcMetrics :: Metric GHCMetrics
27
35
ghcMetrics = Metric (return (GHCMetrics , concat <$> sequence ghcCollectors))
28
36
37
+ #if __GLASGOW_HASKELL__ < 804
29
38
ghcCollectors :: [IO [SampleGroup ]]
30
39
ghcCollectors = [
31
40
showCollector
@@ -125,13 +134,193 @@ ghcCollectors = [
125
134
parMaxBytesCopied
126
135
]
127
136
137
+ #else
138
+
139
+ ghcCollectors :: [IO [SampleGroup ]]
140
+ ghcCollectors = [
141
+ statsCollector
142
+ " ghc_gcs_total"
143
+ " Total number of GCs"
144
+ CounterType
145
+ gcs
146
+ , statsCollector
147
+ " ghc_major_gcs_total"
148
+ " Total number of major (oldest generation) GCs"
149
+ CounterType
150
+ major_gcs
151
+ , statsCollector
152
+ " ghc_allocated_bytes_total"
153
+ " Total bytes allocated"
154
+ CounterType
155
+ allocated_bytes
156
+ , statsCollector
157
+ " ghc_max_live_bytes"
158
+ " Maximum live data (including large objects + compact regions)"
159
+ GaugeType
160
+ max_live_bytes
161
+ , statsCollector
162
+ " ghc_max_large_objects_bytes"
163
+ " Maximum live data in large objects"
164
+ GaugeType
165
+ max_large_objects_bytes
166
+ , statsCollector
167
+ " ghc_max_compact_bytes"
168
+ " Maximum live data in compact regions"
169
+ GaugeType
170
+ max_compact_bytes
171
+ , statsCollector
172
+ " ghc_max_slop_bytes"
173
+ " Maximum slop"
174
+ GaugeType
175
+ max_slop_bytes
176
+ , statsCollector
177
+ " ghc_max_mem_in_use_bytes"
178
+ " Maximum memory in use by the RTS"
179
+ GaugeType
180
+ max_mem_in_use_bytes
181
+ , statsCollector
182
+ " ghc_cumulative_live_bytes_total"
183
+ " Sum of live bytes across all major GCs. Divided by major_gcs gives the average live data over the lifetime of the program."
184
+ CounterType
185
+ cumulative_live_bytes
186
+ , statsCollector
187
+ " ghc_copied_bytes_total"
188
+ " Sum of copied_bytes across all GCs"
189
+ CounterType
190
+ copied_bytes
191
+ , statsCollector
192
+ " ghc_par_copied_bytes_total"
193
+ " Sum of copied_bytes across all parallel GCs"
194
+ CounterType
195
+ par_copied_bytes
196
+ , statsCollector
197
+ " ghc_cumulative_par_max_copied_bytes_total"
198
+ " Sum of par_max_copied_bytes across all parallel GCs"
199
+ CounterType
200
+ cumulative_par_max_copied_bytes
201
+ , statsCollector
202
+ " ghc_mutator_cpu_seconds_total"
203
+ " Total CPU time used by the mutator"
204
+ CounterType
205
+ (rtsTimeToSeconds . mutator_cpu_ns)
206
+ , statsCollector
207
+ " ghc_mutator_elapsed_seconds_total"
208
+ " Total elapsed time used by the mutator"
209
+ CounterType
210
+ (rtsTimeToSeconds . mutator_elapsed_ns)
211
+ , statsCollector
212
+ " ghc_gc_cpu_seconds_total"
213
+ " Total CPU time used by the GC"
214
+ CounterType
215
+ (rtsTimeToSeconds . gc_cpu_ns)
216
+ , statsCollector
217
+ " ghc_gc_elapsed_seconds_total"
218
+ " Total elapsed time used by the GC"
219
+ CounterType
220
+ (rtsTimeToSeconds . gc_elapsed_ns)
221
+ , statsCollector
222
+ " ghc_cpu_seconds_total"
223
+ " Total CPU time (at the previous GC)"
224
+ CounterType
225
+ (rtsTimeToSeconds . cpu_ns)
226
+ , statsCollector
227
+ " ghc_elapsed_seconds_total"
228
+ " Total elapsed time (at the previous GC)"
229
+ CounterType
230
+ (rtsTimeToSeconds . elapsed_ns)
231
+
232
+ , statsCollector
233
+ " ghc_gcdetails_gen"
234
+ " The generation number of this GC"
235
+ HistogramType -- TODO: is this correct?
236
+ -- Gauge makes little sense here.
237
+ -- With Histogram we'll be able to see which
238
+ -- generations are collected most often.
239
+ (gcdetails_gen . gc)
240
+ , statsCollector
241
+ " ghc_gcdetails_threads"
242
+ " Number of threads used in this GC"
243
+ GaugeType
244
+ (gcdetails_threads . gc)
245
+ , statsCollector
246
+ " ghc_gcdetails_allocated_bytes"
247
+ " Number of bytes allocated since the previous GC"
248
+ GaugeType -- TODO: this doesn't seem very meaningful.
249
+ (gcdetails_allocated_bytes . gc)
250
+ , statsCollector
251
+ " ghc_gcdetails_live_bytes"
252
+ " Total amount of live data in the heap (including large + compact data)"
253
+ GaugeType
254
+ (gcdetails_live_bytes . gc)
255
+ , statsCollector
256
+ " ghc_gcdetails_large_objects_bytes"
257
+ " Total amount of live data in large objects"
258
+ GaugeType
259
+ (gcdetails_large_objects_bytes . gc)
260
+ , statsCollector
261
+ " ghc_gcdetails_compact_bytes"
262
+ " Total amount of live data in compact regions"
263
+ GaugeType
264
+ (gcdetails_compact_bytes . gc)
265
+ , statsCollector
266
+ " ghc_gcdetails_slop_bytes"
267
+ " Total amount of slop (wasted memory)"
268
+ GaugeType
269
+ (gcdetails_slop_bytes . gc)
270
+ , statsCollector
271
+ " ghc_gcdetails_mem_in_use_bytes"
272
+ " Total amount of memory in use by the RTS"
273
+ CounterType
274
+ (gcdetails_mem_in_use_bytes . gc)
275
+ , statsCollector
276
+ " ghc_gcdetails_copied_bytes"
277
+ " Total amount of data copied during this GC"
278
+ GaugeType -- TODO: this will also vary wildly between GCs of different generations.
279
+ (gcdetails_copied_bytes . gc)
280
+ , statsCollector
281
+ " ghc_gcdetails_par_max_copied_bytes"
282
+ " In parallel GC, the max amount of data copied by any one thread"
283
+ GaugeType
284
+ (gcdetails_par_max_copied_bytes . gc)
285
+ , statsCollector
286
+ " ghc_gcdetails_sync_elapsed_seconds"
287
+ " The time elapsed during synchronisation before GC"
288
+ GaugeType
289
+ (rtsTimeToSeconds . gcdetails_sync_elapsed_ns . gc)
290
+ , statsCollector
291
+ " ghc_gcdetails_cpu_seconds"
292
+ " The CPU time used during GC itself"
293
+ GaugeType
294
+ (rtsTimeToSeconds . gcdetails_cpu_ns . gc)
295
+ , statsCollector
296
+ " ghc_gcdetails_elapsed_seconds"
297
+ " The time elapsed during GC itself"
298
+ GaugeType
299
+ (rtsTimeToSeconds . gcdetails_elapsed_ns . gc)
300
+ ]
301
+
302
+ -- | Convert from 'RtsTime' (nanoseconds) to seconds with nanosecond precision.
303
+ rtsTimeToSeconds :: Stats. RtsTime -> Fixed E9
304
+ rtsTimeToSeconds = (/ 1e9 ) . fromIntegral
305
+ #endif
306
+
307
+ #if __GLASGOW_HASKELL__ < 804
128
308
statsCollector :: Show a
129
309
=> Text -> Text -> SampleType -> (GCStats -> a ) -> IO [SampleGroup ]
130
310
statsCollector name help sampleType stat = do
131
311
statsEnabled <- getGCStatsEnabled
132
312
if statsEnabled
133
313
then showCollector name help sampleType (stat <$> getGCStats)
134
314
else return []
315
+ #else
316
+ statsCollector :: Show a
317
+ => Text -> Text -> SampleType -> (RTSStats -> a ) -> IO [SampleGroup ]
318
+ statsCollector name help sampleType stat = do
319
+ statsEnabled <- getRTSStatsEnabled
320
+ if statsEnabled
321
+ then showCollector name help sampleType (stat <$> getRTSStats)
322
+ else return []
323
+ #endif
135
324
136
325
showCollector :: Show a => Text -> Text -> SampleType -> IO a -> IO [SampleGroup ]
137
326
showCollector name help sampleType ioInt = do
0 commit comments