Support Center & Knowledge base

Providing Metrics

The type of metrics that are exposed is extensible. Any part of the runtime and extensions to the runtime can provide metrics that they independently own and update at their own will.

To provide metrics, all you need to do is implement the ICanProvideMetrics interface found in the Metrics package.

using Dolittle.Runtime.Metrics;
using Prometheus;

public class MyMetrics : ICanProvideMetrics
{
    public IEnumerable<Collector> Provide(IMetricFactory metricFactory)
    {
        return new Collector[] {

        };
    }
}

The IMetricFactory wraps the Prometheus.NET API and gives you functionality for creating:

Recommend reading the best practices for when to use which type of Collector

Exposing Metrics to the outside

The provider itself is only responsible for creating the different Collectors, to use the Collectors we need them to be exposed in a good way to the outside world. This can be achieved by exposing public properties on the provider itself and make sure we have it as a singleton for us to be able use them across the system.

The Collectors are not per tenant. This means they are to be considered global variables. Look at dynamic metrics for an example of how you could have tenant specific Collectors.

The following example shows how you can achieve this:

using Dolittle.Execution;
using Dolittle.Runtime.Metrics;
using Prometheus;

[Singleton]
public class MyMetrics : ICanProvideMetrics
{
    public Counter MyCounter { get; private set; }

    public Gauge MyGauge { get; private set; }

    public IEnumerable<Collector> Provide(IMetricFactory metricFactory)
    {
        MyCounter = metricFactory.Counter("MyCounter", "This is my first counter");
        MyGauge = metricFactory.Gauge("MyGauge", "This is my first gauge");

        return new Collector[] {
            MyCounter,
            MyGauge
        };
    }
}

You can find out more on how to work with the different collector types in the Prometheus.NET documentation.

Labels

Metrics can also be labeled, which gives you the ability to have well known metrics with different properties making them unique. Read more about how this is done here.

See also the best practices on naming and labels. Names and labels combines into a unique key and makes for unique time series. This has a performance and data amount implication for the scraper and indexer.