HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduleprometheus-client-1.1.1Haskell2010

Prometheus

This module provides the basics for instrumenting Haskell executables for use with the Prometheus monitoring system.

  • 25 types
  • 3 classes
  • 38 values

Registry

6 declarations
valueunsafeRegisterIO :: IO (Metric s) -> s
#

Registers a metric with the global metric registry.

IMPORTANT: This method should only be used to register metrics as top level symbols, it should not be run from other pure code.

For example,

Example1 expression
:{ {-# NOINLINE c #-} let c = unsafeRegisterIO $ counter (Info "my_counter" "An example metric"):}...
valueunsafeRegister :: Metric s -> s
#

Registers a metric with the global metric registry.

IMPORTANT: This method should only be used to register metrics as top level symbols, it should not be run from other pure code.

valuecollectMetrics :: MonadIO m => m [SampleGroup]
#

Collect samples from all currently registered metrics. In typical use cases there is no reason to use this function, instead you should use exportMetricsAsText or a convenience library.

This function is likely only of interest if you wish to export metrics in a non-supported format for use with another monitoring service.

Exporting

1 declaration

Export all registered metrics in the Prometheus 0.0.4 text exposition format.

For the full specification of the format, see the official Prometheus documentation.

Example4 expressions
:m +Data.ByteStringmyCounter <- register $ counter (Info "my_counter" "Example counter")incCounter myCounterexportMetricsAsText >>= Data.ByteString.Lazy.putStr# HELP my_counter Example counter# TYPE my_counter countermy_counter 1.0

Metrics

0 declarations

A metric represents a single value that is being monitored. For example a metric could be the number of open files, the current CPU temperature, the elapsed time of execution, and the latency of HTTP requests.

This module provides 4 built-in metric types: counters, gauges, summaries, and metric vectors. These types of metrics should cover most typical use cases. However, for more specialized use cases it is also possible to write custom metrics.

Counter

A counter models a monotonically increasing value. It is the simplest type of metric provided by this library.

A Counter is typically used to count requests served, tasks completed, errors occurred, etc.

Example5 expressions
myCounter <- register $ counter (Info "my_counter" "An example counter")replicateM_ 47 (incCounter myCounter)getCounter myCounter47.0void $ addCounter myCounter 10getCounter myCounter57.0
newtypenewtype Counter
#
Instances1NFData
  • NFData CounterDefined in prometheus-client-1.1.1 · Prometheus.Metric.Counter
valuecountExceptions :: (MonadCatch m, MonadMonitor m) => Counter -> m a -> m a
#

Count the amount of times an action throws any synchronous exception.

Example5 expressions
exceptions <- register $ counter (Info "exceptions_total" "Total amount of exceptions thrown")countExceptions exceptions $ return ()getCounter exceptions0.0countExceptions exceptions (error "Oh no!") `catch` (\SomeException{} -> return ())getCounter exceptions1.0

It's important to note that this will count *all* synchronous exceptions. If you want more granular counting of exceptions, you will need to write custom code using incCounter.

Gauge

A gauge models an arbitrary floating point value. There are operations to set the value of a gauge as well as add and subtract arbitrary values.

Example5 expressions
myGauge <- register $ gauge (Info "my_gauge" "An example gauge")setGauge myGauge 100addGauge myGauge 50subGauge myGauge 25getGauge myGauge125.0
newtypenewtype Gauge
#
Instances1NFData
  • NFData GaugeDefined in prometheus-client-1.1.1 · Prometheus.Metric.Gauge

Summaries and histograms

An Observer is a generic metric that captures observations of a floating point value over time. Different implementations can store and summarise these value in different ways.

The two main observers are summaries and histograms. A Summary allows you to get a precise estimate of a particular quantile, but cannot be meaningfully aggregated across processes. A Histogram packs requests into user-supplied buckets, which can be aggregated meaningfully, but provide much less precise information on particular quantiles.

classclass Observer metric where
#

Interface shared by Summary and Histogram.

Methods

  • observe :: MonadMonitor m => metric -> Double -> m ()

    Observe that a particular floating point value has occurred. For example, observe that this request took 0.23s.

Instances2Observer
  • Observer HistogramDefined in prometheus-client-1.1.1 · Prometheus.Metric.Histogram
  • Observer SummaryDefined in prometheus-client-1.1.1 · Prometheus.Metric.Summary
valueobserveDuration
  1. :: (Observer metric, MonadIO m, MonadMonitor m)
  2. => metric
  3. -> m a
  4. -> m a
#

Adds the duration in seconds of an IO action as an observation to an observer metric.

If the IO action throws an exception no duration will be observed.

Summary

A summary is an Observer that summarizes the observations as a count, sum, and rank estimations. A typical use case for summaries is measuring HTTP request latency.

Example3 expressions
mySummary <- register $ summary (Info "my_summary" "") defaultQuantilesobserve mySummary 0getSummary mySummary[(1 % 2,0.0),(9 % 10,0.0),(99 % 100,0.0)]
datadata Summary
#
Instances2NFData, Observer
  • NFData SummaryDefined in prometheus-client-1.1.1 · Prometheus.Metric.Summary
  • Observer SummaryDefined in prometheus-client-1.1.1 · Prometheus.Metric.Summary

Histogram

A histogram captures observations of a floating point value over time and stores those observations in a user-supplied histogram. A typical use case for histograms is measuring HTTP request latency. Histograms are unlike summaries in that they can be meaningfully aggregated across processes.

Example3 expressions
myHistogram <- register $ histogram (Info "my_histogram" "") defaultBucketsobserve myHistogram 0getHistogram myHistogramfromList [(5.0e-3,1),(1.0e-2,0),(2.5e-2,0),(5.0e-2,0),(0.1,0),(0.25,0),(0.5,0),(1.0,0),(2.5,0),(5.0,0),(10.0,0)]
newtypenewtype Histogram
#

A histogram. Counts the number of observations that fall within the specified buckets.

Instances2NFData, Observer
  • NFData HistogramDefined in prometheus-client-1.1.1 · Prometheus.Metric.Histogram
  • Observer HistogramDefined in prometheus-client-1.1.1 · Prometheus.Metric.Histogram
typetype Bucket = Double
#

Upper-bound for a histogram bucket.

valuedefaultBuckets :: [Double]
#

The default Histogram buckets. These are tailored to measure the response time (in seconds) of a network service. You will almost certainly need to customize them for your particular use case.

valueexponentialBuckets :: Bucket -> Double -> Int -> [Bucket]
#

Create count buckets, where the lowest bucket has an upper bound of start and each bucket's upper bound is factor times the previous bucket's upper bound. Use this to create buckets for histogram.

valuegetHistogram :: MonadIO m => Histogram -> m (Map Bucket Int)
#

Retries a map of upper bounds to counts of values observed that are less-than-or-equal-to that upper bound, but greater than any other upper bound in the map.

Vector

A vector models a collection of metrics that share the same name but are partitioned across a set of dimensions.

Example7 expressions
myVector <- register $ vector ("method", "code") $ counter (Info "http_requests" "")withLabel myVector ("GET", "200") incCounterwithLabel myVector ("GET", "200") incCounterwithLabel myVector ("GET", "404") incCounterwithLabel myVector ("POST", "200") incCountergetVectorWith myVector getCounter[(("GET","200"),2.0),(("GET","404"),1.0),(("POST","200"),1.0)]exportMetricsAsText >>= Data.ByteString.Lazy.putStr# HELP http_requests# TYPE http_requests counterhttp_requests{method="GET",code="200"} 2.0http_requests{method="GET",code="404"} 1.0http_requests{method="POST",code="200"} 1.0
datadata Vector l m
#
Instances1NFData
  • NFData (Vector l m)Defined in prometheus-client-1.1.1 · Prometheus.Metric.Vector
valuewithLabel
  1. :: (Label label, MonadMonitor m)
  2. => Vector label metric
  3. -> label
  4. -> metric -> IO ()
  5. -> m ()
#

Given a label, applies an operation to the corresponding metric in the vector.

Labels

The labels of a vector metric are types of the class Label. This module defines all n-tupes of Strings for n <= 9 to be Labels. Additionally, the type aliases LabelN is defined for each of these tuple types to make specifying the types of vectors more concise.

Example4 expressions
:{let myVector :: Metric (Vector Label3 Counter);    myVector = vector ("a", "b", "c") $ counter (Info "some_counter" ""):}
classclass Ord l => Label l where
#

Label describes a class of types that can be used to as the label of a vector.

Methods

Instances10Label, …
  • Label TextDefined in prometheus-client-1.1.1 · Prometheus.Label
  • Label ()Defined in prometheus-client-1.1.1 · Prometheus.Label
  • (a ~ Text, b ~ a) => Label (a, b)Defined in prometheus-client-1.1.1 · Prometheus.Label
  • (a ~ Text, b ~ a, c ~ a) => Label (a, b, c)Defined in prometheus-client-1.1.1 · Prometheus.Label
  • (a ~ Text, b ~ a, c ~ a, d ~ a) => Label (a, b, c, d)Defined in prometheus-client-1.1.1 · Prometheus.Label
  • (a ~ Text, b ~ a, c ~ a, d ~ a, e ~ a) => Label (a, b, c, d, e)Defined in prometheus-client-1.1.1 · Prometheus.Label
  • (a ~ Text, b ~ a, c ~ a, d ~ a, e ~ a, f ~ a) => Label (a, b, c, d, e, f)Defined in prometheus-client-1.1.1 · Prometheus.Label
  • (a ~ Text, b ~ a, c ~ a, d ~ a, e ~ a, f ~ a, g ~ a) => Label (a, b, c, d, e, f, g)Defined in prometheus-client-1.1.1 · Prometheus.Label
  • (a ~ Text, b ~ a, c ~ a, d ~ a, e ~ a, f ~ a, g ~ a, h ~ a) => Label (a, b, c, d, e, f, g, h)Defined in prometheus-client-1.1.1 · Prometheus.Label
  • (a ~ Text, b ~ a, c ~ a, d ~ a, e ~ a, f ~ a, g ~ a, h ~ a, i ~ a) => Label (a, b, c, d, e, f, g, h, i)Defined in prometheus-client-1.1.1 · Prometheus.Label
typetype LabelPairs = [(Text, Text)]
#

A list of tuples where the first value is the label and the second is the value of that label.

Custom metrics

Custom metrics can be created by directly creating a new Metric type. There are two parts of any metric, the handle and the collect method.

The handle is a value embedded in the metric that is intended to allow for communication with the metric from instrumented code. For example, all of the metrics provided by this library use a newtype wrapped TVar of some underlying data type as their handle. When defining a new metric, it is recommended that you use a newtype wrapper around your handle type as it will allow users of your metric to succinctly identify your metric in type signatures.

The collect method is responsible for serializing the current value of a metric into a list of SampleGroups.

The following is an example of a custom metric that models the current CPU time. It uses a newtype wrapped unit as the handler type since it doesn't need to maintain any state.

Example11 expressions
:m +System.CPUTime:m +Data.ByteString.UTF8newtype CPUTime = MkCPUTime ()let info = Info "cpu_time" "The current CPU time"let toValue = Data.ByteString.UTF8.fromString . showlet toSample = Sample "cpu_time" [] . toValuelet toSampleGroup = (:[]) . SampleGroup info GaugeType . (:[]) . toSamplelet collectCPUTime = fmap toSampleGroup getCPUTimelet cpuTimeMetric = Metric (return (MkCPUTime (), collectCPUTime))register cpuTimeMetricexportMetricsAsText >>= Data.ByteString.Lazy.putStr# HELP cpu_time The current CPU time# TYPE cpu_time gaugecpu_time ...

Instrumenting pure code

5 declarations

Pure code can be instrumented through the use of the Monitor monad and MonitorT monad transformer. These constructs work by queueing all operations on metrics. In order for the operations to actually be performed, the queue must be evaluated within the IO monad.

The following is a contrived example that defines an add function that records the number of times it was invoked.

add :: Int -> Int -> Monitor Int

Note that the changes to numAdds are not reflected until the updateMetrics value has been evaluated in the IO monad.

Example6 expressions
numAdds <- register $ counter (Info "num_adds" "The number of additions")let add x y = incCounter numAdds >> return (x + y)let (3, updateMetrics) = runMonitor $ (add 1 1) >>= (add 1)getCounter numAdds0.0updateMetricsgetCounter numAdds2.0
classclass Monad m => MonadMonitor (m :: Type -> Type) where
#

MonadMonitor describes a class of Monads that are capable of performing asynchronous IO operations.

Methods

Instances12MonadMonitor, …
typetype Monitor a = MonitorT Identity a
#

Monitor allows the use of Prometheus metrics in pure code. When using Monitor, all of the metric operations will be collected and queued into a single IO () value that can be run from impure code.

Because all of the operations are performed asynchronously use of this class is not recommended for use with metrics that are time sensitive (e.g. for measuring latency).

valuerunMonitor :: Monitor a -> (a, IO ())
#

Extract a value and the corresponding monitor update value from the Monitor monad. For an example use see Monitor.

newtypenewtype MonitorT (m :: Type -> Type) a
#

MonitorT is the monad transformer analog of Monitor and allows for monitoring pure monad transformer stacks.

Instances5MonadTrans, Monad, Functor, Applicative, MonadMonitor
valuerunMonitorT :: Monad m => MonitorT m a -> m (a, IO ())
#

Extract a value and the corresponding monitor update value from the MonitorT monad transformer.

Base data types

5 declarations
datadata Info
#

Meta data about a metric including its name and a help string that describes the value that the metric is measuring.

Instances4Eq, Ord, Read, Show
  • Eq InfoDefined in prometheus-client-1.1.1 · Prometheus.Info
  • Ord InfoDefined in prometheus-client-1.1.1 · Prometheus.Info
  • Read InfoDefined in prometheus-client-1.1.1 · Prometheus.Info
  • Show InfoDefined in prometheus-client-1.1.1 · Prometheus.Info
newtypenewtype Metric s
#

A metric represents a single value that is being monitored. It is comprised of a handle value and a collect method. The handle value is typically a new type wrapped value that provides access to the internal state of the metric. The collect method samples the current value of the metric.

Constructors

  • Metric
    • construct :: IO (s, IO [SampleGroup])

      construct is an IO action that creates a new instance of a metric. For example, in a counter, this IO action would create a mutable reference to maintain the state of the counter.

      construct returns two things:

      1. The state of the metric itself, which can be used to modify the metric. A counter would return state pointing to the mutable reference.

      2. An IO action that samples the metric and returns SampleGroups. This is the data that will be stored by Prometheus.

Instances1NFData
datadata Sample
#

A single value recorded at a moment in time. The sample type contains the name of the sample, a list of labels and their values, and the value encoded as a ByteString.

Instances1Show
  • Show SampleDefined in prometheus-client-1.1.1 · Prometheus.Metric