-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use labels in prometheus metrics #1681
Use labels in prometheus metrics #1681
Conversation
public SampleBuilder labelsSampleBuilder() { | ||
final List<MapperConfig> mapperConfigs = new ArrayList<>(); | ||
|
||
mapperConfigs.addAll(accountModuleMapperConfigs()); | ||
mapperConfigs.addAll(moduleMapperConfigs()); | ||
mapperConfigs.addAll(accountMapperConfigs()); | ||
mapperConfigs.addAll(adapterMapperConfigs()); | ||
// other | ||
mapperConfigs.add(requestsOk); | ||
mapperConfigs.add(bidderCardinality); | ||
mapperConfigs.addAll(privacyMappingConfigs()); | ||
mapperConfigs.addAll(vertxResponseConfig); | ||
mapperConfigs.addAll(vertxRequestConfigs); | ||
mapperConfigs.add(vertxServer); | ||
|
||
return new CustomMappingSampleBuilder(mapperConfigs); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets utilize Spring and make this method simpler:
@Bean
@ConditionalOnProperty(prefix = "metrics.prometheus.labels", name = "enabled", havingValue = "true")
public SampleBuilder labelsSampleBuilder(List<MapperConfig> mapperConfigs) {
return new CustomMappingSampleBuilder(mapperConfigs);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done 👍🏻 But I had to use a List<List<MapperConfig>>
because Spring didn't like the max of
@Bean
public MapperConfig mapperConfig() {}
and
@Bean
public List<MapperConfig> mapperConfig() {}
so that the last Bean doesn't overwrite all other Bean declarations
private final MapperConfig requestsOk = new MapperConfig( | ||
"requests.*.*", | ||
"requests.status.type", | ||
Map.of("status", "${0}", "type", "${1}") | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make all these fields Spring beans and extract groups of related mappings to separate configuration.
Also, we are not breaking line for );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
private final List<MapperConfig> vertxRequestConfigs = Stream.of( | ||
"get", "post", "head", "delete", "connect", "options", "patch", "put", "other", "trace" | ||
).map(request -> new MapperConfig( | ||
"vertx.http.clients." + request + "-requests", | ||
"vertx.http.clients.requests_by_type", | ||
Map.of("request", request) | ||
) | ||
|
||
).collect(Collectors.toList()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with our code style it would be:
Stream.of("get", "post", "head", "delete", "connect", "options", "patch", "put", "other", "trace")
.map(request -> new MapperConfig(
"vertx.http.clients." + request + "-requests",
"vertx.http.clients.requests_by_type",
Map.of("request", request)))
.collect(Collectors.toList());
Also, this should be a bean provider method, as i said before:
@Bean
public List<MapperConfig> vertxRequestMapperConfigs() {
return Stream.of("get", "post", "head", "delete", "connect", "options", "patch", "put", "other", "trace")
.map(request -> new MapperConfig(
"vertx.http.clients." + request + "-requests",
"vertx.http.clients.requests_by_type",
Map.of("request", request)))
.collect(Collectors.toList());
}
Please, refactor other mappings to follow this pattern.
final MapperConfig privacyTcfMissing = new MapperConfig( | ||
"privacy.tcf.missing", | ||
"privacy.tcf.errors", | ||
Map.of("error", "missing")); | ||
|
||
final MapperConfig privacyTcfInvalid = new MapperConfig( | ||
"privacy.tcf.invalid", | ||
"privacy.tcf.errors", | ||
Map.of("error", "invalid")); | ||
|
||
final MapperConfig privacyVendorList = new MapperConfig( | ||
"privacy.tcf.*.vendorlist.*", | ||
"privacy.tcf.vendorlist", | ||
Map.of("tcf", "${0}", "status", "${1}")); | ||
|
||
final MapperConfig privacyTcfStatus = new MapperConfig( | ||
"privacy.tcf.*.*", | ||
"privacy.tcf.${1}", | ||
Map.of("tcf", "${0}")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of these should be separate beans. Could be extracted to separate configuration.
final MapperConfig accountRequestTime = new MapperConfig( | ||
"account.*.adapter.*.request_time", | ||
"account.request_time", | ||
Map.of("account", "${0}", "adapter", "${1}") | ||
); | ||
|
||
// example: account.<account>.adapter.appnexus.requests.gotbids | ||
final MapperConfig accountAdapterRequests = new MapperConfig( | ||
"account.*.adapter.*.requests.*", | ||
"account.requests.responses", | ||
Map.of("account", "${0}", "adapter", "${1}", "response", "${2}") | ||
); | ||
|
||
// example: account.<account>.adapter.appnexus.bids_received | ||
final MapperConfig accountAdapterBidsReceived = new MapperConfig( | ||
"account.*.adapter.*.bids_received", | ||
"account.bids_received", | ||
Map.of("account", "${0}", "adapter", "${1}") | ||
); | ||
|
||
// example: account.<account>.requests.type.openrtb2-web | ||
final MapperConfig accountRequestTypeConfig = new MapperConfig( | ||
"account.*.requests.type.*", | ||
"account.requests.type", | ||
Map.of("account", "${0}", "type", "${1}") | ||
); | ||
|
||
// example: account_<account>_adapter_pubmatic_prices | ||
final MapperConfig accountPricesConfig = new MapperConfig( | ||
"account.*.adapter.*.prices", | ||
"account.prices", | ||
Map.of("account", "${0}", "adapter", "${1}") | ||
); | ||
|
||
// example: adapter.yieldlab.response.validation.size.warn | ||
final MapperConfig accountValidationConfig = new MapperConfig( | ||
"account.*.response.validation.*.*", | ||
"account.response.validation", | ||
Map.of("account", "${0}", "validation", "${1}", "level", "${2}") | ||
); | ||
|
||
// example: account.<account>.requests | ||
final MapperConfig accountCacheConfig = new MapperConfig( | ||
"account.*.prebid_cache.requests.*", | ||
"account.requests.type", | ||
Map.of("account", "${0}", "result", "${1}") | ||
); | ||
|
||
// example: account.<account>.requests | ||
final MapperConfig accountRequestsConfig = new MapperConfig( | ||
"account.*.requests", | ||
"account.requests.type", | ||
Map.of("account", "${0}") | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
final MapperConfig adapterRequestTime = new MapperConfig( | ||
"adapter.*.request_time", | ||
"adapter.request_time", | ||
Map.of("adapter", "${0}") | ||
); | ||
|
||
// example: adapter.ix.requests.type.openrtb2-web | ||
final MapperConfig adapterRequestsType = new MapperConfig( | ||
"adapter.*.requests.type.*", | ||
"adapter.requests.type", | ||
Map.of("adapter", "${0}", "type", "${1}") | ||
); | ||
|
||
// example: adapter.yieldlab.requests.nobid | ||
// example: adapter.yieldlab.requests.timeout | ||
// example: adapter.yieldlab.requests.unknown_error | ||
// example: adapter.yieldlab.requests.gotbids | ||
final MapperConfig adapterRequestsResult = new MapperConfig( | ||
"adapter.*.requests.*", | ||
"adapter.requests.result", | ||
Map.of("adapter", "${0}", "result", "${1}") | ||
); | ||
|
||
// example: adapter.pubmatic.bids_received | ||
final MapperConfig adapterBidsReceived = new MapperConfig( | ||
"adapter.*.bids_received", | ||
"adapter.bids_received", | ||
Map.of("adapter", "${0}") | ||
); | ||
|
||
// example: adapter.pubmatic.price | ||
final MapperConfig adapterPrices = new MapperConfig( | ||
"adapter.*.prices", | ||
"adapter.prices", | ||
Map.of("adapter", "${0}") | ||
); | ||
|
||
// example: adapter.yieldlab.response.validation.size.warn | ||
final MapperConfig adapterValidation = new MapperConfig( | ||
"adapter.*.response.validation.*.*", | ||
"adapter.response.validation", | ||
Map.of("adapter", "${0}", "validation", "${1}", "level", "${2}") | ||
); | ||
|
||
// example: adapter.yieldlab.no_cookie_requests | ||
final MapperConfig adapterNoCookieConfig = new MapperConfig( | ||
"adapter.*.no_cookie_requests", | ||
"adapter.no_cookie_requests", | ||
Map.of("adapter", "${0}") | ||
); | ||
|
||
// example: adapter.ix.openrtb2-web.tcf.request_blocked | ||
final MapperConfig adapterRequestTypeTcfConfig = new MapperConfig( | ||
"adapter.*.*.tcf.*", | ||
"adapter.tcf", | ||
Map.of("adapter", "${0}", "type", "${1}", "tcf", "${2}") | ||
); | ||
|
||
// example: adapter.appnexus.banner.adm_bids_received | ||
// example: adapter.appnexus.xNative.adm_bids_received | ||
final MapperConfig adapterMediaType = new MapperConfig( | ||
"adapter.*.*.*", | ||
"adapter.media_type", | ||
Map.of("adapter", "${0}", "mediaType", "${1}", "metric", "${2}") | ||
); | ||
|
||
// example: cookie_sync.rubicon.tcf.blocked | ||
final MapperConfig adapterCookieSyncTcfConfig = new MapperConfig( | ||
"cookie_sync.*.tcf.*", | ||
"adapter.cookie_sync.tcf", | ||
Map.of("adapter", "${0}", "tcf", "${1}") | ||
); | ||
|
||
// example: cookie_sync.appnexus.gen | ||
// example: cookie_sync.ix.matches | ||
final MapperConfig adapterGenCookieConfig = new MapperConfig( | ||
"cookie_sync.*.*", | ||
"adapter.cookie_sync.action", | ||
Map.of("adapter", "${0}", "action", "${1}") | ||
); | ||
|
||
// example: usersync.triplelift.sets | ||
final MapperConfig adapterUserSyncSets = new MapperConfig( | ||
"usersync.*.*", | ||
"adapter.usersync.action", | ||
Map.of("adapter", "${0}", "action", "${1}") | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
I saw there are other changes in #1802 Would it be possible to merge this first when the comments are resolved? |
@rmattis Pls merge master to this PR, to fix functional tests github action |
@SerhiiNahornyi Done |
The current prometheus implementation doesn't allow the usage of Prometheus labels.
To overcome this, we used the
MapperConfig
feature to allow Dropwizard parsing the labels out of the metrics path.To enable the feature it is necessary to set
metrics.prometheus.labels.enabled
totrue
. Otherwise it'll just stay as it is.