Step 1.添加依赖

        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-influx</artifactId>
</dependency>

Step 2.修改Spring配置文件application.yml

management:
endpoints:
enabled-by-default: true
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
metrics:
export:
influx:
enabled: true
db: spring
uri: http://localhost:8086
step: 10s
user-name: admin
password: admin

Step 3. 实现micrometer的MeterBinder接口

public class DemoMetrics implements MeterBinder {
AtomicInteger count = new AtomicInteger(0); @Override
public void bindTo(MeterRegistry meterRegistry) {
Gauge.builder("demo.count", count, c -> c.incrementAndGet())
.tags("host", "localhost")
.description("demo of custom meter binder")
.register(meterRegistry);
}

这里实现了MeterBinder接口的bindTo方法,将要采集的指标注册到MeterRegistry

Step 4.注册

@Bean
public DemoMetrics demoMetrics(){
return new DemoMetrics();
}

在springboot只要标注下bean,注入到spring容器后,springboot会自动注册到registry。springboot已经帮你初始化了包括UptimeMetrics等一系列metrics。

源码解析

MetricsAutoConfiguration

spring-boot-actuator-autoconfigure-2.0.0.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java

@Configuration
@ConditionalOnClass(Timed.class)
@EnableConfigurationProperties(MetricsProperties.class)
@AutoConfigureBefore(CompositeMeterRegistryAutoConfiguration.class)
public class MetricsAutoConfiguration { @Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
} @Bean
public static MeterRegistryPostProcessor meterRegistryPostProcessor(
ApplicationContext context) {
return new MeterRegistryPostProcessor(context);
} @Bean
@Order(0)
public PropertiesMeterFilter propertiesMeterFilter(MetricsProperties properties) {
return new PropertiesMeterFilter(properties);
} @Configuration
@ConditionalOnProperty(value = "management.metrics.binders.jvm.enabled", matchIfMissing = true)
static class JvmMeterBindersConfiguration { @Bean
@ConditionalOnMissingBean
public JvmGcMetrics jvmGcMetrics() {
return new JvmGcMetrics();
} @Bean
@ConditionalOnMissingBean
public JvmMemoryMetrics jvmMemoryMetrics() {
return new JvmMemoryMetrics();
} @Bean
@ConditionalOnMissingBean
public JvmThreadMetrics jvmThreadMetrics() {
return new JvmThreadMetrics();
} @Bean
@ConditionalOnMissingBean
public ClassLoaderMetrics classLoaderMetrics() {
return new ClassLoaderMetrics();
} } @Configuration
static class MeterBindersConfiguration { @Bean
@ConditionalOnClass(name = { "ch.qos.logback.classic.LoggerContext",
"org.slf4j.LoggerFactory" })
@Conditional(LogbackLoggingCondition.class)
@ConditionalOnMissingBean(LogbackMetrics.class)
@ConditionalOnProperty(value = "management.metrics.binders.logback.enabled", matchIfMissing = true)
public LogbackMetrics logbackMetrics() {
return new LogbackMetrics();
} @Bean
@ConditionalOnProperty(value = "management.metrics.binders.uptime.enabled", matchIfMissing = true)
@ConditionalOnMissingBean
public UptimeMetrics uptimeMetrics() {
return new UptimeMetrics();
} @Bean
@ConditionalOnProperty(value = "management.metrics.binders.processor.enabled", matchIfMissing = true)
@ConditionalOnMissingBean
public ProcessorMetrics processorMetrics() {
return new ProcessorMetrics();
} @Bean
@ConditionalOnProperty(name = "management.metrics.binders.files.enabled", matchIfMissing = true)
@ConditionalOnMissingBean
public FileDescriptorMetrics fileDescriptorMetrics() {
return new FileDescriptorMetrics();
} } static class LogbackLoggingCondition extends SpringBootCondition { @Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
ConditionMessage.Builder message = ConditionMessage
.forCondition("LogbackLoggingCondition");
if (loggerFactory instanceof LoggerContext) {
return ConditionOutcome.match(
message.because("ILoggerFactory is a Logback LoggerContext"));
}
return ConditionOutcome
.noMatch(message.because("ILoggerFactory is an instance of "
+ loggerFactory.getClass().getCanonicalName()));
} } }
 

可以看到这里注册了好多metrics,比如UptimeMetrics,JvmGcMetrics,ProcessorMetrics,FileDescriptorMetrics等

这里重点看使用@Bean标注了MeterRegistryPostProcessor

MeterRegistryPostProcessor

spring-boot-actuator-autoconfigure-2.0.0.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java

class MeterRegistryPostProcessor implements BeanPostProcessor {

    private final ApplicationContext context;

    private volatile MeterRegistryConfigurer configurer;

    MeterRegistryPostProcessor(ApplicationContext context) {
this.context = context;
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof MeterRegistry) {
getConfigurer().configure((MeterRegistry) bean);
}
return bean;
} @SuppressWarnings("unchecked")
private MeterRegistryConfigurer getConfigurer() {
if (this.configurer == null) {
this.configurer = new MeterRegistryConfigurer(beansOfType(MeterBinder.class),
beansOfType(MeterFilter.class),
(Collection<MeterRegistryCustomizer<?>>) (Object) beansOfType(
MeterRegistryCustomizer.class),
this.context.getBean(MetricsProperties.class).isUseGlobalRegistry());
}
return this.configurer;
} private <T> Collection<T> beansOfType(Class<T> type) {
return this.context.getBeansOfType(type).values();
} }

可以看到这里new了一个MeterRegistryConfigurer,重点注意这里使用beansOfType(MeterBinder.class)方法的返回值给其构造器

MeterRegistryConfigurer

spring-boot-actuator-autoconfigure-2.0.0.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryConfigurer.java

class MeterRegistryConfigurer {

    private final Collection<MeterRegistryCustomizer<?>> customizers;

    private final Collection<MeterFilter> filters;

    private final Collection<MeterBinder> binders;

    private final boolean addToGlobalRegistry;

    MeterRegistryConfigurer(Collection<MeterBinder> binders,
Collection<MeterFilter> filters,
Collection<MeterRegistryCustomizer<?>> customizers,
boolean addToGlobalRegistry) {
this.binders = (binders != null ? binders : Collections.emptyList());
this.filters = (filters != null ? filters : Collections.emptyList());
this.customizers = (customizers != null ? customizers : Collections.emptyList());
this.addToGlobalRegistry = addToGlobalRegistry;
} void configure(MeterRegistry registry) {
if (registry instanceof CompositeMeterRegistry) {
return;
}
// Customizers must be applied before binders, as they may add custom
// tags or alter timer or summary configuration.
customize(registry);
addFilters(registry);
addBinders(registry);
if (this.addToGlobalRegistry && registry != Metrics.globalRegistry) {
Metrics.addRegistry(registry);
}
} @SuppressWarnings("unchecked")
private void customize(MeterRegistry registry) {
LambdaSafe.callbacks(MeterRegistryCustomizer.class, this.customizers, registry)
.withLogger(MeterRegistryConfigurer.class)
.invoke((customizer) -> customizer.customize(registry));
} private void addFilters(MeterRegistry registry) {
this.filters.forEach(registry.config()::meterFilter);
} private void addBinders(MeterRegistry registry) {
this.binders.forEach((binder) -> binder.bindTo(registry));
} }

可以看到configure方法里头调用了addBinders,也就是把托管给spring容器的MeterBinder实例bindTo到meterRegistry

Spring Boot 2.x 自定义metrics 并导出到influxdb的更多相关文章

  1. spring boot / cloud (四) 自定义线程池以及异步处理@Async

    spring boot / cloud (四) 自定义线程池以及异步处理@Async 前言 什么是线程池? 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线 ...

  2. Spring boot 自动配置自定义配置文件

    示例如下: 1.   新建 Maven 项目 properties 2.   pom.xml <project xmlns="http://maven.apache.org/POM/4 ...

  3. 如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  4. Spring Boot 中关于自定义异常处理的套路!

    在 Spring Boot 项目中 ,异常统一处理,可以使用 Spring 中 @ControllerAdvice 来统一处理,也可以自己来定义异常处理方案.Spring Boot 中,对异常的处理有 ...

  5. Spring Boot笔记之自定义启动banner

    控制banner内容 Spring Boot启动的时候默认的banner是spring的字样,看多了觉得挺单调的,Spring Boot为我们提供了自定义banner的功能. 自定义banner只需要 ...

  6. Spring boot JPA 用自定义主键策略 生成自定义主键ID

    最近学习Spring boot JPA 学习过程解决的一些问题写成随笔,大家一起成长.这次遇到自定义主键的问题 package javax.persistence; public enum Gener ...

  7. 20. Spring Boot 默认、自定义数据源 、配置多个数据源 jdbcTemplate操作DB

    Spring-Boot-2.0.0-M1版本将默认的数据库连接池从tomcat jdbc pool改为了hikari,这里主要研究下hikari的默认配置 0.  创建Spring Boot项目,选中 ...

  8. Spring Boot中的自定义start pom

    start pom是springboot中提供的简化企业级开发绝大多数场景的一个工具,利用好strat pom就可以消除相关技术的配置得到自动配置好的Bean. 举个例子,在一般使用中,我们使用基本的 ...

  9. Spring Boot环境下自定义shiro过滤器会过滤所有的url的问题

    在配置shiro过滤器时增加了自定义的过滤器,主要是用来处理未登录状态下返回一些信息 //自定义过滤器 Map<String, Filter> filtersMap = new Linke ...

随机推荐

  1. 读《JavaScript权威指南》笔记(三)--对象

    1.对象介绍 对象是JavaScript的基本数据类型.对象是一种复合值:它将很多值(原始值或者其他对象)聚合在一起,可通过名字访问这些值.对象也可看做是属性的无序集合,每个属性都是一个名/值对.属性 ...

  2. 【bzoj4800】: [Ceoi2015]Ice Hockey World Championship dfs

    [bzoj4800]: [Ceoi2015]Ice Hockey World Championship N<=40所以如果直接dfs背包会TLE 考虑Meet-in-the-middle 如果把 ...

  3. [CQOI2012][bzoj2668] 交换棋子 [费用流]

    题面 传送门 思路 抖机灵 一开始看到这题我以为是棋盘模型-_-|| 然而现实是骨感的 后来我尝试使用插头dp来交换,然后又惨死 最后我不得不把目光转向那个总能化腐朽为神奇的算法:网络流 思维 我们要 ...

  4. SP8222 NSUBSTR - Substrings

    \(\color{#0066ff}{ 题目描述 }\) 你得到一个字符串,最多由25万个小写拉丁字母组成.我们将 F(x)定义为某些长度X的字符串在s中出现的最大次数,例如字符串'ababaf'- F ...

  5. C# 添加vertical 属性上下边框消失问题

    点击这里的曲别针就好了.... 自定义控件主题..... #学习地址: http://www.cnblogs.com/anding/p/4993655.html

  6. poj3728之离线LCA+dp思想/RMQ+LCA(非常好的题目)

    题意很简单 给一个树(n < 5w) 每个点有个权值,代表商品价格 若干个询问(5w) 对每个询问,问的是从u点走到v点(简单路径),商人在这个路径中的某点买入商品,然后在某点再卖出商品,   ...

  7. 关于django的模板层

    你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. def current_datetime(request): now = datet ...

  8. 阿里Java开发规约(2)

    本文是对阿里插件中规约的详细解释二,关于插件使用,请参考这里 及时清理不再使用的代码段或配置信息. 说明:对于垃圾代码或过时配置,坚决清理干净,避免程序过度臃肿,代码冗余 Positive examp ...

  9. datetimepicker使用

    常考地址:http://www.bootcss.c 直接上代码: 步骤:1.http://www.bootcss.com/p/bootstrap-datetimepicker/下载包 2.将里面的js ...

  10. mysql初始化

    注意:--install前,必须用mysql启动命令的绝对路径 # 制作MySQL的Windows服务,在终端执行此命令: mysqld --install # 移除MySQL的Windows服务,在 ...