前言
这里我们来讲解一下MetricReaderPublicMetrics,RichGaugeReaderPublicMetrics的实现,之前由于没有讲解完RichGaugeReader,MetricReader的实现,因此就没有讲解.由于现在我们基本上讲解完了前置要求(RichGaugeReader,MetricReader的实现),因此,这里就把之前漏掉没说明的进行讲解.
解析
MetricReaderPublicMetrics
字段,构造器如下:
private final MetricReader metricReader; public MetricReaderPublicMetrics(MetricReader metricReader) { Assert.notNull(metricReader, "MetricReader must not be null"); this.metricReader = metricReader; }
其metrics方法实现如下:
public Collection<Metric<?>> metrics() { List<Metric<?>> result = new ArrayList<Metric<?>>(); for (Metric<?> metric : this.metricReader.findAll()) { result.add(metric); } return result; }
自动装配:
该类的自动装配有3种情况,如图:
PublicMetricsAutoConfiguration,声明如下:
@Bean public MetricReaderPublicMetrics metricReaderPublicMetrics() { // 默认情况下,this.metricReaders 等于null return new MetricReaderPublicMetrics( new CompositeMetricReader(this.metricReaders == null ? new MetricReader[0] : this.metricReaders .toArray(new MetricReader[this.metricReaders.size()]))); }
首先实例化CompositeMetricReader,由于默认情况下metricReaders 等于null,因此,此时传入CompositeMetricReader的是1个空数组. metricReaders声明如下:
private final List<MetricReader> metricReaders; public PublicMetricsAutoConfiguration( @ExportMetricReader ObjectProvider<List<MetricReader>> metricReaders) { this.metricReaders = metricReaders.getIfAvailable(); }
当我们加入了liquibase-core的依赖后,MetricsDropwizardAutoConfiguration该配置类就会生效,其中进行了如下声明:
@Bean public MetricReaderPublicMetrics dropwizardPublicMetrics( MetricRegistry metricRegistry) { MetricRegistryMetricReader reader = new MetricRegistryMetricReader( metricRegistry); return new MetricReaderPublicMetrics(reader); }
此时,MetricReaderPublicMetrics中持有的MetricReader是MetricRegistryMetricReader,因此最终会从MetricRegistry中获得数据.
关于此处的讲解,可以参考之前的文章–>spring boot 源码解析26-Liquibase使用及LiquibaseEndpoint解析,spring boot 源码解析39-DropwizardMetricServices详解.
在加入了spring-boot-starter-integration之后,IntegrationMetricsConfiguration该配置类就会生效,如下:
@Configuration @ConditionalOnClass(EnableIntegrationManagement.class) @ConditionalOnJava(JavaVersion.SEVEN) @UsesJava7 static class IntegrationMetricsConfiguration { @Bean(name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME) @ConditionalOnMissingBean(value = IntegrationManagementConfigurer.class, name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME, search = SearchStrategy.CURRENT) public IntegrationManagementConfigurer managementConfigurer() { IntegrationManagementConfigurer configurer = new IntegrationManagementConfigurer(); configurer.setDefaultCountsEnabled(true); configurer.setDefaultStatsEnabled(true); return configurer; } @Bean @ConditionalOnMissingBean(name = "springIntegrationPublicMetrics") public MetricReaderPublicMetrics springIntegrationPublicMetrics( IntegrationManagementConfigurer managementConfigurer) { return new MetricReaderPublicMetrics( new SpringIntegrationMetricReader(managementConfigurer)); } }
IntegrationMetricsConfiguration满足如下条件时生效:
- @ConditionalOnClass(EnableIntegrationManagement.class) –> 类路径下存在EnableIntegrationManagement.class时生效,由于加入了spring-boot-starter-integration的依赖,因此该条件生效.
- @ConditionalOnJava(JavaVersion.SEVEN)–> 在jdk1.7及以上的环境中运行时生效.
生效后,会注册如下2个bean:
id为managementConfigurer.当满足如下条件时生效:
- @ConditionalOnMissingBean(value = IntegrationManagementConfigurer.class, name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME, search = SearchStrategy.CURRENT)–> 在当前applicationContext中不存在id为integrationManagementConfigurer,类型为IntegrationManagementConfigurer时生效.
id为springIntegrationPublicMetrics,当满足在BeanFactory中不存在类型为MetricReaderPublicMetrics,id为springIntegrationPublicMetrics的bean时生效.因此,此时MetricReaderPublicMetrics会读取IntegrationManagementConfigurer中的数据,在上篇文章的基础上,访问http://127.0.0.1:8080/metrics,会发现返回如下内容:
integration.channel.errorChannel.errorRate.mean: 0, ...... integration.channel.errorChannel.sendRate.count: 0, ..... integration.channel.metricsChannel.sendRate.count: 0, integration.channel.nullChannel.errorRate.mean: 0, .... integration.channel.nullChannel.sendRate.count: 0, integration.handler.org.springframework.integration.stream.CharacterStreamWritingMessageHandler#0.duration.mean: 0, .... integration.handler.org.springframework.integration.stream.CharacterStreamWritingMessageHandler#0.activeCount: 0, integration.handler._org.springframework.integration.errorLogger.handler.duration.mean: 0, integration.handler._org.springframework.integration.errorLogger.handler.duration.max: 0, integration.handler._org.springframework.integration.errorLogger.handler.duration.min: 0, integration.handler._org.springframework.integration.errorLogger.handler.duration.stdev: 0, integration.handler._org.springframework.integration.errorLogger.handler.duration.count: 0, integration.handler._org.springframework.integration.errorLogger.handler.activeCount: 0, integration.handlerCount: 2, integration.channelCount: 3, integration.sourceCount: 0,
其中:
- integration.channel.errorChannel.* 是统计errorChannel的指标,errorChannel是自动配置的
- integration.channel.metricsChannel.*–>metricsChannel是我们自己声明的,见spring boot 源码解析42-MessageChannelMetricWriter详解.
- integration.channel.nullChannel.* 是统计nullChannel的指标,errorChannel是自动配置的
- integration.handler.org.springframework.integration.stream.CharacterStreamWritingMessageHandler#0 –> CharacterStreamWritingMessageHandler是我们自己声明的,见spring boot 源码解析42-MessageChannelMetricWriter详解.
- integration.handler._org.springframework.integration.errorLogger.*–> errorLogger是自动装配的
更多内容,请看–>spring boot 源码解析42-MessageChannelMetricWriter详解
RichGaugeReaderPublicMetrics
该类实现了PublicMetrics
字段,构造器如下:
private final RichGaugeReader richGaugeReader; public RichGaugeReaderPublicMetrics(RichGaugeReader richGaugeReader) { Assert.notNull(richGaugeReader, "RichGaugeReader must not be null"); this.richGaugeReader = richGaugeReader; }
其metrics实现如下:
public Collection<Metric<?>> metrics() { List<Metric<?>> result = new ArrayList<Metric<?>>(); for (RichGauge richGauge : this.richGaugeReader.findAll()) { result.addAll(convert(richGauge)); } return result; }
- 从RichGaugeReader获得所有的RichGauge,进行遍历
依次调用convert方法,获得对应的Metric,加入到结果集中,代码如下:
private List<Metric<?>> convert(RichGauge gauge) { List<Metric<?>> result = new ArrayList<Metric<?>>(6); result.add( new Metric<Double>(gauge.getName() + RichGauge.AVG, gauge.getAverage())); result.add(new Metric<Double>(gauge.getName() + RichGauge.VAL, gauge.getValue())); result.add(new Metric<Double>(gauge.getName() + RichGauge.MIN, gauge.getMin())); result.add(new Metric<Double>(gauge.getName() + RichGauge.MAX, gauge.getMax())); result.add( new Metric<Double>(gauge.getName() + RichGauge.ALPHA, gauge.getAlpha())); result.add(new Metric<Long>(gauge.getName() + RichGauge.COUNT, gauge.getCount())); return result; }
该方法还是比较简单的,将RichGauge持有的各种指标,封装为对应的Metric,加入到结果即可.
自动装配:
在PublicMetricsAutoConfiguration中进行了声明,代码如下:
@Bean @ConditionalOnBean(RichGaugeReader.class) public RichGaugeReaderPublicMetrics richGaugePublicMetrics( RichGaugeReader richGaugeReader) { return new RichGaugeReaderPublicMetrics(richGaugeReader); }
当BeanFactory中存在RichGaugeReader类型的bean时生效.
由于默认情况下,没有 RichGaugeReader类型的bean,因此, RichGaugeReaderPublicMetrics不会进行自动装配.
证明如下:
访问http://127.0.0.1:8080/autoconfig,可以看到如下内容:
PublicMetricsAutoConfiguration#richGaugePublicMetrics: { notMatched: [ { condition: "OnBeanCondition", message: "@ConditionalOnBean (types: org.springframework.boot.actuate.metrics.rich.RichGaugeReader; SearchStrategy: all) did not find any beans" } ], matched: [ ] }