To analyze metrics from different application instances, hosts, regions ..., additional (usually platform specific) common tags are required to allow distinguishing and aggregating the metrics across those different platforms, instances and environments...
While the MeterRegistryCustomizer allows adding common tags, it implies that every time a new tag is need the target boot application will have to be re-compiled. Furthermore the boot app will have to hardcode, keep and broadcast the superset of all added tags, although only subset of those might be required in a given deployment environment.
This problem is visible in Spring Cloud Data Flow and Spring Cloud Streams App Starters where certain SCDF specific tags (such as stream name, app guid, app type, instance id) are need for all apps and each Spring Cloud Deployer requires its own specific tags as well.
Therefore a declarative mechanism for setting common tags at application deployment time is required. For example by using application property like this: management.metrics.tags=<my-tag-name>:<my-tag-value>
cc @jkschneider
Adding property-based configuration for this makes sense to me (although I'd like some confirmation from @jkschneider before we implement anything). One change I'd make from the proposal above is to use a Map<String, String> for tags so that the properties would be like this:
management.metrics.tags.<my-tag-name> = <my-tag-value>
Looks good @wilkinsona. The order of common tags is important to graphite users. Can we guarantee such an ordering within a props file?
Can we guarantee such an ordering within a props file?
We can't as the resulting Properties object is unordered. I don't think we can guarantee the order in YAML either when it's a map. To guarantee the order, we'd have to use a List. It'd look a bit like this in a properties file:
management.metrics.tags[0].name=a
management.metrics.tags[0].value=alpha
And this in YAML:
management:
metrics:
tags:
- name: a
value: alpha
That feels like a big burden to place on everyone for something that only Graphite users care about.
The original proposal is actually slightly better in this regard. If management.metrics.tags had a value that was comma-separated name:value pairs then the ordering of those pairs would define the ordering of the tags. Downsides of that approach are that it requires you to know the name:value syntax and it also prevents you from using , or : in the name or value of an entry unless we support some form of escaping too.
It looks to me like a decision between something that's easiest to configure but doesn't help Graphite users or something that's slightly harder to configure and will be of use to everyone. Anyone who doesn't like what we do can always roll their own property-based configuration with a custom MeterRegistryCustomizer. Due to that, I'm leaning slightly towards serving the many as well as we can, going with management.metrics.tags.<my-tag-name> = <my-tag-value>, and documenting that Graphite users shouldn't use it.
Thanks for the detail @wilkinsona, and agree. If it were easy to accomodate Graphite users, great. If not, let's do what's best for the majority of folks going forward. Graphite isn't exactly gaining market share at this point.
@snicoll - could you consider adding this to 2.0.3 ?
@maximusfloydus I am afraid not, 2.0.x is in maintenance mode and this is a new feature that does not block you in any way as registering a MeterFilter is very easy.
馃憤 for following semantic versioning! I created something similar for my projects already, just planning when I can deprecate it.
I'm assuming, this feature is tracked as part of https://github.com/micrometer-metrics/micrometer/issues/646?
@ghost That's right!
Most helpful comment
Adding property-based configuration for this makes sense to me (although I'd like some confirmation from @jkschneider before we implement anything). One change I'd make from the proposal above is to use a
Map<String, String>for tags so that the properties would be like this: