DefaultWebMvcTagsProvider Code Flow. #2767
Labels
bug
A general bug
registry: prometheus
A Prometheus Registry related issue
waiting for feedback
We need additional information before we can continue
Describe the bug
The code workflow when adding tags to Prometheus registry is erreneous
Environment
Springboot: 2.4.1
openjdk version "11.0.11" 2021-04-20 LTS
OpenJDK Runtime Environment SapMachine (build 11.0.11+9-LTS-sapmachine)
OpenJDK 64-Bit Server VM SapMachine (build 11.0.11+9-LTS-sapmachine, mixed mode)]
To Reproduce
How to reproduce the bug:
Sample Code used for WebMvcTagsContributor Bean:
BreakPoints Useful when debugging: applyToCollector
applytoCollector-2
CollectorResistry.register(Collector)
Expected behavior
The DefaultMvcProvider populates the tags before the code execution reaches PrometheusRegistry.
Additional context
Bug in PrometheusMeterRegistry
ERROR:
Collector already registered that provides name: http_server_requests_seconds
By surfing on web for quick fixes on the internet for this issue found the following articles:
https://stackoverflow.com/questions/52893435/including-spring-boot-endpoint-path-variable-as-a-metric-dimension
#2399
prometheus/client_java#279
Although These articles discuss the error faced by me they are caused by a different requirement. i.e to have different tags for the same metric.
But we need the same tags for the metric throughout the runtime of application.
Dependencies Used:
io.micrometer:micrometer-registry-prometheus:1.6.2
Then i started to debug the application and found the following.
When Using "WebMvcTagsContributor" Bean or extending "WebMvcTagsProvider" configuration
The call to applyToCollector checks if the metric has a MicrometerCollector entry for the metric and if it doesn't, it would add it to the collector.
When checking the MicrometerCollectorentry the default tags are being used micrometerCollector.register(registry)
There are default tags assosciated to the metric here are without invocation of "DefaultWebMvcTagsProvider.getTags()", Not sure how this is being populated.
This method returns Collector.register(CollectorRegistry) -> CollectorResistry.register(Collector) Here the Collecter is populated with default tags.
Ater this execution is complete.
It follows to "DefaultWebMvcTagsProvider.getTags()", here the additional tags that are provided in the bean are populated.
Following the above tag reassignment it again proceeds to applyToCollector
Since the entry for MicrometerCollector is populated the method would direct to
if clause existingCollector.getTagKeys().equals(tagKeys)applytoCollector-2 There is a mismatch because of the nely added tags from defaultmvctags provider.
And for this reason the CollectorMap in PrometheusMeterRegistry is not updated whereas the collector is populated with default tags, when a new request arrives PrometheusMeterRegistry will try to populate the collecor with an existing entry.
This causes an exception like following:
Collector already registered that provides name: http_server_requests_seconds
The text was updated successfully, but these errors were encountered: