001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus; 018 019import java.time.Duration; 020import java.util.Map; 021 022import io.micrometer.core.instrument.Clock; 023import io.micrometer.prometheus.PrometheusConfig; 024import io.micrometer.prometheus.PrometheusMeterRegistry; 025import io.prometheus.client.CollectorRegistry; 026import io.prometheus.client.exporter.PushGateway; 027 028import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint; 029import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; 030import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; 031import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; 032import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager; 033import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager.ShutdownOperation; 034import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScrapeEndpoint; 035import org.springframework.boot.autoconfigure.AutoConfigureAfter; 036import org.springframework.boot.autoconfigure.AutoConfigureBefore; 037import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 038import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 039import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 040import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 041import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 042import org.springframework.boot.context.properties.EnableConfigurationProperties; 043import org.springframework.context.annotation.Bean; 044import org.springframework.context.annotation.Configuration; 045import org.springframework.core.env.Environment; 046 047/** 048 * {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Prometheus. 049 * 050 * @since 2.0.0 051 * @author Jon Schneider 052 * @author David J. M. Karlsen 053 */ 054@Configuration 055@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, 056 SimpleMetricsExportAutoConfiguration.class }) 057@AutoConfigureAfter(MetricsAutoConfiguration.class) 058@ConditionalOnBean(Clock.class) 059@ConditionalOnClass(PrometheusMeterRegistry.class) 060@ConditionalOnProperty(prefix = "management.metrics.export.prometheus", name = "enabled", havingValue = "true", matchIfMissing = true) 061@EnableConfigurationProperties(PrometheusProperties.class) 062public class PrometheusMetricsExportAutoConfiguration { 063 064 @Bean 065 @ConditionalOnMissingBean 066 public PrometheusConfig prometheusConfig(PrometheusProperties prometheusProperties) { 067 return new PrometheusPropertiesConfigAdapter(prometheusProperties); 068 } 069 070 @Bean 071 @ConditionalOnMissingBean 072 public PrometheusMeterRegistry prometheusMeterRegistry( 073 PrometheusConfig prometheusConfig, CollectorRegistry collectorRegistry, 074 Clock clock) { 075 return new PrometheusMeterRegistry(prometheusConfig, collectorRegistry, clock); 076 } 077 078 @Bean 079 @ConditionalOnMissingBean 080 public CollectorRegistry collectorRegistry() { 081 return new CollectorRegistry(true); 082 } 083 084 @Configuration 085 public static class PrometheusScrapeEndpointConfiguration { 086 087 @Bean 088 @ConditionalOnEnabledEndpoint 089 @ConditionalOnMissingBean 090 public PrometheusScrapeEndpoint prometheusEndpoint( 091 CollectorRegistry collectorRegistry) { 092 return new PrometheusScrapeEndpoint(collectorRegistry); 093 } 094 095 } 096 097 /** 098 * Configuration for <a href="https://github.com/prometheus/pushgateway">Prometheus 099 * Pushgateway</a>. 100 */ 101 @Configuration 102 @ConditionalOnClass(PushGateway.class) 103 @ConditionalOnProperty(prefix = "management.metrics.export.prometheus.pushgateway", name = "enabled") 104 public static class PrometheusPushGatewayConfiguration { 105 106 /** 107 * The fallback job name. We use 'spring' since there's a history of Prometheus 108 * spring integration defaulting to that name from when Prometheus integration 109 * didn't exist in Spring itself. 110 */ 111 private static final String FALLBACK_JOB = "spring"; 112 113 @Bean 114 @ConditionalOnMissingBean 115 public PrometheusPushGatewayManager prometheusPushGatewayManager( 116 CollectorRegistry collectorRegistry, 117 PrometheusProperties prometheusProperties, Environment environment) { 118 PrometheusProperties.Pushgateway properties = prometheusProperties 119 .getPushgateway(); 120 PushGateway pushGateway = new PushGateway(properties.getBaseUrl()); 121 Duration pushRate = properties.getPushRate(); 122 String job = getJob(properties, environment); 123 Map<String, String> groupingKey = properties.getGroupingKey(); 124 ShutdownOperation shutdownOperation = properties.getShutdownOperation(); 125 return new PrometheusPushGatewayManager(pushGateway, collectorRegistry, 126 pushRate, job, groupingKey, shutdownOperation); 127 } 128 129 private String getJob(PrometheusProperties.Pushgateway properties, 130 Environment environment) { 131 String job = properties.getJob(); 132 job = (job != null) ? job 133 : environment.getProperty("spring.application.name"); 134 return (job != null) ? job : FALLBACK_JOB; 135 } 136 137 } 138 139}