/* * Copyright 2012-2017 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.autoconfigure; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.actuate.endpoint.MetricsEndpointMetricReader; import org.springframework.boot.actuate.metrics.export.Exporter; import org.springframework.boot.actuate.metrics.export.MetricExportProperties; import org.springframework.boot.actuate.metrics.export.MetricExporters; import org.springframework.boot.actuate.metrics.reader.CompositeMetricReader; import org.springframework.boot.actuate.metrics.reader.MetricReader; import org.springframework.boot.actuate.metrics.statsd.StatsdMetricWriter; import org.springframework.boot.actuate.metrics.writer.GaugeWriter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import org.springframework.util.CollectionUtils; /** * {@link EnableAutoConfiguration Auto-configuration} for metrics export. * * @author Dave Syer * @author Simon Buettner * @since 1.3.0 */ @Configuration @EnableScheduling @ConditionalOnProperty(value = "spring.metrics.export.enabled", matchIfMissing = true) @EnableConfigurationProperties public class MetricExportAutoConfiguration { private final MetricsEndpointMetricReader endpointReader; private final List<MetricReader> readers; private final Map<String, GaugeWriter> writers; private final Map<String, Exporter> exporters; public MetricExportAutoConfiguration(MetricExportProperties properties, ObjectProvider<MetricsEndpointMetricReader> endpointReader, @ExportMetricReader ObjectProvider<List<MetricReader>> readers, @ExportMetricWriter ObjectProvider<Map<String, GaugeWriter>> writers, ObjectProvider<Map<String, Exporter>> exporters) { this.endpointReader = endpointReader.getIfAvailable(); this.readers = readers.getIfAvailable(); this.writers = writers.getIfAvailable(); this.exporters = exporters.getIfAvailable(); } @Bean @ConditionalOnMissingBean(name = "metricWritersMetricExporter") public SchedulingConfigurer metricWritersMetricExporter( MetricExportProperties properties) { Map<String, GaugeWriter> writers = new HashMap<>(); MetricReader reader = this.endpointReader; if (reader == null && !CollectionUtils.isEmpty(this.readers)) { reader = new CompositeMetricReader( this.readers.toArray(new MetricReader[this.readers.size()])); } if (reader == null && CollectionUtils.isEmpty(this.exporters)) { return new NoOpSchedulingConfigurer(); } MetricExporters exporters = new MetricExporters(properties); if (reader != null) { if (!CollectionUtils.isEmpty(this.writers)) { writers.putAll(this.writers); } exporters.setReader(reader); exporters.setWriters(writers); } exporters.setExporters(this.exporters == null ? Collections.<String, Exporter>emptyMap() : this.exporters); return exporters; } @Configuration static class StatsdConfiguration { @Bean @ExportMetricWriter @ConditionalOnMissingBean @ConditionalOnProperty(prefix = "spring.metrics.export.statsd", name = "host") public StatsdMetricWriter statsdMetricWriter(MetricExportProperties properties) { MetricExportProperties.Statsd statsdProperties = properties.getStatsd(); return new StatsdMetricWriter(statsdProperties.getPrefix(), statsdProperties.getHost(), statsdProperties.getPort()); } } @Configuration protected static class MetricExportPropertiesConfiguration { @Value("${spring.application.name:application}.${random.value:0000}") private String prefix = ""; private String aggregateKeyPattern = "k.d"; @Bean(name = "spring.metrics.export-org.springframework.boot.actuate.metrics.export.MetricExportProperties") @ConditionalOnMissingBean public MetricExportProperties metricExportProperties() { MetricExportProperties export = new MetricExportProperties(); export.getRedis().setPrefix("spring.metrics" + (this.prefix.length() > 0 ? "." : "") + this.prefix); export.getAggregate().setPrefix(this.prefix); export.getAggregate().setKeyPattern(this.aggregateKeyPattern); return export; } } private static class NoOpSchedulingConfigurer implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { } } }