问题
Recently I switched to Spring Boot 2 with Micrometer. As I got these shiny new metrics, I talked with our DevOps guys and we started exporting them to Telegraf.
To distinguish between different applications and application nodes, we decided to use tags. This works perfectly for custom metrics, but now I started thinking about the pre-defined. To achieve the same for default metrics, I need an ability to add extra tags for them as well.
Is it possible to achieve this? Am I doing this right?
EDIT: I tried next approach:
@Component
public class MyMetricsImpl implements MyMetrics {
@Autowired
protected MyProperties myProperties;
@Autowired
protected MeterRegistry meterRegistry;
@PostConstruct
public void initialize() {
this.meterRegistry.config()
.commonTags(commonTags());
}
@Override
public List<Tag> commonTags() {
List<Tag> tags = new ArrayList<>();
tags.add(Tag.of("application", myProperties.getApplicationName()));
tags.add(Tag.of("node", myProperties.getNodeName()));
return tags;
}
}
The problem is that my metrics behave correctly and even some of the Boot's metrics (at least http.server.requests) see my tags. But jvm.*, system.*, tomcat.* and many others still don't have the needed tags.
回答1:
If you are looking for common tags support, you can do it by registering a MeterFilter doing it.
See this commit or this branch for an example.
With the upcoming Spring Boot 2.1.0.M1, you can use the following properties:
management.metrics.tags.*= # Common tags that are applied to every meter.
See the reference for details.
UPDATED:
As the question has been updated, I checked the updated question with this MeterFilter-based approach and confirmed it's working as follows:
Request: http://localhost:8080/actuator/metrics/jvm.gc.memory.allocated
Response:
{
"name" : "jvm.gc.memory.allocated",
"measurements" : [ {
"statistic" : "COUNT",
"value" : 1.98180864E8
} ],
"availableTags" : [ {
"tag" : "stack",
"values" : [ "prod" ]
}, {
"tag" : "region",
"values" : [ "us-east-1" ]
} ]
}
I didn't check the approach which has been provided in the updated question but I'd just use the proven MeterFilter-based approach unless there's any reason to stick with the approach.
2nd UPDATED:
I looked into the approach and was able to reproduce it with this branch.
It's too late to apply common tags in @PostConstruct as some metrics have been registered already. The reason why http.server.requests works is that it will be registered with the first request. Try to put a breakpoint on the point of filters' application if you're interested in it.
In short, try the above approach which is similar to the upcoming Spring Boot out-of-box support.
回答2:
In response to comment under my original question, here is a small example of adding custom metrics:
package io.github.stepio.examples.metrics;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Component
public class MyImportantComponent {
protected static final String CONNECTIONS_CURRENT = "connections.created";
protected static final String CONNECTIONS_IDLE = "connections.idle";
protected static final String CONNECTIONS_MAX = "connections.max";
protected static final String PREFIX_REQUESTS_FOR_SERVICE = "requests";
protected static final String SERVICE = "service";
protected AtomicInteger connectionMax = new AtomicInteger();
@Autowired
protected MeterRegistry meterRegistry;
@Override
public List<Tag> tags() {
return new ArrayList<>();
}
@Override
public void trackConnectorsCurrent(AtomicInteger counter) {
this.meterRegistry.gauge(CONNECTIONS_CURRENT, tags(), counter);
}
@Override
public void trackConnectorsIdle(Collection<?> collection) {
this.meterRegistry.gaugeCollectionSize(CONNECTIONS_IDLE, tags(), collection);
}
@Override
public void submitConnectorsMax(final int value) {
this.meterRegistry.gauge(CONNECTIONS_MAX, tags(), this.connectionMax).set(value);
}
@Override
public void incrementRequestsForService(String serviceName) {
this.meterRegistry.counter(PREFIX_REQUESTS_FOR_SERVICE, tags(SERVICE, serviceName)).increment();
}
}
来源:https://stackoverflow.com/questions/51552889/is-it-possible-to-define-additional-tags-for-default-spring-boot-2-metrics