Add redis properties as convenience in spring.metrics.export
The redis export and aggregate use case is a lot nicer with this shared data between the two component types. Also made MetricExportProperties itself a Trigger (so the default delay etc. can be configured via spring.metrics.export.*).
This commit is contained in:
parent
e8e89f3738
commit
80ff92919c
|
|
@ -16,30 +16,31 @@
|
|||
|
||||
package org.springframework.boot.actuate.metrics.export;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConfigurationProperties("spring.metrics.export")
|
||||
public class MetricExportProperties {
|
||||
public class MetricExportProperties extends Trigger {
|
||||
|
||||
/**
|
||||
* Flag to disable all metric exports (assuming any MetricWriters are available).
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
private Export export = new Export();
|
||||
private Map<String, SpecificTrigger> triggers = new LinkedHashMap<String, SpecificTrigger>();
|
||||
|
||||
private Map<String, Export> writers = new LinkedHashMap<String, Export>();
|
||||
private Redis redis = new Redis();
|
||||
|
||||
/**
|
||||
* Default values for trigger configuration for all writers. Can also be set by
|
||||
|
|
@ -47,8 +48,8 @@ public class MetricExportProperties {
|
|||
*
|
||||
* @return the default trigger configuration
|
||||
*/
|
||||
public Export getDefault() {
|
||||
return this.export;
|
||||
public Trigger getDefault() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -58,30 +59,27 @@ public class MetricExportProperties {
|
|||
*
|
||||
* @return the writers
|
||||
*/
|
||||
public Map<String, Export> getWriters() {
|
||||
return this.writers;
|
||||
public Map<String, SpecificTrigger> getTriggers() {
|
||||
return this.triggers;
|
||||
}
|
||||
|
||||
public Redis getRedis() {
|
||||
return redis;
|
||||
}
|
||||
|
||||
public void setRedis(Redis redis) {
|
||||
this.redis = redis;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void setUpDefaults() {
|
||||
Export defaults = null;
|
||||
for (Entry<String, Export> entry : this.writers.entrySet()) {
|
||||
Trigger defaults = this;
|
||||
for (Entry<String, SpecificTrigger> entry : this.triggers.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Export value = entry.getValue();
|
||||
SpecificTrigger value = entry.getValue();
|
||||
if (value.getNames() == null || value.getNames().length == 0) {
|
||||
value.setNames(new String[] { key });
|
||||
}
|
||||
if (Arrays.asList(value.getNames()).contains("*")) {
|
||||
defaults = value;
|
||||
}
|
||||
}
|
||||
if (defaults == null) {
|
||||
this.export.setNames(new String[] { "*" });
|
||||
this.writers.put("*", this.export);
|
||||
defaults = this.export;
|
||||
}
|
||||
if (defaults.isIgnoreTimestamps() == null) {
|
||||
defaults.setIgnoreTimestamps(false);
|
||||
}
|
||||
if (defaults.isSendLatest() == null) {
|
||||
defaults.setSendLatest(true);
|
||||
|
|
@ -89,10 +87,7 @@ public class MetricExportProperties {
|
|||
if (defaults.getDelayMillis() == null) {
|
||||
defaults.setDelayMillis(5000);
|
||||
}
|
||||
for (Export value : this.writers.values()) {
|
||||
if (value.isIgnoreTimestamps() == null) {
|
||||
value.setIgnoreTimestamps(defaults.isIgnoreTimestamps());
|
||||
}
|
||||
for (Trigger value : this.triggers.values()) {
|
||||
if (value.isSendLatest() == null) {
|
||||
value.setSendLatest(defaults.isSendLatest());
|
||||
}
|
||||
|
|
@ -110,37 +105,29 @@ public class MetricExportProperties {
|
|||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public static class Export {
|
||||
/**
|
||||
* Find a matching trigger configuration.
|
||||
* @param name the bean name to match
|
||||
* @return a matching configuration if there is one
|
||||
*/
|
||||
public Trigger findTrigger(String name) {
|
||||
for (SpecificTrigger value : this.triggers.values()) {
|
||||
if (PatternMatchUtils.simpleMatch(value.getNames(), name)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger for specific bean names.
|
||||
*/
|
||||
public static class SpecificTrigger extends Trigger {
|
||||
|
||||
/**
|
||||
* Names (or patterns) for bean names that this configuration applies to.
|
||||
*/
|
||||
private String[] names;
|
||||
/**
|
||||
* Delay in milliseconds between export ticks. Metrics are exported to external
|
||||
* sources on a schedule with this delay.
|
||||
*/
|
||||
private Long delayMillis;
|
||||
|
||||
/**
|
||||
* Flag to enable metric export (assuming a MetricWriter is available).
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Flag to switch off any available optimizations based on not exporting unchanged
|
||||
* metric values.
|
||||
*/
|
||||
private Boolean sendLatest;
|
||||
|
||||
/**
|
||||
* Flag to ignore timestamps completely. If true, send all metrics all the time,
|
||||
* including ones that haven't changed since startup.
|
||||
*/
|
||||
private Boolean ignoreTimestamps;
|
||||
|
||||
private String[] includes;
|
||||
|
||||
private String[] excludes;
|
||||
|
||||
public String[] getNames() {
|
||||
return this.names;
|
||||
|
|
@ -150,66 +137,119 @@ public class MetricExportProperties {
|
|||
this.names = names;
|
||||
}
|
||||
|
||||
public String[] getIncludes() {
|
||||
return this.includes;
|
||||
}
|
||||
|
||||
public void setIncludes(String[] includes) {
|
||||
this.includes = includes;
|
||||
}
|
||||
|
||||
public void setExcludes(String[] excludes) {
|
||||
this.excludes = excludes;
|
||||
}
|
||||
|
||||
public String[] getExcludes() {
|
||||
return this.excludes;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Long getDelayMillis() {
|
||||
return this.delayMillis;
|
||||
}
|
||||
|
||||
public void setDelayMillis(long delayMillis) {
|
||||
this.delayMillis = delayMillis;
|
||||
}
|
||||
|
||||
public Boolean isIgnoreTimestamps() {
|
||||
return this.ignoreTimestamps;
|
||||
}
|
||||
|
||||
public void setIgnoreTimestamps(boolean ignoreTimestamps) {
|
||||
this.ignoreTimestamps = ignoreTimestamps;
|
||||
}
|
||||
|
||||
public Boolean isSendLatest() {
|
||||
return this.sendLatest;
|
||||
}
|
||||
|
||||
public void setSendLatest(boolean sendLatest) {
|
||||
this.sendLatest = sendLatest;
|
||||
}
|
||||
}
|
||||
|
||||
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 physical
|
||||
* process and "b" is unique to this logical process (this application). If you
|
||||
* set spring.application.name elsewhere, then the default will be in the right
|
||||
* form.
|
||||
*/
|
||||
@Value("spring.metrics.${random.value:0000}.${spring.application.name:application}")
|
||||
private String prefix = "spring.metrics";
|
||||
|
||||
/**
|
||||
* Key for redis repository export (if active). Should be globally unique for a
|
||||
* system sharing a redis repository.
|
||||
*/
|
||||
private String key = "keys.spring.metrics";
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getAggregatePrefix() {
|
||||
String[] tokens = StringUtils.delimitedListToStringArray(this.prefix, ".");
|
||||
if (tokens.length > 1) {
|
||||
if (StringUtils.hasText(tokens[1])) {
|
||||
// If the prefix has 2 or more non-trivial parts, use the first 1
|
||||
return tokens[0];
|
||||
}
|
||||
}
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Trigger {
|
||||
|
||||
/**
|
||||
* Find a matching trigger configuration.
|
||||
* @param name the bean name to match
|
||||
* @return a matching configuration if there is one
|
||||
* Delay in milliseconds between export ticks. Metrics are exported to external
|
||||
* sources on a schedule with this delay.
|
||||
*/
|
||||
public Export findExport(String name) {
|
||||
for (Export value : this.writers.values()) {
|
||||
if (PatternMatchUtils.simpleMatch(value.getNames(), name)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return this.export;
|
||||
private Long delayMillis;
|
||||
|
||||
/**
|
||||
* Flag to enable metric export (assuming a MetricWriter is available).
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Flag to switch off any available optimizations based on not exporting unchanged
|
||||
* metric values.
|
||||
*/
|
||||
private Boolean sendLatest;
|
||||
|
||||
private String[] includes;
|
||||
|
||||
private String[] excludes;
|
||||
|
||||
public String[] getIncludes() {
|
||||
return this.includes;
|
||||
}
|
||||
|
||||
public void setIncludes(String[] includes) {
|
||||
this.includes = includes;
|
||||
}
|
||||
|
||||
public void setExcludes(String[] excludes) {
|
||||
this.excludes = excludes;
|
||||
}
|
||||
|
||||
public String[] getExcludes() {
|
||||
return this.excludes;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Long getDelayMillis() {
|
||||
return this.delayMillis;
|
||||
}
|
||||
|
||||
public void setDelayMillis(long delayMillis) {
|
||||
this.delayMillis = delayMillis;
|
||||
}
|
||||
|
||||
public Boolean isSendLatest() {
|
||||
return this.sendLatest;
|
||||
}
|
||||
|
||||
public void setSendLatest(boolean sendLatest) {
|
||||
this.sendLatest = sendLatest;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.export.MetricExportProperties.Export;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
|
||||
import org.springframework.scheduling.annotation.SchedulingConfigurer;
|
||||
|
|
@ -56,7 +55,7 @@ public class MetricExporters implements SchedulingConfigurer {
|
|||
|
||||
for (Entry<String, MetricWriter> entry : this.writers.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
Export trigger = this.export.findExport(name);
|
||||
Trigger trigger = this.export.findTrigger(name);
|
||||
|
||||
if (trigger != null) {
|
||||
|
||||
|
|
@ -67,7 +66,6 @@ public class MetricExporters implements SchedulingConfigurer {
|
|||
exporter.setIncludes(trigger.getIncludes());
|
||||
exporter.setExcludes(trigger.getExcludes());
|
||||
}
|
||||
exporter.setIgnoreTimestamps(trigger.isIgnoreTimestamps());
|
||||
exporter.setSendLatest(trigger.isSendLatest());
|
||||
|
||||
this.exporters.put(name, exporter);
|
||||
|
|
|
|||
|
|
@ -910,7 +910,7 @@ used by default if you are on Java 8 or if you are using Dropwizard metrics.
|
|||
|
||||
|
||||
[[production-ready-metric-writers]]
|
||||
=== Metric writers and aggregation
|
||||
=== Metric writers, exporters and aggregation
|
||||
|
||||
Spring Boot provides a couple of implementations of a marker interface called `Exporter`
|
||||
which can be used to copy metric readings from the in-memory buffers to a place where they
|
||||
|
|
@ -919,11 +919,20 @@ can be analysed and displayed. Indeed, if you provide a `@Bean` that implements
|
|||
metric updates every 5 seconds (configured via `spring.metrics.export.delayMillis`) via a
|
||||
`@Scheduled` annotation in `MetricRepositoryAutoConfiguration`.
|
||||
|
||||
The default exporter is a `MetricCopyExporter` which tries to optimize itself by not
|
||||
copying values that haven't changed since it was last called. The optimization can be
|
||||
switched off using a flag (`spring.metrics.export.ignoreTimestamps`). Note also that the
|
||||
`MetricRegistry` has no support for timestamps, so the optimization is not available if
|
||||
you are using Dropwizard metrics (all metrics will be copied on every tick).
|
||||
The default exporter is a `MetricCopyExporter` which tries to optimize
|
||||
itself by not copying values that haven't changed since it was last
|
||||
called (the optimization can be switched off using a flag
|
||||
`spring.metrics.export.sendLatest`). Note also that the Dropwizard
|
||||
`MetricRegistry` has no support for timestamps, so the optimization is
|
||||
not available if you are using Dropwizard metrics (all metrics will be
|
||||
copied on every tick).
|
||||
|
||||
The default values for the export trigger (`delayMillis`, `includes`,
|
||||
`excludes`, `ignoreTimestamps` and `sendLatest`) can be set as
|
||||
`spring.metrics.export.*`. Individual values for specific
|
||||
`MetricWriters` can be set as
|
||||
`spring.metrics.export.triggers.<name>.*` where `<name>` is a bean
|
||||
name (or pattern for matching bean names).
|
||||
|
||||
|
||||
|
||||
|
|
@ -942,19 +951,20 @@ Example:
|
|||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
|
||||
@Value("metrics.mysystem.${random.value:0000}.${spring.application.name:application}")
|
||||
private String prefix = "metrics.mysystem";
|
||||
|
||||
@Value("${metrics.key:keys.mysystem}")
|
||||
private String key = "METRICSKEY";
|
||||
|
||||
@Bean
|
||||
MetricWriter metricWriter() {
|
||||
return new RedisMetricRepository(connectionFactory, prefix, key);
|
||||
MetricWriter metricWriter(MetricExportProperties export) {
|
||||
return new RedisMetricRepository(connectionFactory,
|
||||
export.getRedis().getPrefix(), export.getRedis().getKey());
|
||||
}
|
||||
----
|
||||
|
||||
.application.properties
|
||||
[source,properties]
|
||||
----
|
||||
spring.metrics.export.redis.prefix: metrics.mysystem.${random.value:0000}.${spring.application.name:application}
|
||||
spring.metrics.export.redis.key: keys.mysystem
|
||||
----
|
||||
|
||||
The prefix is constructed with the application name at the end, so it can easily be used
|
||||
to identify a group of processes with the same logical name later.
|
||||
|
||||
|
|
@ -967,6 +977,11 @@ start with the master prefix (like `metrics.mysystem.*` in the example above). I
|
|||
efficient to read all the keys from a "master" repository like that, but inefficient to
|
||||
read a subset with a longer prefix (e.g. using one of the writing repositories).
|
||||
|
||||
NOTE: the example above uses `MetricExportProperties` to inject and
|
||||
extract the key and prefix. This is provided to you as a convenience
|
||||
by Spring Boot, and the defaults for that will be sensible, but there
|
||||
is nothing to stop you using your own values as long as they follow
|
||||
the recommendations.
|
||||
|
||||
|
||||
[[production-ready-metric-writers-export-to-open-tdsb]]
|
||||
|
|
@ -1064,25 +1079,31 @@ results to the "/metrics" endpoint. Example:
|
|||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@Bean
|
||||
public PublicMetrics metricsAggregate() {
|
||||
return new MetricReaderPublicMetrics(aggregates());
|
||||
}
|
||||
@Autowired
|
||||
private MetricExportProperties export;
|
||||
|
||||
@Bean
|
||||
protected MetricReader repository(RedisConnectionFactory connectionFactory) {
|
||||
RedisMetricRepository repository = new RedisMetricRepository(connectionFactory,
|
||||
"mysystem", "myorg.keys");
|
||||
return repository;
|
||||
}
|
||||
@Bean
|
||||
public PublicMetrics metricsAggregate() {
|
||||
return new MetricReaderPublicMetrics(aggregates());
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected MetricReader aggregates() {
|
||||
AggregateMetricReader repository = new AggregateMetricReader(repository());
|
||||
return repository;
|
||||
}
|
||||
@Bean
|
||||
protected MetricReader repository(RedisConnectionFactory connectionFactory) {
|
||||
RedisMetricRepository repository = new RedisMetricRepository(connectionFactory,
|
||||
this.export.getRedis().getAggregatePrefix(), this.export.getRedis().getKey());
|
||||
return repository;
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected MetricReader aggregates() {
|
||||
AggregateMetricReader repository = new AggregateMetricReader(repository());
|
||||
return repository;
|
||||
}
|
||||
----
|
||||
|
||||
NOTE: the example above uses `MetricExportProperties` to inject and
|
||||
extract the key and prefix. This is provided to you as a convenience
|
||||
by Spring Boot, and the defaults for that will be sensible.
|
||||
|
||||
|
||||
[[production-ready-dropwizard-metrics]]
|
||||
|
|
@ -1134,33 +1155,33 @@ and obtain basic information about the last few requests:
|
|||
|
||||
[source,json,indent=0]
|
||||
----
|
||||
[{
|
||||
"timestamp": 1394343677415,
|
||||
"info": {
|
||||
"method": "GET",
|
||||
"path": "/trace",
|
||||
"headers": {
|
||||
"request": {
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||
"Connection": "keep-alive",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"User-Agent": "Mozilla/5.0 Gecko/Firefox",
|
||||
"Accept-Language": "en-US,en;q=0.5",
|
||||
"Cookie": "_ga=GA1.1.827067509.1390890128; ..."
|
||||
"Authorization": "Basic ...",
|
||||
"Host": "localhost:8080"
|
||||
},
|
||||
"response": {
|
||||
"Strict-Transport-Security": "max-age=31536000 ; includeSubDomains",
|
||||
"X-Application-Context": "application:8080",
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"status": "200"
|
||||
}
|
||||
}
|
||||
}
|
||||
},{
|
||||
"timestamp": 1394343684465,
|
||||
...
|
||||
[{
|
||||
"timestamp": 1394343677415,
|
||||
"info": {
|
||||
"method": "GET",
|
||||
"path": "/trace",
|
||||
"headers": {
|
||||
"request": {
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||
"Connection": "keep-alive",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"User-Agent": "Mozilla/5.0 Gecko/Firefox",
|
||||
"Accept-Language": "en-US,en;q=0.5",
|
||||
"Cookie": "_ga=GA1.1.827067509.1390890128; ..."
|
||||
"Authorization": "Basic ...",
|
||||
"Host": "localhost:8080"
|
||||
},
|
||||
"response": {
|
||||
"Strict-Transport-Security": "max-age=31536000 ; includeSubDomains",
|
||||
"X-Application-Context": "application:8080",
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"status": "200"
|
||||
}
|
||||
}
|
||||
}
|
||||
},{
|
||||
"timestamp": 1394343684465,
|
||||
...
|
||||
}]
|
||||
----
|
||||
|
||||
|
|
@ -1201,9 +1222,9 @@ In `META-INF/spring.factories` file you have to activate the listener(s):
|
|||
|
||||
[indent=0]
|
||||
----
|
||||
org.springframework.context.ApplicationListener=\
|
||||
org.springframework.boot.actuate.system.ApplicationPidFileWriter,
|
||||
org.springframework.boot.actuate.system.EmbeddedServerPortFileWriter
|
||||
org.springframework.context.ApplicationListener=\
|
||||
org.springframework.boot.actuate.system.ApplicationPidFileWriter,
|
||||
org.springframework.boot.actuate.system.EmbeddedServerPortFileWriter
|
||||
----
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.boot.actuate.endpoint.MetricReaderPublicMetrics;
|
||||
import org.springframework.boot.actuate.endpoint.PublicMetrics;
|
||||
import org.springframework.boot.actuate.metrics.aggregate.AggregateMetricReader;
|
||||
import org.springframework.boot.actuate.metrics.export.MetricExportProperties;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
import org.springframework.boot.actuate.metrics.repository.redis.RedisMetricRepository;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
|
@ -33,7 +34,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
|
|||
public class AggregateMetricsConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ExportProperties export;
|
||||
private MetricExportProperties export;
|
||||
|
||||
@Autowired
|
||||
private RedisConnectionFactory connectionFactory;
|
||||
|
|
@ -45,7 +46,7 @@ public class AggregateMetricsConfiguration {
|
|||
|
||||
private MetricReader globalMetricsForAggregation() {
|
||||
return new RedisMetricRepository(this.connectionFactory,
|
||||
this.export.getAggregatePrefix(), this.export.getKey());
|
||||
this.export.getRedis().getAggregatePrefix(), this.export.getRedis().getKey());
|
||||
}
|
||||
|
||||
private MetricReader aggregatesMetricReader() {
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.metrics.redis;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@ConfigurationProperties("redis.metrics.export")
|
||||
class ExportProperties {
|
||||
|
||||
private String prefix = "spring.metrics";
|
||||
private String key = "keys.spring.metrics";
|
||||
|
||||
public String getPrefix() {
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getAggregatePrefix() {
|
||||
String[] tokens = StringUtils.delimitedListToStringArray(this.prefix, ".");
|
||||
if (tokens.length > 1) {
|
||||
if (StringUtils.hasText(tokens[1])) {
|
||||
// If the prefix has 2 or more non-trivial parts, use the first 1
|
||||
return tokens[0];
|
||||
}
|
||||
}
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,20 +19,19 @@ package sample.metrics.redis;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.actuate.metrics.export.MetricExportProperties;
|
||||
import org.springframework.boot.actuate.metrics.jmx.JmxMetricWriter;
|
||||
import org.springframework.boot.actuate.metrics.repository.redis.RedisMetricRepository;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.jmx.export.MBeanExporter;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableConfigurationProperties(ExportProperties.class)
|
||||
public class SampleRedisExportApplication {
|
||||
|
||||
@Autowired
|
||||
private ExportProperties export;
|
||||
private MetricExportProperties export;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(SampleRedisExportApplication.class, args);
|
||||
|
|
@ -41,8 +40,8 @@ public class SampleRedisExportApplication {
|
|||
@Bean
|
||||
public RedisMetricRepository redisMetricWriter(
|
||||
RedisConnectionFactory connectionFactory) {
|
||||
return new RedisMetricRepository(connectionFactory, this.export.getPrefix(),
|
||||
this.export.getKey());
|
||||
return new RedisMetricRepository(connectionFactory, this.export.getRedis().getPrefix(),
|
||||
this.export.getRedis().getKey());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
service.name: Phil
|
||||
redis.metrics.export.prefix: metrics.sample.${random.value:0000}.${spring.application.name:application}
|
||||
redis.metrics.export.key: keys.metrics.sample
|
||||
spring.metrics.export.redis.prefix: metrics.sample.${random.value:0000}.${spring.application.name:application}
|
||||
spring.metrics.export.redis.key: keys.metrics.sample
|
||||
spring.jmx.default-domain: org.springframework.boot
|
||||
|
|
|
|||
Loading…
Reference in New Issue