Prometheus: NewPrometheus constructor shall accept a config struct #92
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The prometheus middleware is difficult to extend. Not only because the existing
NewPrometheus
constructor has no way to extend the arguments passed, but also the imperativePrometheus.SetFoo
style of configuration that is currently supported is difficult to reason about.This PR creates a new constructor called
prometheus.NewPrometheusWithConfig
which accepts aprometheus.PrometheusConfig
struct as an argument. The PrometheusConfig struct is by nature much more extensible because additional fields can be invented without breaking any existing clients. This resolves the issue referenced in #80This PR uses this new PrometheusConfig struct to add 2 forms of extensibility:
PrometheusConfig.LabelDescriminators
field can be used to add additional labels to the metrics in prometheus. The keys of this mapping are the names of the labels to add. The values in this mapping are the discriminators that will be used to populate these fields. This resolves the issue referenced in Is there a way to add custom labels to the standard prometheus metrics? #85Prometheus.labelDescriminators["code"]
entry.PrometheusConfig.Registerer
andPrometheusConfig.Gatherer
allow users to use a prometheus registry other thanprometheus.DefaultRegistery
- this is particularly helpful in unit tests. This resolves the issue referenced in Mock Prometheus Middleware in unit tests echo#2419 . I initially hoped to handle this registry issue in a separate PR, but I needed the ability to specify my own registry in order to properly test the LabelDescriminators code because prometheus would otherwise complain that the labels are inconsistent between test cases.Testing done
Please note that there are many test cases referencing the old
prometheus.NewPrometheus
constructor. This constructor now uses the newprometheus.NewPrometheusWithConfig
constructor under the hood, so those existing unit tests provide a reasonable degree of confidence that there haven't been any regressions.I've added an additional test case to cover the LabelDescriminators config piece. This test case defines an additional label called
userAgent
along with a function that populates this label given the User-Agent header from the request. This new test also covers thePrometheusConfig.{Registerer,Gatherer}
fields. If we were to use theprometheus.DefaultRegistry
here, the middleware would get an error when trying to register the labels because the labels from this test are different from the labels from other tests. Using a private registry prevents the conflict.