Commit 602f52ff authored by Stephane Nicoll's avatar Stephane Nicoll

Add support for configuring common tags declaratively

Closes gh-12933
parent 8e4f4317
......@@ -44,6 +44,11 @@ public class MetricsProperties {
*/
private Map<String, Boolean> enable = new LinkedHashMap<>();
/**
* Common tags that are applied to every meter.
*/
private final Map<String, String> tags = new LinkedHashMap<>();
private final Web web = new Web();
private final Distribution distribution = new Distribution();
......@@ -65,6 +70,10 @@ public class MetricsProperties {
this.enable = enable;
}
public Map<String, String> getTags() {
return this.tags;
}
public Web getWeb() {
return this.web;
}
......
......@@ -19,9 +19,12 @@ package org.springframework.boot.actuate.autoconfigure.metrics;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.Meter.Id;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.config.MeterFilter;
import io.micrometer.core.instrument.config.MeterFilterReply;
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
......@@ -35,17 +38,30 @@ import org.springframework.util.StringUtils;
*
* @author Jon Schneider
* @author Phillip Webb
* @author Stephane Nicoll
* @since 2.0.0
*/
public class PropertiesMeterFilter implements MeterFilter {
private static final ServiceLevelAgreementBoundary[] EMPTY_SLA = {};
private MetricsProperties properties;
private final MetricsProperties properties;
private final MeterFilter mapFilter;
public PropertiesMeterFilter(MetricsProperties properties) {
Assert.notNull(properties, "Properties must not be null");
this.properties = properties;
this.mapFilter = createMapFilter(properties.getTags());
}
private static MeterFilter createMapFilter(Map<String, String> tags) {
if (tags.isEmpty()) {
return new MeterFilter() { };
}
Tags commonTags = Tags.of(tags.entrySet().stream().map((entry) ->
Tag.of(entry.getKey(), entry.getValue())).collect(Collectors.toList()));
return MeterFilter.commonTags(commonTags);
}
@Override
......@@ -54,6 +70,11 @@ public class PropertiesMeterFilter implements MeterFilter {
return (enabled ? MeterFilterReply.NEUTRAL : MeterFilterReply.DENY);
}
@Override
public Id map(Id id) {
return this.mapFilter.map(id);
}
@Override
public DistributionStatisticConfig configure(Meter.Id id,
DistributionStatisticConfig config) {
......
......@@ -55,6 +55,19 @@ public class MetricsAutoConfigurationIntegrationTests {
});
}
@Test
public void propertyBasedCommonTagsIsAutoConfigured() {
this.contextRunner.withPropertyValues("management.metrics.tags.region=test",
"management.metrics.tags.origin=local")
.run((context) -> {
MeterRegistry registry = context.getBean(MeterRegistry.class);
registry.counter("my.counter", "env", "qa");
assertThat(registry.find("my.counter").tags("env", "qa")
.tags("region", "test").tags("origin", "local").counter())
.isNotNull();
});
}
@Test
public void simpleMeterRegistryIsUsedAsAFallback() {
this.contextRunner
......
......@@ -1432,6 +1432,7 @@ content into your application. Rather, pick only the properties that you need.
management.metrics.export.wavefront.step=10s # Step size (i.e. reporting frequency) to use.
management.metrics.export.wavefront.uri=https://longboard.wavefront.com # URI to ship metrics to.
management.metrics.use-global-registry=true # Whether auto-configured MeterRegistry implementations should be bound to the global static registry on Metrics.
management.metrics.tags.*= # Common tags that are applied to every meter.
management.metrics.web.client.max-uri-tags=100 # Maximum number of unique URI tag values allowed. After the max number of tag values is reached, metrics with additional tag values are denied by filter.
management.metrics.web.client.requests-metric-name=http.client.requests # Name of the metric for sent requests.
management.metrics.web.server.auto-time-requests=true # Whether requests handled by Spring MVC or WebFlux should be automatically timed.
......
......@@ -1846,6 +1846,21 @@ all meter IDs beginning with `com.example`, you can do the following:
include::{code-examples}/actuate/metrics/MetricsFilterBeanExample.java[tag=configuration]
----
[[production-ready-metrics-common-tags]]
==== Common tags
Common tag are generally used for dimensional drill-down on the operating environment like
host, instance, region, stack, etc. Commons tags applied to all meters and can be
configured as shown in the following example:
[source,properties,indent=0]
----
management.metrics.tags.region=us-east-1
management.metrics.tags.stack=prod
----
The example above adds a `region` and `stack` tags to all meters with a value of
`us-east-1` and `prod` respectively.
==== Per-meter properties
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment