Skip to content

Prometheus: unnecessary allocation and validation performed on every scrape #7450

@m-burst

Description

@m-burst

See this part of code (taken from commit at v1.16.5):

@Override
public Counter newCounter(Meter.Id id) {
PrometheusCounter counter = new PrometheusCounter(id, exemplarSamplerFactory);
long createdTimestampMillis = clock.wallTime();
applyToCollector(id, (collector) -> {
List<String> tagValues = tagValues(id);
collector
.add(tagValues, (conventionName, tagKeys) -> Stream.of(new MicrometerCollector.Family<>(conventionName,
family -> new CounterSnapshot(family.metadata, family.dataPointSnapshots),
getMetadata(conventionName, id.getDescription()), new CounterDataPointSnapshot(counter.count(),
Labels.of(tagKeys, tagValues), counter.exemplar(), createdTimestampMillis))));
});
return counter;
}

getMetadata and Labels.of are called within the inner lambda, the one that implements Child and is called on every scrape. These calls construct the same Metadata and Labels objects over and over, which in turn also performs repeated validation (PrometheusNaming.validateMetricName and PrometheusNaming.validateLabelName), verifying on each scrape that the metric name and label names are valid UTF-8.

The Metadata and Labels can in fact be created and validated once, because the conventionName and tagKeys are stored in the MicrometerCollector and not modified during its lifetime. This will make scraping more efficient in terms of performance and garbage.

The same applies to all meter types, not only to counters.

If the maintainers agree with the idea of this change, I can open a PR to implement it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementA general enhancementperformanceIssues related to general performanceregistry: prometheusA Prometheus Registry related issue

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions