Commit ae3cd75d authored by Stephane Nicoll's avatar Stephane Nicoll

Polish "Upgrade to Micrometer 1.0.0-rc.6"

Closes gh-11598
parent ccc820f7
...@@ -52,6 +52,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; ...@@ -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 ...@@ -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 ...@@ -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 { ...@@ -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();
if (configurers.getIfAvailable() != null) {
configurers.getIfAvailable(Collections::emptyList) configurers.getIfAvailable(Collections::emptyList)
.forEach((configurer) -> configurer.configureRegistry(composite)); .forEach((configurer) -> configurer.configureRegistry(composite));
} exporters.getIfAvailable(Collections::emptyList).forEach(exporter -> {
MeterRegistry childRegistry = exporter.registry();
if (exporters.getIfAvailable() != null) {
exporters.getIfAvailable().forEach(exporter -> {
final MeterRegistry childRegistry = exporter.registry();
if (composite == childRegistry) { if (composite == childRegistry) {
throw new IllegalStateException("cannot add a CompositeMeterRegistry to itself"); throw new IllegalStateException(
"cannot add a CompositeMeterRegistry to itself");
} }
composite.add(childRegistry); composite.add(childRegistry);
}); });
}
return composite; return composite;
} }
......
/* /*
* 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 { ...@@ -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;
......
/* /*
* 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 ...@@ -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);
} }
} }
/* /*
* 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; ...@@ -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.
*/ */
......
/* /*
* 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> ...@@ -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);
} }
} }
/* /*
* 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.
......
/* /*
* 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 { ...@@ -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 { ...@@ -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());
......
/* /*
* 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; ...@@ -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 { ...@@ -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 { ...@@ -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; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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();
......
/* /*
* 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 { ...@@ -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)
......
/* /*
* 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; ...@@ -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();
......
/* /*
* 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.
......
/* /*
* 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; ...@@ -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)
.build();
validateRestTemplate(restTemplate, registry);
});
} }
catch (Throwable ignored) {
// doesn't matter whether the request succeeded or not @Test
public void restTemplateCanBeCustomizedManually() {
this.contextRunner.run((context) -> {
assertThat(context).hasSingleBean(MetricsRestTemplateCustomizer.class);
RestTemplate restTemplate = new RestTemplateBuilder().customizers(
context.getBean(MetricsRestTemplateCustomizer.class)).build();
MeterRegistry registry = context.getBean(MeterRegistry.class);
validateRestTemplate(restTemplate, registry);
});
} }
assertThat(this.registry.find("http.client.requests").meter()).isPresent();
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();
} }
@SpringBootApplication(exclude = { @Configuration
FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class, static class RegistryConfiguration {
CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class,
Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class,
MongoAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class,
HazelcastAutoConfiguration.class, MongoDataAutoConfiguration.class,
ElasticsearchAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class,
JestAutoConfiguration.class, SolrRepositoriesAutoConfiguration.class,
SolrAutoConfiguration.class, RedisAutoConfiguration.class,
RedisRepositoriesAutoConfiguration.class
})
static class ClientApp {
@Bean @Bean
public MeterRegistry registry() { public MeterRegistry registry() {
return new SimpleMeterRegistry(); return new SimpleMeterRegistry();
} }
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
} }
} }
/* /*
* 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 { ...@@ -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) -> {
......
/* /*
* 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.
......
/* /*
* 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 { ...@@ -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. ...@@ -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;
...@@ -230,6 +231,7 @@ public class WebMvcMetricsFilterTests { ...@@ -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 { ...@@ -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 { ...@@ -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 {
......
...@@ -83,8 +83,8 @@ public class WebMvcMetricsIntegrationTests { ...@@ -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 { ...@@ -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. ...@@ -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. ...@@ -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. ...@@ -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.
......
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