A mutable metric store.
Moduleekg-core-0.1.2.0Haskell2010
System.Metrics
A module for defining metrics that can be monitored.
Metrics are used to monitor program behavior and performance. All metrics have
a name, and
a way to get the metric's current value.
This module provides a way to register metrics in a global "metric store". The store can then be used to get a snapshot of all metrics. The store also serves as a central place to keep track of all the program's metrics, both user and library defined.
Here's an example of creating a single counter, used to count the number of request served by a web server:
import System.Metrics
import qualified System.Metrics.Counter as Counter
main = do
store <- newStore
requests <- createCounter "myapp.request_count" store
-- Every time we receive a request:
Counter.inc requestsThis module also provides a way to register a number of predefined metrics that are useful in most applications. See e.g. registerGcMetrics.
- 3 types
- 12 values
- Packageekg-core-0.1.2.0
- Exports15
- LanguageHaskell2010
- LicenceBSD-3-Clause
- SourceMetrics.hs
Naming metrics
0 declarationsCompound metric names should be separated using underscores.
Example: request_count. Periods in the name imply namespacing.
Example: "myapp.users". Some consumers of metrics will use
these namespaces to group metrics in e.g. UIs.
Libraries and frameworks that want to register their own metrics
should prefix them with a namespace, to avoid collision with
user-defined metrics and metrics defined by other libraries. For
example, the Snap web framework could prefix all its metrics with
"snap.".
It's customary to suffix the metric name with a short string
explaining the metric's type e.g. using "_ms" to denote
milliseconds.
The metric store
2 declarationsThe metric store is a shared store of metrics. It allows several disjoint components (e.g. libraries) to contribute to the set of metrics exposed by an application. Libraries that want to provide a set of metrics should defined a register method, in the style of registerGcMetrics, that registers the metrics in the Store. The register function should document which metrics are registered and their types (i.e. counter, gauge, label, or distribution).
Create a new, empty metric store.
Registering metrics
5 declarationsBefore metrics can be sampled they need to be registered with the metric store. The same metric name can only be used once. Passing a metric name that has already been used to one of the register function is an error.
registerCounter Register a non-negative, monotonically increasing, integer-valued metric. The provided action to read the value must be thread-safe. Also see createCounter.
registerGauge Register an integer-valued metric. The provided action to read the value must be thread-safe. Also see createGauge.
registerLabel Register a text metric. The provided action to read the value must be thread-safe. Also see createLabel.
registerDistribution Register a distribution metric. The provided action to read the value must be thread-safe. Also see createDistribution.
registerGroup Register an action that will be executed any time one of the metrics computed from the value it returns needs to be sampled.
When one or more of the metrics listed in the first argument needs to be sampled, the action is executed and the provided getter functions will be used to extract the metric(s) from the action's return value.
The registered action might be called from a different thread and therefore needs to be thread-safe.
This function allows you to sample groups of metrics together. This is useful if
you need a consistent view of several metric or
sampling the metrics together is more efficient.
For example, sampling GC statistics needs to be done atomically or a GC might strike in the middle of sampling, rendering the values incoherent. Sampling GC statistics is also more efficient if done in "bulk", as the run-time system provides a function to sample all GC statistics at once.
Note that sampling of the metrics is only atomic if the provided
action computes a atomically (e.g. if a is a record, the action
needs to compute its fields atomically if the sampling is to be
atomic.)
Example usage:
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.HashMap.Strict as M
import GHC.Stats
import System.Metrics
main = do
store <- newStore
let metrics =
[ ("num_gcs", Counter . numGcs)
, ("max_bytes_used", Gauge . maxBytesUsed)
]
registerGroup (M.fromList metrics) getGCStats storeConvenience functions
These functions combined the creation of a mutable reference (e.g. a Counter) with registering that reference in the store in one convenient function.
Create and register a zero-initialized counter.
Create and register a zero-initialized gauge.
Create and register an empty label.
Create and register an event tracker.
Predefined metrics
This library provides a number of pre-defined metrics that can easily be added to a metrics store by calling their register function.
Register a number of metrics related to garbage collector behavior.
To enable GC statistics collection, either run your program with
+RTS -Tor compile it with
-with-rtsopts=-TThe runtime overhead of -T is very small so it's safe to always
leave it enabled.
Registered counters:
rts.gc.bytes_allocatedTotal number of bytes allocated
rts.gc.num_gcsNumber of garbage collections performed
rts.gc.num_bytes_usage_samplesNumber of byte usage samples taken
rts.gc.cumulative_bytes_usedSum of all byte usage samples, can be used with
numByteUsageSamplesto calculate averages with arbitrary weighting (if you are sampling this record multiple times).
rts.gc.bytes_copiedNumber of bytes copied during GC
rts.gc.init_cpu_msCPU time used by the init phase, in milliseconds. GHC 8.6+ only.
rts.gc.init_wall_msWall clock time spent running the init phase, in milliseconds. GHC 8.6+ only.
rts.gc.mutator_cpu_msCPU time spent running mutator threads, in milliseconds. This does not include any profiling overhead or initialization.
rts.gc.mutator_wall_msWall clock time spent running mutator threads, in milliseconds. This does not include initialization.
rts.gc.gc_cpu_msCPU time spent running GC, in milliseconds.
rts.gc.gc_wall_msWall clock time spent running GC, in milliseconds.
rts.gc.cpu_msTotal CPU time elapsed since program start, in milliseconds.
rts.gc.wall_msTotal wall clock time elapsed since start, in milliseconds.
Registered gauges:
rts.gc.max_bytes_usedMaximum number of live bytes seen so far
rts.gc.max_large_bytes_usedMaximum number of live bytes seen so far just in large ojects
rts.gc.max_compact_bytes_usedMaximum number of live bytes seen so far just in compact regions
rts.gc.current_bytes_usedCurrent number of live bytes
rts.gc.current_bytes_slopCurrent number of bytes lost to slop
rts.gc.max_bytes_slopMaximum number of bytes lost to slop at any one time so far
rts.gc.peak_megabytes_allocatedMaximum number of megabytes allocated
rts.gc.par_tot_bytes_copiedNumber of bytes copied during GC, minus space held by mutable lists held by the capabilities. Can be used with
parMaxBytesCopiedto determine how well parallel GC utilized all cores.
rts.gc.par_avg_bytes_copiedDeprecated alias for
par_tot_bytes_copied.
rts.gc.par_max_bytes_copiedSum of number of bytes copied each GC by the most active GC thread each GC. The ratio of
par_tot_bytes_copieddivided by
par_max_bytes_copiedapproaches 1 for a maximally sequential run and approaches the number of threads (set by the RTS flag
-N) for a maximally parallel run. Deprecated by GHC in later versions.
rts.gc.par_balanced_bytes_copiedSum of balanced data copied by all threads in parallel GC, across all parallel GCs.
rts.gc.nm.sync_cpu_msThe total CPU time used during the post-mark pause phase of the concurrent nonmoving GC.
rts.gc.nm.sync_elapsed_msThe total time elapsed during the post-mark pause phase of the concurrent nonmoving GC.
rts.gc.nm.sync_max_elapsed_msThe maximum elapsed length of any post-mark pause phase of the concurrent nonmoving GC.
rts.gc.nm.cpu_msThe total CPU time used by the nonmoving GC.
rts.gc.nm.elapsed_msThe total time elapsed during which there is a nonmoving GC active.
rts.gc.nm.max_elapsed_msThe maximum time elapsed during any nonmoving GC cycle.
Sampling metrics
3 declarationsThe metrics register in the store can be sampled together. Sampling is not atomic. While each metric will be retrieved atomically, the sample is not an atomic snapshot of the system as a whole. See registerGroup for an explanation of how to sample a subset of all metrics atomically.
A sample of some metrics.
Sample all metrics. Sampling is not atomic in the sense that some metrics might have been mutated before they're sampled but after some other metrics have already been sampled.