spring-boot - 如何使用 Spring Boot 2.0 通过 PushGateway 将指标导出到 Prometheus

标签 spring-boot prometheus micrometer

我将 Spring Boot 版本从 1.5.x 升级到 2.0.1,但遇到了新指标问题。

要在 Spring boot 2.0+ 中使用千分尺,我必须删除 <dependency/>micrometer-spring-legacy .不幸的是,management.metrics.export.prometheus.pushgateway 的所有配置消失了。那么如何使用 spring boot 2.0 将指标导出到 pushgateway? 非常感谢!

最佳答案

不幸的是,Prometheus Pushgateway 自动配置尚未进入 Spring-Boot 2。不确定是否接受包含 micromter-spring-legacy 设置的 PR。

与此同时,您可以尝试设置自己的 @Configuration 类,其中包括从 here 开始的所有内容.

这是一个快速拼接在一起的解决方案:

@Configuration
@EnableConfigurationProperties(PushgatewayProperties.class)
public class PushgatewayConfiguration {

    @ConfigurationProperties(prefix = "management.metrics.export.prometheus.pushgateway")
    public static class PushgatewayProperties {
        /**
        * Enable publishing via a Prometheus Pushgateway.
        */
        private Boolean enabled = false;

        /**
        * Required host:port or ip:port of the Pushgateway.
        */
        private String baseUrl = "localhost:9091";

        /**
        * Required identifier for this application instance.
        */
        private String job;

        /**
        * Frequency with which to push metrics to Pushgateway.
        */
        private Duration pushRate = Duration.ofMinutes(1);

        /**
        * Push metrics right before shut-down. Mostly useful for batch jobs.
        */
        private boolean pushOnShutdown = true;

        /**
        * Delete metrics from Pushgateway when application is shut-down
        */
        private boolean deleteOnShutdown = true;

        /**
        * Used to group metrics in pushgateway. A common example is setting
        */
        private Map<String, String> groupingKeys = new HashMap<>();

        public Boolean getEnabled() {
            return enabled;
        }

        public void setEnabled(Boolean enabled) {
            this.enabled = enabled;
        }

        public String getBaseUrl() {
            return baseUrl;
        }

        public void setBaseUrl(String baseUrl) {
            this.baseUrl = baseUrl;
        }

        public String getJob() {
            return job;
        }

        public void setJob(String job) {
            this.job = job;
        }

        public Duration getPushRate() {
            return pushRate;
        }

        public void setPushRate(Duration pushRate) {
            this.pushRate = pushRate;
        }

        public boolean isPushOnShutdown() {
            return pushOnShutdown;
        }

        public void setPushOnShutdown(boolean pushOnShutdown) {
            this.pushOnShutdown = pushOnShutdown;
        }

        public boolean isDeleteOnShutdown() {
            return deleteOnShutdown;
        }

        public void setDeleteOnShutdown(boolean deleteOnShutdown) {
            this.deleteOnShutdown = deleteOnShutdown;
        }

        public Map<String, String> getGroupingKeys() {
            return groupingKeys;
        }

        public void setGroupingKeys(Map<String, String> groupingKeys) {
            this.groupingKeys = groupingKeys;
        }
    }

    static class PrometheusPushGatewayEnabledCondition extends AllNestedConditions {
        public PrometheusPushGatewayEnabledCondition() {
            super(ConfigurationPhase.PARSE_CONFIGURATION);
        }

        @ConditionalOnProperty(value = "management.metrics.export.prometheus.enabled", matchIfMissing = true)
        static class PrometheusMeterRegistryEnabled {
            //
        }

        @ConditionalOnProperty("management.metrics.export.prometheus.pushgateway.enabled")
        static class PushGatewayEnabled {
            //
        }
    }

    /**
    * Configuration for
    * <a href="https://github.com/prometheus/pushgateway">Prometheus
    * Pushgateway</a>.
    *
    * @author David J. M. Karlsen
    */
    @Configuration
    @ConditionalOnClass(PushGateway.class)
    @Conditional(PrometheusPushGatewayEnabledCondition.class)
    @Incubating(since = "1.0.0")
    public class PrometheusPushGatewayConfiguration {
        private final Logger logger = LoggerFactory.getLogger(PrometheusPushGatewayConfiguration.class);
        private final CollectorRegistry collectorRegistry;
        private final PushgatewayProperties pushgatewayProperties;
        private final PushGateway pushGateway;
        private final Environment environment;
        private final ScheduledExecutorService executorService;

        PrometheusPushGatewayConfiguration(CollectorRegistry collectorRegistry,
                PushgatewayProperties pushgatewayProperties, Environment environment) {
            this.collectorRegistry = collectorRegistry;
            this.pushgatewayProperties = pushgatewayProperties;
            this.pushGateway = new PushGateway(pushgatewayProperties.getBaseUrl());
            this.environment = environment;
            this.executorService = Executors.newSingleThreadScheduledExecutor((r) -> {
                final Thread thread = new Thread(r);
                thread.setDaemon(true);
                thread.setName("micrometer-pushgateway");
                return thread;
            });
            executorService.scheduleAtFixedRate(this::push, 0, pushgatewayProperties.getPushRate().toMillis(),
                    TimeUnit.MILLISECONDS);
        }

        void push() {
            try {
                pushGateway.pushAdd(collectorRegistry, job(), pushgatewayProperties.getGroupingKeys());
            } catch (UnknownHostException e) {
                logger.error("Unable to locate host '" + pushgatewayProperties.getBaseUrl()
                        + "'. No longer attempting metrics publication to this host");
                executorService.shutdown();
            } catch (Throwable t) {
                logger.error("Unable to push metrics to Prometheus Pushgateway", t);
            }
        }

        @PreDestroy
        void shutdown() {
            executorService.shutdown();
            if (pushgatewayProperties.isPushOnShutdown()) {
                push();
            }
            if (pushgatewayProperties.isDeleteOnShutdown()) {
                try {
                    pushGateway.delete(job(), pushgatewayProperties.getGroupingKeys());
                } catch (Throwable t) {
                    logger.error("Unable to delete metrics from Prometheus Pushgateway", t);
                }
            }
        }

        private String job() {
            String job = pushgatewayProperties.getJob();
            if (job == null) {
                job = environment.getProperty("spring.application.name");
            }
            if (job == null) {
                // There's a history of Prometheus spring integration defaulting the job name to
                // "spring" from when
                // Prometheus integration didn't exist in Spring itself.
                job = "spring";
            }
            return job;
        }
    }

}

关于spring-boot - 如何使用 Spring Boot 2.0 通过 PushGateway 将指标导出到 Prometheus,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49779684/

相关文章:

java - 如何将 CompletableFuture 与 Spring Boot 结合使用以提供可靠的服务

kubernetes - 如何总结每个服务的指标?

docker - Kubernetes View 服务监视器

java - 使用 micrometer.io 更改 prometheus 端点

micrometer - Micrometer 在 OpenTelemetry 项目中的位置

java - 无法 Autowiring 存储库字段

java - 优化 Spring Boot JPA 查询

java - Spring Boot Resilience4J注解不开路

histogram - 基于Prometheus中的速率了解histogram_quantile

java - Spring Boot Micrometer Metric system_load_average_1m 说明