Skip to content

Dynamically creating metrics #12

@MaxGabriel

Description

@MaxGabriel

Sometimes you want to generate metrics on the fly. Example use cases:

  • You don't want to register metrics before hand since you have a lot of them, instead you'd like a fire-and-forget "create this counter if it doesn't exist, and increment it" operation. (Example code). I think this would help for use cases like this, as well.
  • Your metric name may be parameterized by some value in your function (this is pretty common)

Currently ekg-core makes it difficult to dynamically create metrics. Reasons:

  1. If you try to register a metric that already exists, you'll get a runtime error.
  2. There isn't a way of getting a reference to an already created Counter from your Store, you need to track that yourself.

As a workaround to this, for example, @tfausak keeps an IORef of

data Metrics = Metrics
    { metricsCounters :: IORef.IORef (Map.Map Text.Text Counter.Counter)
    , metricsDistributions :: IORef.IORef (Map.Map Text.Text Distribution.Distribution)
    , metricsGauges :: IORef.IORef (Map.Map Text.Text Gauge.Gauge)
    , metricsServer :: Maybe Monitoring.Server
    , metricsStore :: Metrics.Store
    }

in his Blunt package (used for pointfree.info).

Is this a problem? I think so: it's a hassle for users to keep a map of all their metrics, especially when the Store is pretty much doing that already.

Proposed solution

ekg-core provides an API to lookup already registered metrics. Probably a lookupOrCreate type of API should be added as well. The main complication is that ekg-core doesn't actually track the Counters, Distributions, Labels or Gauges you make, it tracks this data:

-- TODO: Rename this to Metric and Metric to SampledMetric.
data MetricSampler = CounterS !(IO Int64)
                   | GaugeS !(IO Int64)
                   | LabelS !(IO T.Text)
                   | DistributionS !(IO Distribution.Stats)

Thoughts? I imagine the choice to track CounterS !(IO Int64) instead of the actual Counter was intentional, so maybe I'm missing something.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions