hiero-ledger / hiero-ledger/hiero-consensus-node
Missing features of Metrics API - labels & cumulative results
- 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.
## 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:
While that looks exactly like I expect it the metric that shows the average task time looks like this:
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
Assessment
This issue has not been assessed yet.