Skip to content

Commit

Permalink
Add redis properties as convenience in spring.metrics.export
Browse files Browse the repository at this point in the history
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.*).
  • Loading branch information
dsyer committed May 31, 2015
1 parent e8e89f3 commit 80ff929
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 222 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,40 @@

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
* including a writer with <code>name="*"</code>.
*
* @return the default trigger configuration
*/
public Export getDefault() {
return this.export;
public Trigger getDefault() {
return this;
}

/**
Expand All @@ -58,41 +59,35 @@ public Export getDefault() {
*
* @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);
}
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());
}
Expand All @@ -110,37 +105,29 @@ public void setEnabled(boolean enabled) {
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;
Expand All @@ -150,66 +137,119 @@ public void setNames(String[] names) {
this.names = names;
}

public String[] getIncludes() {
return this.includes;
}
}

public void setIncludes(String[] includes) {
this.includes = includes;
}
public static class Redis {

public void setExcludes(String[] excludes) {
this.excludes = excludes;
}
/**
* 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";

public String[] getExcludes() {
return this.excludes;
}
/**
* 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 boolean isEnabled() {
return this.enabled;
public String getPrefix() {
return prefix;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
public void setPrefix(String prefix) {
this.prefix = prefix;
}

public Long getDelayMillis() {
return this.delayMillis;
public String getKey() {
return key;
}

public void setDelayMillis(long delayMillis) {
this.delayMillis = delayMillis;
public void setKey(String key) {
this.key = key;
}

public Boolean isIgnoreTimestamps() {
return this.ignoreTimestamps;
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;
}

public void setIgnoreTimestamps(boolean ignoreTimestamps) {
this.ignoreTimestamps = ignoreTimestamps;
}
}

public Boolean isSendLatest() {
return this.sendLatest;
}
}

public void setSendLatest(boolean sendLatest) {
this.sendLatest = sendLatest;
}
}
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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
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;
Expand Down Expand Up @@ -56,7 +55,7 @@ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

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) {

Expand All @@ -67,7 +66,6 @@ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
exporter.setIncludes(trigger.getIncludes());
exporter.setExcludes(trigger.getExcludes());
}
exporter.setIgnoreTimestamps(trigger.isIgnoreTimestamps());
exporter.setSendLatest(trigger.isSendLatest());

this.exporters.put(name, exporter);
Expand Down
Loading

0 comments on commit 80ff929

Please sign in to comment.