Polish "Upgrade to Micrometer 1.0.0-rc.6"
Closes gh-11598
This commit is contained in:
parent
ccc820f723
commit
ae3cd75d1a
|
@ -52,6 +52,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -64,6 +65,7 @@ import org.springframework.integration.support.management.IntegrationManagementC
|
||||||
*
|
*
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
* @author Jon Schneider
|
* @author Jon Schneider
|
||||||
|
* @author Stephane Nicoll
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnClass(Timed.class)
|
@ConditionalOnClass(Timed.class)
|
||||||
|
@ -76,7 +78,8 @@ import org.springframework.integration.support.management.IntegrationManagementC
|
||||||
InfluxExportConfiguration.class, JmxExportConfiguration.class,
|
InfluxExportConfiguration.class, JmxExportConfiguration.class,
|
||||||
PrometheusExportConfiguration.class, SimpleExportConfiguration.class,
|
PrometheusExportConfiguration.class, SimpleExportConfiguration.class,
|
||||||
StatsdExportConfiguration.class })
|
StatsdExportConfiguration.class })
|
||||||
@AutoConfigureAfter({ CacheAutoConfiguration.class, DataSourceAutoConfiguration.class })
|
@AutoConfigureAfter({ CacheAutoConfiguration.class, DataSourceAutoConfiguration.class,
|
||||||
|
RestTemplateAutoConfiguration.class })
|
||||||
public class MetricsAutoConfiguration {
|
public class MetricsAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -87,21 +90,16 @@ public class MetricsAutoConfiguration {
|
||||||
ObjectProvider<Collection<MeterRegistryConfigurer>> configurers) {
|
ObjectProvider<Collection<MeterRegistryConfigurer>> configurers) {
|
||||||
CompositeMeterRegistry composite = metricsProperties.isUseGlobalRegistry() ?
|
CompositeMeterRegistry composite = metricsProperties.isUseGlobalRegistry() ?
|
||||||
Metrics.globalRegistry : new CompositeMeterRegistry();
|
Metrics.globalRegistry : new CompositeMeterRegistry();
|
||||||
|
configurers.getIfAvailable(Collections::emptyList)
|
||||||
if (configurers.getIfAvailable() != null) {
|
.forEach((configurer) -> configurer.configureRegistry(composite));
|
||||||
configurers.getIfAvailable(Collections::emptyList)
|
exporters.getIfAvailable(Collections::emptyList).forEach(exporter -> {
|
||||||
.forEach((configurer) -> configurer.configureRegistry(composite));
|
MeterRegistry childRegistry = exporter.registry();
|
||||||
}
|
if (composite == childRegistry) {
|
||||||
|
throw new IllegalStateException(
|
||||||
if (exporters.getIfAvailable() != null) {
|
"cannot add a CompositeMeterRegistry to itself");
|
||||||
exporters.getIfAvailable().forEach(exporter -> {
|
}
|
||||||
final MeterRegistry childRegistry = exporter.registry();
|
composite.add(childRegistry);
|
||||||
if (composite == childRegistry) {
|
});
|
||||||
throw new IllegalStateException("cannot add a CompositeMeterRegistry to itself");
|
|
||||||
}
|
|
||||||
composite.add(childRegistry);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return composite;
|
return composite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -40,8 +40,8 @@ public class DatadogProperties extends StepRegistryProperties {
|
||||||
private String applicationKey;
|
private String applicationKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable publishing descriptions metadata to Datadog. Turn
|
* Whether to publish descriptions metadata to Datadog. Turn this off to minimize the
|
||||||
* this off to minimize the amount of metadata sent.
|
* amount of metadata sent.
|
||||||
*/
|
*/
|
||||||
private Boolean descriptions;
|
private Boolean descriptions;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -58,4 +58,5 @@ class DatadogPropertiesConfigAdapter
|
||||||
public boolean descriptions() {
|
public boolean descriptions() {
|
||||||
return get(DatadogProperties::getDescriptions, DatadogConfig.super::descriptions);
|
return get(DatadogProperties::getDescriptions, DatadogConfig.super::descriptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties(prefix = "management.metrics.export.jmx")
|
@ConfigurationProperties(prefix = "management.metrics.export.jmx")
|
||||||
public class JmxProperties {
|
public class JmxProperties {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step size (i.e. reporting frequency) to use.
|
* Step size (i.e. reporting frequency) to use.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -43,4 +43,5 @@ class JmxPropertiesConfigAdapter extends PropertiesConfigAdapter<JmxProperties>
|
||||||
public Duration step() {
|
public Duration step() {
|
||||||
return get(JmxProperties::getStep, JmxConfig.super::step);
|
return get(JmxProperties::getStep, JmxConfig.super::step);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -40,7 +40,7 @@ public class MeterRegistryConfigurerTests {
|
||||||
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
|
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
|
||||||
.withConfiguration(
|
.withConfiguration(
|
||||||
UserConfigurations.of(MeterRegistryConfigurerConfiguration.class))
|
UserConfigurations.of(MeterRegistryConfigurerConfiguration.class))
|
||||||
.withPropertyValues("metrics.use-global-registry=false")
|
.withPropertyValues("management.metrics.use-global-registry=false")
|
||||||
.run((context) -> assertThat(context.getBean(MeterRegistry.class)
|
.run((context) -> assertThat(context.getBean(MeterRegistry.class)
|
||||||
.find("jvm.memory.used").tags("region", "us-east-1").gauge())
|
.find("jvm.memory.used").tags("region", "us-east-1").gauge())
|
||||||
.isPresent());
|
.isPresent());
|
||||||
|
@ -52,7 +52,7 @@ public class MeterRegistryConfigurerTests {
|
||||||
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
|
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
|
||||||
.withConfiguration(
|
.withConfiguration(
|
||||||
UserConfigurations.of(MeterRegistryConfigurerConfiguration.class))
|
UserConfigurations.of(MeterRegistryConfigurerConfiguration.class))
|
||||||
.withPropertyValues("metrics.use-global-registry=false")
|
.withPropertyValues("management.metrics.use-global-registry=false")
|
||||||
.run((context) -> assertThat(context.getBean(MeterRegistry.class)
|
.run((context) -> assertThat(context.getBean(MeterRegistry.class)
|
||||||
.find("my.thing").tags("region", "us-east-1").gauge())
|
.find("my.thing").tags("region", "us-east-1").gauge())
|
||||||
.isPresent());
|
.isPresent());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -32,17 +32,17 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.actuate.metrics.web.client.DefaultRestTemplateExchangeTagsProvider;
|
|
||||||
import org.springframework.boot.actuate.metrics.web.client.MetricsRestTemplateCustomizer;
|
|
||||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -115,7 +115,8 @@ public class MetricsAutoConfigurationIntegrationTests {
|
||||||
@Configuration
|
@Configuration
|
||||||
@ImportAutoConfiguration({ MetricsAutoConfiguration.class,
|
@ImportAutoConfiguration({ MetricsAutoConfiguration.class,
|
||||||
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
|
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
|
||||||
WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
|
RestTemplateAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
|
DispatcherServletAutoConfiguration.class,
|
||||||
ServletWebServerFactoryAutoConfiguration.class })
|
ServletWebServerFactoryAutoConfiguration.class })
|
||||||
@Import(PersonController.class)
|
@Import(PersonController.class)
|
||||||
static class MetricsApp {
|
static class MetricsApp {
|
||||||
|
@ -126,12 +127,8 @@ public class MetricsAutoConfigurationIntegrationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RestTemplate restTemplate(MeterRegistry registry) {
|
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
return restTemplateBuilder.build();
|
||||||
MetricsRestTemplateCustomizer customizer = new MetricsRestTemplateCustomizer(
|
|
||||||
registry, new DefaultRestTemplateExchangeTagsProvider(), "http.client.requests", false);
|
|
||||||
customizer.customize(restTemplate);
|
|
||||||
return restTemplate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
public class MetricsAutoConfigurationTests {
|
public class MetricsAutoConfigurationTests {
|
||||||
|
|
||||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
|
.withPropertyValues("management.metrics.use-global-registry=false")
|
||||||
.withUserConfiguration(RegistryConfiguration.class)
|
.withUserConfiguration(RegistryConfiguration.class)
|
||||||
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class));
|
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class));
|
||||||
|
|
||||||
|
@ -49,8 +50,7 @@ public class MetricsAutoConfigurationTests {
|
||||||
this.contextRunner
|
this.contextRunner
|
||||||
.withConfiguration(
|
.withConfiguration(
|
||||||
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
.withPropertyValues("spring.datasource.generate-unique-name=true")
|
||||||
"management.metrics.use-global-registry=false")
|
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.getBean(DataSource.class).getConnection().getMetaData();
|
context.getBean(DataSource.class).getConnection().getMetaData();
|
||||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
|
@ -65,8 +65,7 @@ public class MetricsAutoConfigurationTests {
|
||||||
.withConfiguration(
|
.withConfiguration(
|
||||||
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
||||||
"management.metrics.jdbc.datasource-metric-name=custom.name",
|
"management.metrics.jdbc.datasource-metric-name=custom.name")
|
||||||
"management.metrics.use-global-registry=false")
|
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.getBean(DataSource.class).getConnection().getMetaData();
|
context.getBean(DataSource.class).getConnection().getMetaData();
|
||||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
|
@ -81,8 +80,7 @@ public class MetricsAutoConfigurationTests {
|
||||||
.withConfiguration(
|
.withConfiguration(
|
||||||
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
||||||
"management.metrics.jdbc.instrument-datasource=false",
|
"management.metrics.jdbc.instrument-datasource=false")
|
||||||
"management.metrics.use-global-registry=false")
|
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.getBean(DataSource.class).getConnection().getMetaData();
|
context.getBean(DataSource.class).getConnection().getMetaData();
|
||||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
|
@ -96,7 +94,6 @@ public class MetricsAutoConfigurationTests {
|
||||||
this.contextRunner.withUserConfiguration(TwoDataSourcesConfiguration.class)
|
this.contextRunner.withUserConfiguration(TwoDataSourcesConfiguration.class)
|
||||||
.withConfiguration(
|
.withConfiguration(
|
||||||
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
.withPropertyValues("metrics.use-global-registry=false")
|
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.getBean("firstDataSource", DataSource.class).getConnection()
|
context.getBean("firstDataSource", DataSource.class).getConnection()
|
||||||
.getMetaData();
|
.getMetaData();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -37,7 +37,7 @@ public class MetricsConfigurationCompositeTests {
|
||||||
public void compositeContainsImplementationsOnClasspath() {
|
public void compositeContainsImplementationsOnClasspath() {
|
||||||
new ApplicationContextRunner()
|
new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
|
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
|
||||||
.withPropertyValues("metrics.use-global-registry=false")
|
.withPropertyValues("management.metrics.use-global-registry=false")
|
||||||
.run((context) -> assertThat(
|
.run((context) -> assertThat(
|
||||||
context.getBean(CompositeMeterRegistry.class).getRegistries())
|
context.getBean(CompositeMeterRegistry.class).getRegistries())
|
||||||
.hasAtLeastOneElementOfType(PrometheusMeterRegistry.class)
|
.hasAtLeastOneElementOfType(PrometheusMeterRegistry.class)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -27,12 +27,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
*/
|
*/
|
||||||
public class DatadogPropertiesConfigAdapterTests {
|
public class DatadogPropertiesConfigAdapterTests {
|
||||||
|
|
||||||
@Test(expected = IllegalStateException.class)
|
|
||||||
public void apiKeyIsRequired() {
|
|
||||||
DatadogProperties properties = new DatadogProperties();
|
|
||||||
new DatadogPropertiesConfigAdapter(properties).apiKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uriCanBeSet() {
|
public void uriCanBeSet() {
|
||||||
DatadogProperties properties = new DatadogProperties();
|
DatadogProperties properties = new DatadogProperties();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -19,76 +19,75 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.client;
|
||||||
import io.micrometer.core.instrument.MeterRegistry;
|
import io.micrometer.core.instrument.MeterRegistry;
|
||||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.actuate.metrics.web.client.MetricsRestTemplateCustomizer;
|
||||||
import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
/**
|
||||||
@SpringBootTest(classes = RestTemplateMetricsConfigurationTests.ClientApp.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
* Tests for {@link RestTemplateMetricsConfiguration}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
public class RestTemplateMetricsConfigurationTests {
|
public class RestTemplateMetricsConfigurationTests {
|
||||||
@Autowired
|
|
||||||
private RestTemplate client;
|
|
||||||
|
|
||||||
@Autowired
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
private MeterRegistry registry;
|
.withPropertyValues("management.metrics.use-global-registry=false")
|
||||||
|
.withConfiguration(AutoConfigurations.of(
|
||||||
|
RestTemplateAutoConfiguration.class, MetricsAutoConfiguration.class))
|
||||||
|
.withUserConfiguration(RegistryConfiguration.class);
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void restTemplatesCreatedWithBuilderAreInstrumented() {
|
public void restTemplateCreatedWithBuilderIsInstrumented() {
|
||||||
try {
|
this.contextRunner.run((context) -> {
|
||||||
this.client.getForObject("http://google.com", String.class);
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
}
|
RestTemplate restTemplate = context.getBean(RestTemplateBuilder.class)
|
||||||
catch (Throwable ignored) {
|
.build();
|
||||||
// doesn't matter whether the request succeeded or not
|
validateRestTemplate(restTemplate, registry);
|
||||||
}
|
});
|
||||||
assertThat(this.registry.find("http.client.requests").meter()).isPresent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SpringBootApplication(exclude = {
|
@Test
|
||||||
FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class,
|
public void restTemplateCanBeCustomizedManually() {
|
||||||
CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class,
|
this.contextRunner.run((context) -> {
|
||||||
Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class,
|
assertThat(context).hasSingleBean(MetricsRestTemplateCustomizer.class);
|
||||||
MongoAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class,
|
RestTemplate restTemplate = new RestTemplateBuilder().customizers(
|
||||||
HazelcastAutoConfiguration.class, MongoDataAutoConfiguration.class,
|
context.getBean(MetricsRestTemplateCustomizer.class)).build();
|
||||||
ElasticsearchAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class,
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
JestAutoConfiguration.class, SolrRepositoriesAutoConfiguration.class,
|
validateRestTemplate(restTemplate, registry);
|
||||||
SolrAutoConfiguration.class, RedisAutoConfiguration.class,
|
});
|
||||||
RedisRepositoriesAutoConfiguration.class
|
}
|
||||||
})
|
|
||||||
static class ClientApp {
|
private void validateRestTemplate(RestTemplate restTemplate, MeterRegistry registry) {
|
||||||
|
MockRestServiceServer server = MockRestServiceServer.createServer(restTemplate);
|
||||||
|
server.expect(requestTo("/test")).andRespond(withStatus(HttpStatus.OK));
|
||||||
|
assertThat(registry.find("http.client.requests").meter()).isNotPresent();
|
||||||
|
assertThat(restTemplate.getForEntity("/test", Void.class).getStatusCode())
|
||||||
|
.isEqualTo(HttpStatus.OK);
|
||||||
|
assertThat(registry.find("http.client.requests").meter()).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class RegistryConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MeterRegistry registry() {
|
public MeterRegistry registry() {
|
||||||
return new SimpleMeterRegistry();
|
return new SimpleMeterRegistry();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
public RestTemplate restTemplate(RestTemplateBuilder builder) {
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -94,7 +94,8 @@ public class WebMvcMetrics {
|
||||||
|
|
||||||
void preHandle(HttpServletRequest request, Object handler) {
|
void preHandle(HttpServletRequest request, Object handler) {
|
||||||
if (request.getAttribute(TIMING_REQUEST_ATTRIBUTE) == null) {
|
if (request.getAttribute(TIMING_REQUEST_ATTRIBUTE) == null) {
|
||||||
request.setAttribute(TIMING_REQUEST_ATTRIBUTE, this.registry.config().clock().monotonicTime());
|
request.setAttribute(TIMING_REQUEST_ATTRIBUTE,
|
||||||
|
this.registry.config().clock().monotonicTime());
|
||||||
}
|
}
|
||||||
request.setAttribute(HANDLER_REQUEST_ATTRIBUTE, handler);
|
request.setAttribute(HANDLER_REQUEST_ATTRIBUTE, handler);
|
||||||
longTaskTimed(handler).forEach((config) -> {
|
longTaskTimed(handler).forEach((config) -> {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -75,7 +75,6 @@ public class WebMvcMetricsFilterAutoTimedTests {
|
||||||
@Test
|
@Test
|
||||||
public void metricsCanBeAutoTimed() throws Exception {
|
public void metricsCanBeAutoTimed() throws Exception {
|
||||||
this.mvc.perform(get("/api/10")).andExpect(status().isOk());
|
this.mvc.perform(get("/api/10")).andExpect(status().isOk());
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
this.registry.find("http.server.requests").tags("status", "200").timer())
|
this.registry.find("http.server.requests").tags("status", "200").timer())
|
||||||
.hasValueSatisfying((t) -> assertThat(t.count()).isEqualTo(1));
|
.hasValueSatisfying((t) -> assertThat(t.count()).isEqualTo(1));
|
||||||
|
|
|
@ -85,6 +85,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
public class WebMvcMetricsFilterTests {
|
public class WebMvcMetricsFilterTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SimpleMeterRegistry registry;
|
private SimpleMeterRegistry registry;
|
||||||
|
|
||||||
|
@ -167,7 +168,7 @@ public class WebMvcMetricsFilterTests {
|
||||||
public void unhandledError() {
|
public void unhandledError() {
|
||||||
assertThatCode(() -> this.mvc.perform(get("/api/c1/unhandledError/10"))
|
assertThatCode(() -> this.mvc.perform(get("/api/c1/unhandledError/10"))
|
||||||
.andExpect(status().isOk()))
|
.andExpect(status().isOk()))
|
||||||
.hasRootCauseInstanceOf(RuntimeException.class);
|
.hasRootCauseInstanceOf(RuntimeException.class);
|
||||||
assertThat(this.registry.find("http.server.requests")
|
assertThat(this.registry.find("http.server.requests")
|
||||||
.tags("exception", "RuntimeException").value(Statistic.Count, 1.0)
|
.tags("exception", "RuntimeException").value(Statistic.Count, 1.0)
|
||||||
.timer()).isPresent();
|
.timer()).isPresent();
|
||||||
|
@ -230,6 +231,7 @@ public class WebMvcMetricsFilterTests {
|
||||||
@EnableWebMvc
|
@EnableWebMvc
|
||||||
@Import({ Controller1.class, Controller2.class })
|
@Import({ Controller1.class, Controller2.class })
|
||||||
static class MetricsFilterApp {
|
static class MetricsFilterApp {
|
||||||
|
|
||||||
@Primary
|
@Primary
|
||||||
@Bean
|
@Bean
|
||||||
MeterRegistry meterRegistry(Collection<MeterRegistry> registries) {
|
MeterRegistry meterRegistry(Collection<MeterRegistry> registries) {
|
||||||
|
@ -250,7 +252,9 @@ public class WebMvcMetricsFilterTests {
|
||||||
@Override
|
@Override
|
||||||
public MeterFilterReply accept(Meter.Id id) {
|
public MeterFilterReply accept(Meter.Id id) {
|
||||||
for (Tag tag : id.getTags()) {
|
for (Tag tag : id.getTags()) {
|
||||||
if (tag.getKey().equals("uri") && (tag.getValue().contains("histogram") || tag.getValue().contains("percentiles"))) {
|
if (tag.getKey().equals("uri")
|
||||||
|
&& (tag.getValue().contains("histogram")
|
||||||
|
|| tag.getValue().contains("percentiles"))) {
|
||||||
return MeterFilterReply.ACCEPT;
|
return MeterFilterReply.ACCEPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,6 +372,7 @@ public class WebMvcMetricsFilterTests {
|
||||||
public String successful(@PathVariable Long id) {
|
public String successful(@PathVariable Long id) {
|
||||||
return id.toString();
|
return id.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class RedirectAndNotFoundFilter extends OncePerRequestFilter {
|
static class RedirectAndNotFoundFilter extends OncePerRequestFilter {
|
||||||
|
@ -377,7 +382,7 @@ public class WebMvcMetricsFilterTests {
|
||||||
@Override
|
@Override
|
||||||
protected void doFilterInternal(HttpServletRequest request,
|
protected void doFilterInternal(HttpServletRequest request,
|
||||||
HttpServletResponse response, FilterChain filterChain)
|
HttpServletResponse response, FilterChain filterChain)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
String misbehave = request.getHeader(TEST_MISBEHAVE_HEADER);
|
String misbehave = request.getHeader(TEST_MISBEHAVE_HEADER);
|
||||||
if (misbehave != null) {
|
if (misbehave != null) {
|
||||||
response.setStatus(Integer.parseInt(misbehave));
|
response.setStatus(Integer.parseInt(misbehave));
|
||||||
|
|
|
@ -83,8 +83,8 @@ public class WebMvcMetricsIntegrationTests {
|
||||||
public void handledExceptionIsRecordedInMetricTag() throws Exception {
|
public void handledExceptionIsRecordedInMetricTag() throws Exception {
|
||||||
this.mvc.perform(get("/api/handledError")).andExpect(status().is5xxServerError());
|
this.mvc.perform(get("/api/handledError")).andExpect(status().is5xxServerError());
|
||||||
assertThat(this.registry.find("http.server.requests")
|
assertThat(this.registry.find("http.server.requests")
|
||||||
.tags("exception", "Exception1", "status", "500").value(Statistic.Count, 1.0).timer())
|
.tags("exception", "Exception1", "status", "500")
|
||||||
.isPresent();
|
.value(Statistic.Count, 1.0).timer()).isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -92,8 +92,8 @@ public class WebMvcMetricsIntegrationTests {
|
||||||
assertThatCode(() -> this.mvc.perform(get("/api/rethrownError"))
|
assertThatCode(() -> this.mvc.perform(get("/api/rethrownError"))
|
||||||
.andExpect(status().is5xxServerError()));
|
.andExpect(status().is5xxServerError()));
|
||||||
assertThat(this.registry.find("http.server.requests")
|
assertThat(this.registry.find("http.server.requests")
|
||||||
.tags("exception", "Exception2", "status", "500").value(Statistic.Count, 1.0).timer())
|
.tags("exception", "Exception2", "status", "500")
|
||||||
.isPresent();
|
.value(Statistic.Count, 1.0).timer()).isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|
|
@ -1290,8 +1290,10 @@ content into your application. Rather, pick only the properties that you need.
|
||||||
management.metrics.export.atlas.step=1m # Step size (i.e. reporting frequency) to use.
|
management.metrics.export.atlas.step=1m # Step size (i.e. reporting frequency) to use.
|
||||||
management.metrics.export.atlas.uri= # URI of the Atlas server.
|
management.metrics.export.atlas.uri= # URI of the Atlas server.
|
||||||
management.metrics.export.datadog.api-key= # Datadog API key.
|
management.metrics.export.datadog.api-key= # Datadog API key.
|
||||||
|
management.metrics.export.datadog.application-key= # Datadog application key.
|
||||||
management.metrics.export.datadog.batch-size= # Number of measurements per request to use for the backend. If more measurements are found, then multiple requests will be made.
|
management.metrics.export.datadog.batch-size= # Number of measurements per request to use for the backend. If more measurements are found, then multiple requests will be made.
|
||||||
management.metrics.export.datadog.connect-timeout= # Connection timeout for requests to the backend.
|
management.metrics.export.datadog.connect-timeout= # Connection timeout for requests to the backend.
|
||||||
|
management.metrics.export.datadog.descriptions= # Whether to publish descriptions metadata to Datadog. Turn this off to minimize the amount of metadata sent.
|
||||||
management.metrics.export.datadog.enabled=true # Whether exporting of metrics to this backend is enabled.
|
management.metrics.export.datadog.enabled=true # Whether exporting of metrics to this backend is enabled.
|
||||||
management.metrics.export.datadog.host-tag= # Tag that will be mapped to "host" when shipping metrics to Datadog. Can be omitted if host should be omitted on publishing.
|
management.metrics.export.datadog.host-tag= # Tag that will be mapped to "host" when shipping metrics to Datadog. Can be omitted if host should be omitted on publishing.
|
||||||
management.metrics.export.datadog.num-threads= # Number of threads to use with the metrics publishing scheduler.
|
management.metrics.export.datadog.num-threads= # Number of threads to use with the metrics publishing scheduler.
|
||||||
|
@ -1328,6 +1330,7 @@ content into your application. Rather, pick only the properties that you need.
|
||||||
management.metrics.export.influx.uri= # URI of the Influx server.
|
management.metrics.export.influx.uri= # URI of the Influx server.
|
||||||
management.metrics.export.influx.user-name= # Login user of the Influx server.
|
management.metrics.export.influx.user-name= # Login user of the Influx server.
|
||||||
management.metrics.export.jmx.enabled=true # Whether exporting of metrics to JMX is enabled.
|
management.metrics.export.jmx.enabled=true # Whether exporting of metrics to JMX is enabled.
|
||||||
|
management.metrics.export.jmx.step= # Step size (i.e. reporting frequency) to use.
|
||||||
management.metrics.export.prometheus.descriptions= # Enable publishing descriptions as part of the scrape payload to Prometheus. Turn this off to minimize the amount of data sent on each scrape.
|
management.metrics.export.prometheus.descriptions= # Enable publishing descriptions as part of the scrape payload to Prometheus. Turn this off to minimize the amount of data sent on each scrape.
|
||||||
management.metrics.export.prometheus.enabled=true # Whether exporting of metrics to Prometheus is enabled.
|
management.metrics.export.prometheus.enabled=true # Whether exporting of metrics to Prometheus is enabled.
|
||||||
management.metrics.export.prometheus.step= # Step size (i.e. reporting frequency) to use.
|
management.metrics.export.prometheus.step= # Step size (i.e. reporting frequency) to use.
|
||||||
|
|
|
@ -1010,9 +1010,9 @@ instance.
|
||||||
|
|
||||||
[[production-ready-metrics-rest-template]]
|
[[production-ready-metrics-rest-template]]
|
||||||
=== RestTemplate Metrics
|
=== RestTemplate Metrics
|
||||||
Auto-configuration customizes the auto-configured `RestTemplate` to enable the
|
The instrumentation of any `RestTemplate` created using the auto-configured
|
||||||
instrumentation of its requests. `MetricsRestTemplateCustomizer` can be used to customize
|
`RestTemplateBuilder` is enabled. It is also possible to apply
|
||||||
your own `RestTemplate` instances.
|
`MetricsRestTemplateCustomizer` manually.
|
||||||
|
|
||||||
By default, metrics are generated with the name, `http.client.requests`. The name can be
|
By default, metrics are generated with the name, `http.client.requests`. The name can be
|
||||||
customized by setting the `management.metrics.web.client.requests-metric-name` property.
|
customized by setting the `management.metrics.web.client.requests-metric-name` property.
|
||||||
|
|
Loading…
Reference in New Issue