hiero-ledger / hiero-ledger/hiero-consensus-node

Missing features of Metrics API - labels & cumulative results

Open
#12,768 0 comments 0 reactions 1 assignee Claimed by @hendrikebbers View on GitHub
Base Metrics Platform
Dominant language
Java
Stars
406
Forks
226
Avg merge
3d 4h
Merged PRs (30d)
210

Description

To better discuss additions and changes for the metrics API I want to start with a concrete usecase that I currently have:

We introduced an executor service for low priority base tasks. You can find the executor API at `com.swirlds.base.internal.BaseExecutorFactory`. For that executor I want to add metrics. What I want to know from that metrics is how the executor is used at production. Example are the average time of task execution, how many tasks fail, and so on.
I created a class that adds several metrics to the executor. You can find the code at `com.swirlds.common.metrics.extensions.BaseExecutorFactoryMetrics`.
Here I define several counter metrics that will keep track of the count of added and executed tasks. Next to that I add some accumulators to measure the min / max / avg execution time of tasks.

By doing so I have 2 specific points where the metrics api do not fit my needs.

## Label support

In base we have a hand full of different tasks that are executed by the executor. Examples are flushing logging files or clearing caches. Next to having a min / max / avg execution time of all tasks I want to have it per task type. The type is defined as a string. For sure It could create individual metrics for each type by just adding the type as a suffix to the name. But other metric frameworks provide labels (of attributes - based on the api that you are using). By doing so you are able to simply add values for a specific label/type/attribute.

In micrometer the functionality is called tags and you can simply create a metric by adding 0-N tags:

`Counter counter = registry.counter("page.visitors", "age", "20s");`

Here the unique identifier of a metric is the name + all tags.

Micrometer even allows to define global tags. That will work create in combination to our Context API:

`registry.config().commonTags("region", "ua-east");`

In Open Telemetry the feature is called attributes:

```
Gauge gauge = meter.gaugeBuilder("cpu_usage”).setUnit("ms”);

Attributes attributesAttributes.builder().put("key1", "value1").build();
gauge.record(getCpuUsage(), attributes);
```

Since Open Telemetry has a context concept that is quite similar to our context it supports attribute extraction from a context by default.

It would be great if we could do the same in our api. I assume the easiest way would be to allow to define labels at metric creation. That won’t change too much for the api implementation. The usage could look like that:

```
Counter.Config config = new Counter.Config("base_executor", "base_executor_task_count")
.withUnit("tasks")
.withLabel(“name”, “value”);
Counter counter = metrics.getOrCreate(config);
counter.increment();
```

In grafana labels could be used to enrich the reporting. Here it can be used to just add additional information to datapoints or to make the diagrams more dynamic by showing only information for specific labels.

Bildschirmfoto 2024-04-12 um 11 57 43

Bildschirmfoto 2024-04-12 um 11 58 02

## Support for delta and cumulative metric results

To show the problem I created a sample with the executor. In that sample I added some tasks to the executor. First I added 40 tasks that took 500ms each and then I add 40 tasks that took 50 ms each.

In prometheus you can see exactly that behaviour when looking at the count metric:

count-chart

While that looks exactly like I expect it the metric that shows the average task time looks like this:

avg-time-chart

Here you can see that the metric is reseted several times. That is nothing that I do in code, it happens automatically. It looks like that is a "feature" of our Accumulator metrics.

Open Telemetry has a feature for the SUM metrics that allows to define if the metric should be defined as a delta metric or a cumulative metric (see https://opentelemetry.io/docs/specs/otel/metrics/data-model/#sums).

For our metrics it would be create if we could have something similar. Maybe we automatically create 2 metrics for each Accumulator (one that holds the delta and another one that holds a cumulative value that is calculated by each snapshot).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.