Skip to content

Commit 0515ca0

Browse files
committed
Auto configure micrometer cache metrics
Closes gh-11221
1 parent 38ac595 commit 0515ca0

File tree

15 files changed

+894
-6
lines changed

15 files changed

+894
-6
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import org.springframework.beans.factory.ObjectProvider;
2929
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
30+
import org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsConfiguration;
3031
import org.springframework.boot.actuate.autoconfigure.metrics.export.MetricsExporter;
3132
import org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasExportConfiguration;
3233
import org.springframework.boot.actuate.autoconfigure.metrics.export.datadog.DatadogExportConfiguration;
@@ -45,6 +46,7 @@
4546
import org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetrics;
4647
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
4748
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
49+
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
4850
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
4951
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
5052
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -68,12 +70,13 @@
6870
@EnableConfigurationProperties(MetricsProperties.class)
6971
@Import({ MeterBindersConfiguration.class, WebMvcMetricsConfiguration.class,
7072
WebFluxMetricsConfiguration.class, RestTemplateMetricsConfiguration.class,
71-
DataSourcePoolMetricsConfiguration.class, AtlasExportConfiguration.class,
72-
DatadogExportConfiguration.class, GangliaExportConfiguration.class,
73-
GraphiteExportConfiguration.class, InfluxExportConfiguration.class,
74-
JmxExportConfiguration.class, PrometheusExportConfiguration.class,
75-
SimpleExportConfiguration.class, StatsdExportConfiguration.class })
76-
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
73+
CacheMetricsConfiguration.class, DataSourcePoolMetricsConfiguration.class,
74+
AtlasExportConfiguration.class, DatadogExportConfiguration.class,
75+
GangliaExportConfiguration.class, GraphiteExportConfiguration.class,
76+
InfluxExportConfiguration.class, JmxExportConfiguration.class,
77+
PrometheusExportConfiguration.class, SimpleExportConfiguration.class,
78+
StatsdExportConfiguration.class })
79+
@AutoConfigureAfter({ CacheAutoConfiguration.class, DataSourceAutoConfiguration.class })
7780
public class MetricsAutoConfiguration {
7881

7982
@Bean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2012-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.metrics.cache;
18+
19+
import com.hazelcast.core.Hazelcast;
20+
import com.hazelcast.spring.cache.HazelcastCache;
21+
import io.micrometer.core.instrument.binder.MeterBinder;
22+
import net.sf.ehcache.Ehcache;
23+
24+
import org.springframework.boot.actuate.metrics.cache.CacheMeterBinderProvider;
25+
import org.springframework.boot.actuate.metrics.cache.CacheMeterBinderProviders;
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
27+
import org.springframework.cache.caffeine.CaffeineCache;
28+
import org.springframework.cache.ehcache.EhCacheCache;
29+
import org.springframework.cache.jcache.JCacheCache;
30+
import org.springframework.context.annotation.Bean;
31+
import org.springframework.context.annotation.Configuration;
32+
33+
/**
34+
* {@link Configuration Auto-configuration} for {@link CacheMeterBinderProvider} beans.
35+
*
36+
* @author Stephane Nicoll
37+
* @since 2.0.0
38+
* @see CacheMeterBinderProviders
39+
*/
40+
@Configuration
41+
@ConditionalOnClass(MeterBinder.class)
42+
class CacheMeterBinderProvidersConfiguration {
43+
44+
@Configuration
45+
@ConditionalOnClass({ CaffeineCache.class, com.github.benmanes.caffeine.cache.Cache.class })
46+
static class CaffeineCacheMeterBinderProviderConfiguration {
47+
48+
@Bean
49+
public CacheMeterBinderProvider caffeineCacheMeterBinderProvider() {
50+
return new CacheMeterBinderProviders.CaffeineCacheMeterBinderProvider();
51+
}
52+
53+
}
54+
55+
@Configuration
56+
@ConditionalOnClass({ EhCacheCache.class, Ehcache.class })
57+
static class EhCache2CacheMeterBinderProviderConfiguration {
58+
59+
@Bean
60+
public CacheMeterBinderProvider ehCache2CacheMeterBinderProvider() {
61+
return new CacheMeterBinderProviders.EhCache2CacheMeterBinderProvider();
62+
}
63+
64+
}
65+
66+
@Configuration
67+
@ConditionalOnClass({ HazelcastCache.class, Hazelcast.class })
68+
static class HazelcastCacheMeterBinderProviderConfiguration {
69+
70+
@Bean
71+
public CacheMeterBinderProvider hazelcastCacheMeterBinderProvider() {
72+
return new CacheMeterBinderProviders.HazelcastCacheMeterBinderProvider();
73+
}
74+
75+
}
76+
77+
@Configuration
78+
@ConditionalOnClass({ JCacheCache.class, javax.cache.CacheManager.class })
79+
static class JCacheCacheMeterBinderProviderConfiguration {
80+
81+
@Bean
82+
public CacheMeterBinderProvider jCacheCacheMeterBinderProvider() {
83+
return new CacheMeterBinderProviders.JCacheCacheMeterBinderProvider();
84+
}
85+
86+
}
87+
88+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2012-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.metrics.cache;
18+
19+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
20+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
21+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
22+
import org.springframework.cache.Cache;
23+
import org.springframework.cache.CacheManager;
24+
import org.springframework.context.annotation.Configuration;
25+
import org.springframework.context.annotation.Import;
26+
27+
/**
28+
* Configure metrics for all available {@link Cache caches}.
29+
*
30+
* @author Stephane Nicoll
31+
* @since 2.0.0
32+
*/
33+
@Configuration
34+
@ConditionalOnBean(CacheManager.class)
35+
@ConditionalOnProperty(value = "management.metrics.cache.instrument-cache", matchIfMissing = true)
36+
@EnableConfigurationProperties(CacheMetricsProperties.class)
37+
@Import({ CacheMeterBinderProvidersConfiguration.class, CacheMetricsRegistrarConfiguration.class })
38+
public class CacheMetricsConfiguration {
39+
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2012-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.metrics.cache;
18+
19+
import org.springframework.boot.context.properties.ConfigurationProperties;
20+
21+
/**
22+
* Configuration properties for Cache-based metrics.
23+
*
24+
* @author Stephane Nicoll
25+
* @since 2.0.0
26+
*/
27+
@ConfigurationProperties("management.metrics.cache")
28+
public class CacheMetricsProperties {
29+
30+
/**
31+
* Name of the metric for cache usage.
32+
*/
33+
private String cacheMetricName = "cache";
34+
35+
public String getCacheMetricName() {
36+
return this.cacheMetricName;
37+
}
38+
39+
public void setCacheMetricName(String cacheMetricName) {
40+
this.cacheMetricName = cacheMetricName;
41+
}
42+
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright 2012-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.metrics.cache;
18+
19+
import java.util.ArrayList;
20+
import java.util.Arrays;
21+
import java.util.Collection;
22+
import java.util.List;
23+
24+
import io.micrometer.core.instrument.MeterRegistry;
25+
import io.micrometer.core.instrument.Tag;
26+
import io.micrometer.core.instrument.Tags;
27+
import io.micrometer.core.instrument.binder.MeterBinder;
28+
29+
import org.springframework.boot.actuate.metrics.cache.CacheMeterBinderProvider;
30+
import org.springframework.cache.Cache;
31+
32+
/**
33+
* Register supported {@link Cache} to a {@link MeterRegistry}.
34+
*
35+
* @author Stephane Nicoll
36+
* @since 2.0.0
37+
*/
38+
public class CacheMetricsRegistrar {
39+
40+
private final MeterRegistry registry;
41+
42+
private final String metricName;
43+
44+
private final Collection<CacheMeterBinderProvider> cacheMeterBinderProviders;
45+
46+
/**
47+
* Creates a new registrar.
48+
* @param registry the {@link MeterRegistry} to use
49+
* @param metricName the name of the metric
50+
* @param binderProviders the {@link CacheMeterBinderProvider} instances that should
51+
* be used to detect compatible caches
52+
*/
53+
public CacheMetricsRegistrar(MeterRegistry registry, String metricName,
54+
Collection<CacheMeterBinderProvider> binderProviders) {
55+
this.registry = registry;
56+
this.metricName = metricName;
57+
this.cacheMeterBinderProviders = binderProviders;
58+
}
59+
60+
/**
61+
* Attempt to bind the specified {@link Cache} to the registry. Return {@code true}
62+
* if the cache is supported and was bound to the registry, {@code false} otherwise.
63+
* @param cache the cache to handle
64+
* @param tags the tags to associate with the metrics of that cache
65+
* @return {@code true} if the {@code cache} is supported and was registered
66+
*/
67+
public boolean bindCacheToRegistry(Cache cache, Tag... tags) {
68+
List<Tag> allTags = new ArrayList(Arrays.asList(tags));
69+
MeterBinder meterBinder = getMeterBinder(cache, allTags);
70+
if (meterBinder != null) {
71+
meterBinder.bindTo(this.registry);
72+
return true;
73+
}
74+
return false;
75+
}
76+
77+
private MeterBinder getMeterBinder(Cache cache, List<Tag> tags) {
78+
tags.addAll(getAdditionalTags(cache));
79+
for (CacheMeterBinderProvider binderProvider : this.cacheMeterBinderProviders) {
80+
MeterBinder meterBinder = binderProvider.getMeterBinder(cache,
81+
this.metricName, tags);
82+
if (meterBinder != null) {
83+
return meterBinder;
84+
}
85+
}
86+
return null;
87+
}
88+
89+
/**
90+
* Return additional {@link Tag tags} to be associated with the given {@link Cache}.
91+
* @param cache the cache
92+
* @return a list of additional tags to associate to that {@code cache}.
93+
*/
94+
protected List<Tag> getAdditionalTags(Cache cache) {
95+
return Tags.zip("name", cache.getName());
96+
}
97+
98+
}

0 commit comments

Comments
 (0)