From c71196b92d232c7a7431658810b84031ed794e34 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 8 Jul 2015 09:42:35 +0100 Subject: [PATCH] Better segregation of export and redis keys --- .../MetricExportAutoConfiguration.java | 14 +-- .../export/MetricExportProperties.java | 93 +++++++++++++------ .../redis/AggregateMetricsConfiguration.java | 1 + .../src/main/resources/application.properties | 4 +- 4 files changed, 76 insertions(+), 36 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfiguration.java index 897893fc97..4699151b10 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfiguration.java @@ -85,18 +85,20 @@ public class MetricExportAutoConfiguration { @Configuration protected static class MetricExportPropertiesConfiguration { - @Value("spring.metrics.${spring.application.name:application}.${random.value:0000}") - private String prefix = "spring.metrics"; + @Value("${spring.application.name:application}.${random.value:0000}") + private String prefix = ""; - @Value("d.d.k.d") - private String aggregateKeyPattern = ""; + private String aggregateKeyPattern = "k.d"; @Bean(name = "spring.metrics.export.CONFIGURATION_PROPERTIES") @ConditionalOnMissingBean public MetricExportProperties metricExportProperties() { MetricExportProperties export = new MetricExportProperties(); - export.getRedis().setPrefix(this.prefix); - export.getRedis().setAggregateKeyPattern(this.aggregateKeyPattern); + export.getRedis().setPrefix( + "spring.metrics" + (this.prefix.length() > 0 ? "." : "") + + this.prefix); + export.getAggregate().setPrefix(this.prefix); + export.getAggregate().setKeyPattern(this.aggregateKeyPattern); return export; } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExportProperties.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExportProperties.java index d51ee7e948..aacfdbf176 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExportProperties.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExportProperties.java @@ -39,6 +39,8 @@ public class MetricExportProperties extends TriggerProperties { */ private Map triggers = new LinkedHashMap(); + private Aggregate aggregate = new Aggregate(); + private Redis redis = new Redis(); @PostConstruct @@ -85,6 +87,14 @@ public class MetricExportProperties extends TriggerProperties { this.redis = redis; } + public Aggregate getAggregate() { + return this.aggregate; + } + + public void setAggregate(Aggregate aggregate) { + this.aggregate = aggregate; + } + /** * Find a matching trigger configuration. * @param name the bean name to match @@ -102,30 +112,17 @@ public class MetricExportProperties extends TriggerProperties { public static class Redis { /** - * Prefix for redis repository if active. Should be unique for this JVM, but most - * useful if it also has the form "x.y.a.b" where "x.y" is globally unique across - * all processes sharing the same repository, "a" is unique to this logical - * process (this application) and "b" is unique to this physical process. If you - * set spring.application.name elsewhere, then the default will be in the right - * form. + * Prefix for redis repository if active. Should be globally unique across all + * processes sharing the same repository. */ private String prefix = "spring.metrics"; /** * Key for redis repository export (if active). Should be globally unique for a - * system sharing a redis repository. + * system sharing a redis repository across multiple processes. */ private String key = "keys.spring.metrics"; - /** - * Pattern that tells the aggregator what to do with the keys from the source - * repository. The keys in the source repository are assumed to be period - * separated, and the pattern is in the same format, e.g. "d.d.k.d". Here "d" - * means "discard" and "k" means "keep" the key segment in the corresponding - * position in the source. - */ - private String aggregateKeyPattern = ""; - public String getPrefix() { return this.prefix; } @@ -142,26 +139,64 @@ public class MetricExportProperties extends TriggerProperties { this.key = key; } - public String getAggregateKeyPattern() { - return this.aggregateKeyPattern; - } - - public void setAggregateKeyPattern(String keyPattern) { - this.aggregateKeyPattern = keyPattern; - } - public String getAggregatePrefix() { + // The common case including a standalone aggregator would have a prefix that + // starts with the end of the key, so strip that bit off and call it the + // aggregate prefix. if (this.key.startsWith("keys.")) { - return this.key.substring("keys.".length()); + String candidate = this.key.substring("keys.".length()); + if (this.prefix.startsWith(candidate)) { + return candidate; + } + return candidate; } - // Something that is safe (not empty) but not the whole prefix (on the - // assumption that it contains dimension keys) - if (this.prefix.contains(".") && !this.prefix.endsWith(".")) { - return this.prefix.substring(this.prefix.indexOf("." + 1)); + // If the user went off piste, choose something that is safe (not empty) but + // not the whole prefix (on the assumption that it contains dimension keys) + if (this.prefix.contains(".") + && this.prefix.indexOf(".") < this.prefix.length() - 1) { + return this.prefix.substring(this.prefix.indexOf(".") + 1); } return this.prefix; } } + public static class Aggregate { + + /** + * Prefix for global repository if active. Should be unique for this JVM, but most + * useful if it also has the form "a.b" where "a" is unique to this logical + * process (this application) and "b" is unique to this physical process. If you + * set spring.application.name elsewhere, then the default will be in the right + * form. + */ + private String prefix = ""; + + /** + * Pattern that tells the aggregator what to do with the keys from the source + * repository. The keys in the source repository are assumed to be period + * separated, and the pattern is in the same format, e.g. "d.d.k.d". Here "d" + * means "discard" and "k" means "keep" the key segment in the corresponding + * position in the source. + */ + private String keyPattern = ""; + + public String getPrefix() { + return this.prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getKeyPattern() { + return this.keyPattern; + } + + public void setKeyPattern(String keyPattern) { + this.keyPattern = keyPattern; + } + + } + } diff --git a/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/AggregateMetricsConfiguration.java b/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/AggregateMetricsConfiguration.java index 0f82a691b6..163f2c2289 100644 --- a/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/AggregateMetricsConfiguration.java +++ b/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/AggregateMetricsConfiguration.java @@ -49,6 +49,7 @@ public class AggregateMetricsConfiguration { private MetricReader aggregatesMetricReader() { AggregateMetricReader repository = new AggregateMetricReader( globalMetricsForAggregation()); + repository.setKeyPattern(this.export.getAggregate().getKeyPattern()); return repository; } } diff --git a/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/resources/application.properties index 55bd86821d..26fa18e930 100644 --- a/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/resources/application.properties +++ b/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/resources/application.properties @@ -1,4 +1,6 @@ service.name: Phil -spring.metrics.export.redis.prefix: metrics.sample.${random.value:0000}.${spring.application.name:application} +spring.metrics.export.redis.prefix: metrics.sample.${spring.metrics.export.aggregate.prefix} spring.metrics.export.redis.key: keys.metrics.sample +spring.metrics.export.aggregate.prefix: ${random.value:0000}.${spring.application.name:application} +spring.metrics.export.aggregate.key-pattern: d spring.jmx.default-domain: org.springframework.boot