Derived Metric Types
For more detailed information on building metrics see the Metrics DSL section.
Derived metric types are types of metrics that add extra functionality to an underlying primitive metric.
These metrics exist for the following reasons:
- Separation of concerns between recording a value and performing some additional higher level operation or side effect
- Making the addition of future
MetricRegistry
instances easier as higher level functionality isn't implemented by the primitive metrics - Provides a pattern for adding functionality that will not break binary compatibility
The examples in this section assume you have imported the following and have created a
MetricFactory
:
import cats.effect._
import prometheus4cats._
val factory: MetricFactory[IO] = MetricFactory.noop[IO]
Timer
A Timer
can be derived from either a Gauge
, Histogram
or [Summary
] that record Double
values. It uses
Clock
from Cats-Effect to time a given operation.
The underlying metric type should be carefully considered; a Histogram
or [Summary
] can be used to measure many
operations at differing runtime costs, where a Gauge
will only record the last value so is best for singular
operations.
Obtaining from a Histogram
val simpleTimerHistogram: Resource[IO, Timer.Aux[IO, Unit, Histogram]] = factory
.histogram("time")
.ofDouble
.help("Records the how long an opertation took")
.buckets(1.0, 2.0)
.asTimer
.build
val labelledTimerHistogram: Resource[IO, Timer.Aux[IO, String, Histogram]] = factory
.histogram("time")
.ofDouble
.help("Records the how long an opertation took")
.buckets(1.0, 2.0)
.label[String]("some_label")
.asTimer
.build
Obtaining from a Summary
val simpleTimerSummary: Resource[IO, Timer.Aux[IO, Unit, Summary]] = factory
.summary("time")
.ofDouble
.help("Records the how long an opertation took")
.asTimer
.build
val labelledTimerSummary: Resource[IO, Timer.Aux[IO, String, Summary]] = factory
.summary("time")
.ofDouble
.help("Records the how long an opertation took")
.label[String]("some_label")
.asTimer
.build
Obtaining from a Gauge
val simpleTimerGauge: Resource[IO, Timer.Aux[IO, Unit, Gauge]] = factory
.gauge("time")
.ofDouble
.help("Records the how long an opertation took")
.asTimer
.build
val labelledTimerGauge: Resource[IO, Timer.Aux[IO, String, Gauge]] = factory
.gauge("time")
.ofDouble
.help("Records the how long an opertation took")
.label[String]("some_label")
.asTimer
.build
CurrentTimeRecorder
A CurrentTimeRecorder
can be derived from any Gauge
. It uses Clock
from Cats-Effect to get the current
system time.
Obtaining from a Gauge
val simpleCurrentTimeRecorderGauge: Resource[IO, CurrentTimeRecorder[IO, Unit]] = factory
.gauge("current_time")
.ofDouble
.help("Records the how long an opertation took")
.asCurrentTimeRecorder
.build
val labelledCurrentTimeRecorderGauge:
Resource[IO, CurrentTimeRecorder[IO, String]] =
factory
.gauge("current_time")
.ofDouble
.help("Records the how long an opertation took")
.label[String]("some_label")
.asCurrentTimeRecorder
.build
OutcomeRecorder
A Timer
can be derived from either a Counter
or Gauge
. It uses Outcome
from Cats-Effect to record the status
of a given operation via a outcome_status
label, the value of which will either be succeeded
, canceled
or
errored
.
The underlying metric type should be carefully considered based on the behaviour covered below: a Counter
can be used
to measure repeated operations, where a Gauge
will only record the last value so is best for singular operations.
When using a with a Counter
, each Outcome
will increment its corresponding label value, but when using a Gauge
the last invocation will set the corresponding label value to 1
, with each of the other label values set to 0
.
To help disambiguate the difference in behaviour the OutcomeRecorder
type will be tagged with the underlying
primitive metric type. This is just a type alias and is not required when passing around instances of
OutcomeRecorder
.
Obtaining from a Counter
val simpleOutcomeCounter: Resource[IO, OutcomeRecorder.Aux[IO, Long, Unit, Counter]] = factory
.counter("outcome_total")
.ofLong
.help("Records the outcome of some operation")
.asOutcomeRecorder
.build
val labelledOutcomeCounter:
Resource[IO, OutcomeRecorder.Aux[IO, Long, String, Counter]] = factory
.counter("outcome_total")
.ofLong
.help("Records the outcome of some operation")
.label[String]("some_label")
.asOutcomeRecorder
.build
Obtaining from a Gauge
val simpleOutcomeGauge: Resource[IO, OutcomeRecorder.Aux[IO, Long, Unit, Gauge]] = factory
.gauge("outcome")
.ofLong
.help("Records the outcome of some operation")
.asOutcomeRecorder
.build
val labelledOutcomeGauge:
Resource[IO, OutcomeRecorder.Aux[IO, Long, String, Gauge]] = factory
.gauge("outcome")
.ofLong
.help("Records the outcome of some operation")
.label[String]("some_label")
.asOutcomeRecorder
.build