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

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

  hot3.png

本文主要研究下如何使用自定义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

转载于:https://my.oschina.net/go4it/blog/1647415

你可能感兴趣的文章
C语言实现直接插入排序,冒泡排序以及二分查找(巩固理解记忆)
查看>>
sqoop相关整理记录
查看>>
Solr基础教程之Schema.xml(二)
查看>>
给控件添加长按弹出菜单(上下文菜单,又叫contextMenu)
查看>>
傻瓜式 Material Design 风格矢量图标生成器
查看>>
Nodejs创建HTTPS服务器
查看>>
ubuntu12.04 安装sublime text 2及插件。
查看>>
AFNetworking、MKNetworkKit和ASIHTTPRequest比较
查看>>
Impala 表使用 Avro 文件格式(翻译)
查看>>
http中返回错误代码的意思
查看>>
Spring – 开发环境 – 手动配置
查看>>
!==和!=有什么区别(js php)
查看>>
python入门神图
查看>>
我的友情链接
查看>>
[一文一命令]ls命令详解
查看>>
EBS FORM 失效工具栏按钮
查看>>
com.sun.jdi.InvocationException occurred invoking method
查看>>
Windows Server 2008 R2 IIS7 搭建PHP环境
查看>>
任务计划
查看>>
交换机杂记
查看>>