Refactor PublicMetrics registration
Rework flexible PublicMetrics registration introduced in 2be6b3e4 to
restore compatibility with v1.1 VanillaPublicMetrics. The new
MetricReaderPublicMetrics class now exposes metrics from a MetricReader
and VanillaPublicMetrics is deprecated. The MetricsEndpoint can now
exposes a collection of PublicMetric interface directly.
See gh-1094
This commit is contained in:
parent
8e0b3dd00a
commit
14c6243637
|
|
@ -16,9 +16,11 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.autoconfigure;
|
package org.springframework.boot.actuate.autoconfigure;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
|
@ -32,13 +34,13 @@ import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
|
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.HealthEndpoint;
|
import org.springframework.boot.actuate.endpoint.HealthEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
|
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
|
||||||
|
import org.springframework.boot.actuate.endpoint.MetricReaderPublicMetrics;
|
||||||
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
|
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.PublicMetrics;
|
import org.springframework.boot.actuate.endpoint.PublicMetrics;
|
||||||
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
|
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.SystemPublicMetrics;
|
import org.springframework.boot.actuate.endpoint.SystemPublicMetrics;
|
||||||
import org.springframework.boot.actuate.endpoint.TraceEndpoint;
|
import org.springframework.boot.actuate.endpoint.TraceEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.VanillaPublicMetrics;
|
|
||||||
import org.springframework.boot.actuate.health.HealthAggregator;
|
import org.springframework.boot.actuate.health.HealthAggregator;
|
||||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||||
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
|
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
|
||||||
|
|
@ -85,10 +87,10 @@ public class EndpointAutoConfiguration {
|
||||||
Map<String, HealthIndicator> healthIndicators = new HashMap<String, HealthIndicator>();
|
Map<String, HealthIndicator> healthIndicators = new HashMap<String, HealthIndicator>();
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private MetricReader metricRepository = new InMemoryMetricRepository();
|
private MetricReader metricReader = new InMemoryMetricRepository();
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private Collection<PublicMetrics> allMetrics;
|
private Collection<PublicMetrics> publicMetrics;
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private TraceRepository traceRepository = new InMemoryTraceRepository();
|
private TraceRepository traceRepository = new InMemoryTraceRepository();
|
||||||
|
|
@ -129,8 +131,13 @@ public class EndpointAutoConfiguration {
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public MetricsEndpoint metricsEndpoint() {
|
public MetricsEndpoint metricsEndpoint() {
|
||||||
PublicMetrics metrics = new VanillaPublicMetrics(this.metricRepository, this.allMetrics);
|
List<PublicMetrics> publicMetrics = new ArrayList<PublicMetrics>();
|
||||||
return new MetricsEndpoint(metrics);
|
publicMetrics.add(new SystemPublicMetrics());
|
||||||
|
publicMetrics.add(new MetricReaderPublicMetrics(this.metricReader));
|
||||||
|
if (this.publicMetrics != null) {
|
||||||
|
publicMetrics.addAll(this.publicMetrics);
|
||||||
|
}
|
||||||
|
return new MetricsEndpoint(publicMetrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
@ -158,19 +165,6 @@ public class EndpointAutoConfiguration {
|
||||||
return new ShutdownEndpoint();
|
return new ShutdownEndpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ConditionalOnClass(AbstractHandlerMethodMapping.class)
|
|
||||||
protected static class RequestMappingEndpointConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public RequestMappingEndpoint requestMappingEndpoint() {
|
|
||||||
RequestMappingEndpoint endpoint = new RequestMappingEndpoint();
|
|
||||||
return endpoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public ConfigurationPropertiesReportEndpoint configurationPropertiesReportEndpoint() {
|
public ConfigurationPropertiesReportEndpoint configurationPropertiesReportEndpoint() {
|
||||||
|
|
@ -180,11 +174,14 @@ public class EndpointAutoConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
protected static class CorePublicMetrics {
|
@ConditionalOnClass(AbstractHandlerMethodMapping.class)
|
||||||
|
protected static class RequestMappingEndpointConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
SystemPublicMetrics systemPublicMetrics() {
|
@ConditionalOnMissingBean
|
||||||
return new SystemPublicMetrics();
|
public RequestMappingEndpoint requestMappingEndpoint() {
|
||||||
|
RequestMappingEndpoint endpoint = new RequestMappingEndpoint();
|
||||||
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.actuate.endpoint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.metrics.Metric;
|
||||||
|
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link PublicMetrics} exposed from a {@link MetricReader}.
|
||||||
|
*
|
||||||
|
* @author Dave Syer
|
||||||
|
* @author Christian Dupuis
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class MetricReaderPublicMetrics implements PublicMetrics {
|
||||||
|
|
||||||
|
private final MetricReader metricReader;
|
||||||
|
|
||||||
|
public MetricReaderPublicMetrics(MetricReader metricReader) {
|
||||||
|
Assert.notNull(metricReader, "MetricReader must not be null");
|
||||||
|
this.metricReader = metricReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Metric<?>> metrics() {
|
||||||
|
List<Metric<?>> result = new ArrayList<Metric<?>>();
|
||||||
|
for (Metric<?> metric : this.metricReader.findAll()) {
|
||||||
|
result.add(metric);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,40 +16,56 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.endpoint;
|
package org.springframework.boot.actuate.endpoint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.metrics.Metric;
|
import org.springframework.boot.actuate.metrics.Metric;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Endpoint} to expose {@link PublicMetrics}.
|
* {@link Endpoint} to expose a collection of {@link PublicMetrics}.
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties(prefix = "endpoints.metrics", ignoreUnknownFields = false)
|
@ConfigurationProperties(prefix = "endpoints.metrics", ignoreUnknownFields = false)
|
||||||
public class MetricsEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
public class MetricsEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||||
|
|
||||||
private final PublicMetrics metrics;
|
private final List<PublicMetrics> publicMetrics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link MetricsEndpoint} instance.
|
* Create a new {@link MetricsEndpoint} instance.
|
||||||
*
|
* @param publicMetrics the metrics to expose
|
||||||
* @param metrics the metrics to expose
|
|
||||||
*/
|
*/
|
||||||
public MetricsEndpoint(PublicMetrics metrics) {
|
public MetricsEndpoint(PublicMetrics publicMetrics) {
|
||||||
|
this(Collections.singleton(publicMetrics));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link MetricsEndpoint} instance.
|
||||||
|
* @param publicMetrics the metrics to expose. The collection will be sorted using the
|
||||||
|
* {@link AnnotationAwareOrderComparator}.
|
||||||
|
*/
|
||||||
|
public MetricsEndpoint(Collection<PublicMetrics> publicMetrics) {
|
||||||
super("metrics");
|
super("metrics");
|
||||||
Assert.notNull(metrics, "Metrics must not be null");
|
Assert.notNull(publicMetrics, "PublicMetrics must not be null");
|
||||||
this.metrics = metrics;
|
this.publicMetrics = new ArrayList<PublicMetrics>(publicMetrics);
|
||||||
|
AnnotationAwareOrderComparator.sort(this.publicMetrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> invoke() {
|
public Map<String, Object> invoke() {
|
||||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||||
for (Metric<?> metric : this.metrics.metrics()) {
|
for (PublicMetrics publicMetric : this.publicMetrics) {
|
||||||
|
for (Metric<?> metric : publicMetric.metrics()) {
|
||||||
result.put(metric.getName(), metric.getValue());
|
result.put(metric.getName(), metric.getValue());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.metrics.Metric;
|
import org.springframework.boot.actuate.metrics.Metric;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -36,7 +37,7 @@ import org.springframework.util.StringUtils;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 1.2.0
|
* @since 1.2.0
|
||||||
*/
|
*/
|
||||||
public class SystemPublicMetrics implements PublicMetrics {
|
public class SystemPublicMetrics implements PublicMetrics, Ordered {
|
||||||
|
|
||||||
private long timestamp;
|
private long timestamp;
|
||||||
|
|
||||||
|
|
@ -44,16 +45,19 @@ public class SystemPublicMetrics implements PublicMetrics {
|
||||||
this.timestamp = System.currentTimeMillis();
|
this.timestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return Ordered.HIGHEST_PRECEDENCE + 10;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Metric<?>> metrics() {
|
public Collection<Metric<?>> metrics() {
|
||||||
Collection<Metric<?>> result = new LinkedHashSet<Metric<?>>();
|
Collection<Metric<?>> result = new LinkedHashSet<Metric<?>>();
|
||||||
|
|
||||||
addBasicMetrics(result);
|
addBasicMetrics(result);
|
||||||
addHeapMetrics(result);
|
addHeapMetrics(result);
|
||||||
addThreadMetrics(result);
|
addThreadMetrics(result);
|
||||||
addClassLoadingMetrics(result);
|
addClassLoadingMetrics(result);
|
||||||
addGarbageCollectionMetrics(result);
|
addGarbageCollectionMetrics(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
package org.springframework.boot.actuate.endpoint;
|
package org.springframework.boot.actuate.endpoint;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.metrics.Metric;
|
import org.springframework.boot.actuate.metrics.Metric;
|
||||||
|
|
@ -26,27 +25,21 @@ import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of {@link PublicMetrics} that exposes all metrics from a
|
* Default implementation of {@link PublicMetrics} that exposes all metrics from a
|
||||||
* {@link MetricReader} along with a collection of configurable {@link PublicMetrics}
|
* {@link MetricReader} along with memory information.
|
||||||
* instances.
|
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @author Christian Dupuis
|
* @author Christian Dupuis
|
||||||
* @author Stephane Nicoll
|
* @deprecated since 1.2 in favor of {@link SystemPublicMetrics},
|
||||||
|
* {@code MetricReaderPublicMetrics}
|
||||||
*/
|
*/
|
||||||
public class VanillaPublicMetrics implements PublicMetrics {
|
@Deprecated
|
||||||
|
public class VanillaPublicMetrics extends SystemPublicMetrics {
|
||||||
|
|
||||||
private final MetricReader reader;
|
private final MetricReader reader;
|
||||||
private final Collection<PublicMetrics> publicMetrics;
|
|
||||||
|
|
||||||
public VanillaPublicMetrics(MetricReader reader, Collection<PublicMetrics> publicMetrics) {
|
|
||||||
Assert.notNull(reader, "MetricReader must not be null");
|
|
||||||
Assert.notNull(publicMetrics, "PublicMetrics must not be null");
|
|
||||||
this.reader = reader;
|
|
||||||
this.publicMetrics = publicMetrics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VanillaPublicMetrics(MetricReader reader) {
|
public VanillaPublicMetrics(MetricReader reader) {
|
||||||
this(reader, Collections.<PublicMetrics>emptyList());
|
Assert.notNull(reader, "MetricReader must not be null");
|
||||||
|
this.reader = reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -55,10 +48,7 @@ public class VanillaPublicMetrics implements PublicMetrics {
|
||||||
for (Metric<?> metric : this.reader.findAll()) {
|
for (Metric<?> metric : this.reader.findAll()) {
|
||||||
result.add(metric);
|
result.add(metric);
|
||||||
}
|
}
|
||||||
for (PublicMetrics publicMetric : publicMetrics) {
|
result.addAll(super.metrics());
|
||||||
result.addAll(publicMetric.metrics());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.autoconfigure;
|
package org.springframework.boot.actuate.autoconfigure;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint;
|
import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint;
|
||||||
|
|
@ -43,10 +47,6 @@ import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link EndpointAutoConfiguration}.
|
* Tests for {@link EndpointAutoConfiguration}.
|
||||||
*
|
*
|
||||||
|
|
@ -83,8 +83,8 @@ public class EndpointAutoConfigurationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void healthEndpoint() {
|
public void healthEndpoint() {
|
||||||
load(EmbeddedDataSourceConfiguration.class,
|
load(EmbeddedDataSourceConfiguration.class, EndpointAutoConfiguration.class,
|
||||||
EndpointAutoConfiguration.class, HealthIndicatorAutoConfiguration.class);
|
HealthIndicatorAutoConfiguration.class);
|
||||||
HealthEndpoint bean = this.context.getBean(HealthEndpoint.class);
|
HealthEndpoint bean = this.context.getBean(HealthEndpoint.class);
|
||||||
assertNotNull(bean);
|
assertNotNull(bean);
|
||||||
Health result = bean.invoke();
|
Health result = bean.invoke();
|
||||||
|
|
@ -94,8 +94,7 @@ public class EndpointAutoConfigurationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void healthEndpointWithDefaultHealthIndicator() {
|
public void healthEndpointWithDefaultHealthIndicator() {
|
||||||
load(EndpointAutoConfiguration.class,
|
load(EndpointAutoConfiguration.class, HealthIndicatorAutoConfiguration.class);
|
||||||
HealthIndicatorAutoConfiguration.class);
|
|
||||||
HealthEndpoint bean = this.context.getBean(HealthEndpoint.class);
|
HealthEndpoint bean = this.context.getBean(HealthEndpoint.class);
|
||||||
assertNotNull(bean);
|
assertNotNull(bean);
|
||||||
Health result = bean.invoke();
|
Health result = bean.invoke();
|
||||||
|
|
@ -128,8 +127,7 @@ public class EndpointAutoConfigurationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void autoConfigurationAuditEndpoints() {
|
public void autoConfigurationAuditEndpoints() {
|
||||||
load(EndpointAutoConfiguration.class,
|
load(EndpointAutoConfiguration.class, ConditionEvaluationReport.class);
|
||||||
ConditionEvaluationReport.class);
|
|
||||||
assertNotNull(this.context.getBean(AutoConfigurationReportEndpoint.class));
|
assertNotNull(this.context.getBean(AutoConfigurationReportEndpoint.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +161,6 @@ public class EndpointAutoConfigurationTests {
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class CustomPublicMetricsConfig {
|
static class CustomPublicMetricsConfig {
|
||||||
|
|
||||||
|
|
@ -172,9 +169,11 @@ public class EndpointAutoConfigurationTests {
|
||||||
return new PublicMetrics() {
|
return new PublicMetrics() {
|
||||||
@Override
|
@Override
|
||||||
public Collection<Metric<?>> metrics() {
|
public Collection<Metric<?>> metrics() {
|
||||||
return Collections.<Metric<?>>singleton(new Metric<Integer>("foo", 1));
|
Metric<Integer> metric = new Metric<Integer>("foo", 1);
|
||||||
|
return Collections.<Metric<?>> singleton(metric);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.actuate.endpoint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.boot.actuate.metrics.Metric;
|
||||||
|
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link MetricReaderPublicMetrics}.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class MetricReaderPublicMetricsTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exposesMetrics() {
|
||||||
|
List<Metric<?>> metrics = new ArrayList<Metric<?>>();
|
||||||
|
metrics.add(mock(Metric.class));
|
||||||
|
metrics.add(mock(Metric.class));
|
||||||
|
MetricReader reader = mock(MetricReader.class);
|
||||||
|
given(reader.findAll()).willReturn(metrics);
|
||||||
|
MetricReaderPublicMetrics publicMetrics = new MetricReaderPublicMetrics(reader);
|
||||||
|
assertEquals(metrics, publicMetrics.metrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,16 +16,25 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.endpoint;
|
package org.springframework.boot.actuate.endpoint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.boot.actuate.metrics.Metric;
|
import org.springframework.boot.actuate.metrics.Metric;
|
||||||
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;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -35,6 +44,12 @@ import static org.junit.Assert.assertThat;
|
||||||
*/
|
*/
|
||||||
public class MetricsEndpointTests extends AbstractEndpointTests<MetricsEndpoint> {
|
public class MetricsEndpointTests extends AbstractEndpointTests<MetricsEndpoint> {
|
||||||
|
|
||||||
|
private Metric<Number> metric1 = new Metric<Number>("a", 1);
|
||||||
|
|
||||||
|
private Metric<Number> metric2 = new Metric<Number>("b", 2);;
|
||||||
|
|
||||||
|
private Metric<Number> metric3 = new Metric<Number>("c", 3);;
|
||||||
|
|
||||||
public MetricsEndpointTests() {
|
public MetricsEndpointTests() {
|
||||||
super(Config.class, MetricsEndpoint.class, "metrics", true, "endpoints.metrics");
|
super(Config.class, MetricsEndpoint.class, "metrics", true, "endpoints.metrics");
|
||||||
}
|
}
|
||||||
|
|
@ -44,6 +59,43 @@ public class MetricsEndpointTests extends AbstractEndpointTests<MetricsEndpoint>
|
||||||
assertThat(getEndpointBean().invoke().get("a"), equalTo((Object) 0.5f));
|
assertThat(getEndpointBean().invoke().get("a"), equalTo((Object) 0.5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ordered() {
|
||||||
|
List<PublicMetrics> publicMetrics = new ArrayList<PublicMetrics>();
|
||||||
|
publicMetrics.add(new TestPublicMetrics(2, this.metric2, this.metric2,
|
||||||
|
this.metric3));
|
||||||
|
publicMetrics.add(new TestPublicMetrics(1, this.metric1));
|
||||||
|
Map<String, Object> metrics = new MetricsEndpoint(publicMetrics).invoke();
|
||||||
|
Iterator<Entry<String, Object>> iterator = metrics.entrySet().iterator();
|
||||||
|
assertEquals("a", iterator.next().getKey());
|
||||||
|
assertEquals("b", iterator.next().getKey());
|
||||||
|
assertEquals("c", iterator.next().getKey());
|
||||||
|
assertFalse(iterator.hasNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestPublicMetrics implements PublicMetrics, Ordered {
|
||||||
|
|
||||||
|
private final int order;
|
||||||
|
|
||||||
|
private final List<Metric<?>> metrics;
|
||||||
|
|
||||||
|
public TestPublicMetrics(int order, Metric<?>... metrics) {
|
||||||
|
this.order = order;
|
||||||
|
this.metrics = Arrays.asList(metrics);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return this.order;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Metric<?>> metrics() {
|
||||||
|
return this.metrics;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties
|
@EnableConfigurationProperties
|
||||||
public static class Config {
|
public static class Config {
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,14 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.endpoint;
|
package org.springframework.boot.actuate.endpoint;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.metrics.Metric;
|
import org.springframework.boot.actuate.metrics.Metric;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link SystemPublicMetrics}
|
* Tests for {@link SystemPublicMetrics}
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.endpoint;
|
package org.springframework.boot.actuate.endpoint;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@ -29,15 +25,16 @@ import org.springframework.boot.actuate.metrics.Metric;
|
||||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
|
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link VanillaPublicMetrics}.
|
* Tests for {@link VanillaPublicMetrics}.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Christian Dupuis
|
* @author Christian Dupuis
|
||||||
* @author Stephane Nicoll
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class VanillaPublicMetricsTests {
|
public class VanillaPublicMetricsTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -49,38 +46,36 @@ public class VanillaPublicMetricsTests {
|
||||||
for (Metric<?> metric : publicMetrics.metrics()) {
|
for (Metric<?> metric : publicMetrics.metrics()) {
|
||||||
results.put(metric.getName(), metric);
|
results.put(metric.getName(), metric);
|
||||||
}
|
}
|
||||||
|
assertTrue(results.containsKey("mem"));
|
||||||
|
assertTrue(results.containsKey("mem.free"));
|
||||||
assertThat(results.get("a").getValue().doubleValue(), equalTo(0.5));
|
assertThat(results.get("a").getValue().doubleValue(), equalTo(0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAdditionalMetrics() throws Exception {
|
public void testSystemMetrics() throws Exception {
|
||||||
InMemoryMetricRepository repository = new InMemoryMetricRepository();
|
InMemoryMetricRepository repository = new InMemoryMetricRepository();
|
||||||
Collection<PublicMetrics> allMetrics = new ArrayList<PublicMetrics>();
|
repository.set(new Metric<Double>("a", 0.5, new Date()));
|
||||||
allMetrics.add(new ImmutablePublicMetrics(new Metric<Number>("first", 2L)));
|
VanillaPublicMetrics publicMetrics = new VanillaPublicMetrics(repository);
|
||||||
allMetrics.add(new ImmutablePublicMetrics(new Metric<Number>("second", 4L)));
|
|
||||||
|
|
||||||
VanillaPublicMetrics publicMetrics = new VanillaPublicMetrics(repository, allMetrics);
|
|
||||||
Map<String, Metric<?>> results = new HashMap<String, Metric<?>>();
|
Map<String, Metric<?>> results = new HashMap<String, Metric<?>>();
|
||||||
for (Metric<?> metric : publicMetrics.metrics()) {
|
for (Metric<?> metric : publicMetrics.metrics()) {
|
||||||
results.put(metric.getName(), metric);
|
results.put(metric.getName(), metric);
|
||||||
}
|
}
|
||||||
assertTrue(results.containsKey("first"));
|
assertTrue(results.containsKey("mem"));
|
||||||
assertTrue(results.containsKey("second"));
|
assertTrue(results.containsKey("mem.free"));
|
||||||
assertEquals(2, results.size());
|
assertTrue(results.containsKey("processors"));
|
||||||
}
|
assertTrue(results.containsKey("uptime"));
|
||||||
|
|
||||||
|
assertTrue(results.containsKey("heap.committed"));
|
||||||
|
assertTrue(results.containsKey("heap.init"));
|
||||||
|
assertTrue(results.containsKey("heap.used"));
|
||||||
|
assertTrue(results.containsKey("heap"));
|
||||||
|
|
||||||
private static class ImmutablePublicMetrics implements PublicMetrics {
|
assertTrue(results.containsKey("threads.peak"));
|
||||||
private final Collection<Metric<?>> metrics;
|
assertTrue(results.containsKey("threads.daemon"));
|
||||||
|
assertTrue(results.containsKey("threads"));
|
||||||
|
|
||||||
private ImmutablePublicMetrics(Metric<?> metrics) {
|
assertTrue(results.containsKey("classes.loaded"));
|
||||||
this.metrics = new LinkedHashSet<Metric<?>>();
|
assertTrue(results.containsKey("classes.unloaded"));
|
||||||
this.metrics.addAll(Arrays.asList(metrics));
|
assertTrue(results.containsKey("classes"));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Metric<?>> metrics() {
|
|
||||||
return metrics;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -585,12 +585,12 @@ Spring Boot Actuator includes a metrics service with ``gauge'' and ``counter'' s
|
||||||
A ``gauge'' records a single value; and a ``counter'' records a delta (an increment or
|
A ``gauge'' records a single value; and a ``counter'' records a delta (an increment or
|
||||||
decrement). Spring Boot Actuator also provides a
|
decrement). Spring Boot Actuator also provides a
|
||||||
{sc-spring-boot-actuator}/endpoint/PublicMetrics.{sc-ext}[`PublicMetrics`] interface that
|
{sc-spring-boot-actuator}/endpoint/PublicMetrics.{sc-ext}[`PublicMetrics`] interface that
|
||||||
you can implement to expose metrics that you cannot record via one of those two mechanisms. Look
|
you can implement to expose metrics that you cannot record via one of those two
|
||||||
at {sc-spring-boot-actuator}/endpoint/SystemPublicMetrics.{sc-ext}[`SystemPublicMetrics`]
|
mechanisms. Look at {sc-spring-boot-actuator}/endpoint/SystemPublicMetrics.{sc-ext}[`SystemPublicMetrics`]
|
||||||
for an example.
|
for an example.
|
||||||
|
|
||||||
Metrics for all HTTP requests are automatically recorded, so if you hit the
|
Metrics for all HTTP requests are automatically recorded, so if you hit the `metrics`
|
||||||
`metrics` endpoint you should see a response similar to this:
|
endpoint you should see a response similar to this:
|
||||||
|
|
||||||
[source,json,indent=0]
|
[source,json,indent=0]
|
||||||
----
|
----
|
||||||
|
|
@ -668,15 +668,17 @@ TIP: You can use any string as a metric name but you should follow guidelines of
|
||||||
store/graphing technology. Some good guidelines for Graphite are available on
|
store/graphing technology. Some good guidelines for Graphite are available on
|
||||||
http://matt.aimonetti.net/posts/2013/06/26/practical-guide-to-graphite-monitoring/[Matt Aimonetti's Blog].
|
http://matt.aimonetti.net/posts/2013/06/26/practical-guide-to-graphite-monitoring/[Matt Aimonetti's Blog].
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[production-ready-public-metrics]]
|
[[production-ready-public-metrics]]
|
||||||
=== Adding your own public metrics
|
=== Adding your own public metrics
|
||||||
|
|
||||||
To add additional metrics that are computed every time the metrics endpoint is invoked,
|
To add additional metrics that are computed every time the metrics endpoint is invoked,
|
||||||
simply register additional `PublicMetrics` implementation bean(s). By default, all such
|
simply register additional `PublicMetrics` implementation bean(s). By default, all such
|
||||||
beans are gathered by the endpoint. You can easily change that by defining your own
|
beans are gathered by the endpoint. You can easily change that by defining your own
|
||||||
`MetricsEndpoint`.
|
`MetricsEndpoint`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[production-ready-metric-repositories]]
|
[[production-ready-metric-repositories]]
|
||||||
=== Metric repositories
|
=== Metric repositories
|
||||||
Metric service implementations are usually bound to a
|
Metric service implementations are usually bound to a
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue