博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
micrometer自定义metrics
阅读量:6938 次
发布时间:2019-06-27

本文共 8274 字,大约阅读时间需要 27 分钟。

本文主要研究下如何使用自定义micrometer的metrics

实例

DemoMetrics

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

注册

  • 原始方式
new DemoMetrics().bindTo(registry);
  • springboot autoconfigure
@Beanpublic DemoMetrics demoMetrics(){    return new DemoMetrics();}
在springboot只要标注下bean,注入到spring容器后,springboot会自动注册到registry。springboot已经帮你初始化了包括UptimeMetrics等一系列metrics。详见源码解析部分。

验证

curl -i http://localhost:8080/actuator/metrics/demo.count

返回实例

{  "name": "demo.count",  "measurements": [    {      "statistic": "VALUE",      "value": 6    }  ],  "availableTags": [    {      "tag": "host",      "values": [        "localhost"      ]    }  ]}

源码解析

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
>) (Object) beansOfType( MeterRegistryCustomizer.class), this.context.getBean(MetricsProperties.class).isUseGlobalRegistry()); } return this.configurer; } private
Collection
beansOfType(Class
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
> customizers; private final Collection
filters; private final Collection
binders; private final boolean addToGlobalRegistry; MeterRegistryConfigurer(Collection
binders, Collection
filters, Collection
> 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

小结

springboot2引入的micrometer,自定义metrics只需要实现MeterBinder接口,然后托管给spring即可,springboot的autoconfigure帮你自动注册到meterRegistry。

doc

转载地址:http://ousnl.baihongyu.com/

你可能感兴趣的文章
004-关闭文件后自动备份
查看>>
js实现当前导航菜单高亮显示
查看>>
Linux常用命令(二)--文件目录命令
查看>>
tomcat启动报错
查看>>
由《旧制度与大革命》提取的5个感触
查看>>
sqlserver 分页
查看>>
php通过system()调用Linux命令问题
查看>>
swift 警告框 - 自定义按钮颜色,图片
查看>>
提高搜索引擎结果页面排名的各种技术
查看>>
刷题常用的STL容器总结
查看>>
创建一个支持ES6的Nodejs项目
查看>>
sqlserver 行转列、字符串行转列、自动生产行转列脚本
查看>>
仿微信表情输入
查看>>
慎用dictionaryWithObjectsAndKeys方法
查看>>
兼容FF IE的回车事件
查看>>
冒泡排序,快速排序, 二叉树,一致性哈希
查看>>
sdut 1451 括号东东 (dp或模拟)
查看>>
POJ1002 487-3279
查看>>
Visual Studio 2012+jQuery-1.7.1
查看>>
Appium 在 Android UI 测试中的应用
查看>>