springboot读取dropwizard的metrics-程序员宅基地

技术标签: java  

##autoconfig ~/.m2/repository/org/springframework/boot/spring-boot-actuator/1.4.3.RELEASE/spring-boot-actuator-1.4.3.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/MetricsDropwizardAutoConfiguration.java

@Configuration
@ConditionalOnClass(MetricRegistry.class)
@AutoConfigureBefore(MetricRepositoryAutoConfiguration.class)
public class MetricsDropwizardAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	public MetricRegistry metricRegistry() {
		return new MetricRegistry();
	}

	@Bean
	@ConditionalOnMissingBean({ DropwizardMetricServices.class, CounterService.class,
			GaugeService.class })
	public DropwizardMetricServices dropwizardMetricServices(
			MetricRegistry metricRegistry) {
		return new DropwizardMetricServices(metricRegistry);
	}

	@Bean
	public MetricReaderPublicMetrics dropwizardPublicMetrics(
			MetricRegistry metricRegistry) {
		MetricRegistryMetricReader reader = new MetricRegistryMetricReader(
				metricRegistry);
		return new MetricReaderPublicMetrics(reader);
	}

}

这里将dropwizard的metrics包装为MetricReaderPublicMetrics

##MetricRegistryMetricReader ~/.m2/repository/org/springframework/boot/spring-boot-actuator/1.4.3.RELEASE/spring-boot-actuator-1.4.3.RELEASE-sources.jar!/org/springframework/boot/actuate/metrics/reader/MetricRegistryMetricReader.java

public class MetricRegistryMetricReader implements MetricReader, MetricRegistryListener {

	private static final Log logger = LogFactory.getLog(MetricRegistryMetricReader.class);

	private static final Map<Class<?>, Set<String>> numberKeys = new ConcurrentHashMap<Class<?>, Set<String>>();

	private final Object monitor = new Object();

	private final Map<String, String> names = new ConcurrentHashMap<String, String>();

	private final MultiValueMap<String, String> reverse = new LinkedMultiValueMap<String, String>();

	private final MetricRegistry registry;

	public MetricRegistryMetricReader(MetricRegistry registry) {
		this.registry = registry;
		registry.addListener(this);
	}

	@Override
	public Metric<?> findOne(String metricName) {
		String name = this.names.get(metricName);
		if (name == null) {
			return null;
		}
		com.codahale.metrics.Metric metric = this.registry.getMetrics().get(name);
		if (metric == null) {
			return null;
		}
		if (metric instanceof Counter) {
			Counter counter = (Counter) metric;
			return new Metric<Number>(metricName, counter.getCount());
		}
		if (metric instanceof Gauge) {
			Object value = ((Gauge<?>) metric).getValue();
			if (value instanceof Number) {
				return new Metric<Number>(metricName, (Number) value);
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Ignoring gauge '" + name + "' (" + metric
						+ ") as its value is not a Number");
			}
			return null;
		}
		if (metric instanceof Sampling) {
			if (metricName.contains(".snapshot.")) {
				Number value = getMetric(((Sampling) metric).getSnapshot(), metricName);
				if (metric instanceof Timer) {
					// convert back to MILLISEC
					value = TimeUnit.MILLISECONDS.convert(value.longValue(),
							TimeUnit.NANOSECONDS);
				}
				return new Metric<Number>(metricName, value);
			}
		}
		return new Metric<Number>(metricName, getMetric(metric, metricName));
	}

	@Override
	public Iterable<Metric<?>> findAll() {
		return new Iterable<Metric<?>>() {
			@Override
			public Iterator<Metric<?>> iterator() {
				Set<Metric<?>> metrics = new HashSet<Metric<?>>();
				for (String name : MetricRegistryMetricReader.this.names.keySet()) {
					Metric<?> metric = findOne(name);
					if (metric != null) {
						metrics.add(metric);
					}
				}
				return metrics.iterator();
			}
		};
	}

	@Override
	public long count() {
		return this.names.size();
	}

	@Override
	public void onGaugeAdded(String name, Gauge<?> gauge) {
		this.names.put(name, name);
		synchronized (this.monitor) {
			this.reverse.add(name, name);
		}
	}

	@Override
	public void onGaugeRemoved(String name) {
		remove(name);
	}

	@Override
	public void onCounterAdded(String name, Counter counter) {
		this.names.put(name, name);
		synchronized (this.monitor) {
			this.reverse.add(name, name);
		}
	}

	@Override
	public void onCounterRemoved(String name) {
		remove(name);
	}

	@Override
	public void onHistogramAdded(String name, Histogram histogram) {
		for (String key : getNumberKeys(histogram)) {
			String metricName = name + "." + key;
			this.names.put(metricName, name);
			synchronized (this.monitor) {
				this.reverse.add(name, metricName);
			}
		}
		for (String key : getNumberKeys(histogram.getSnapshot())) {
			String metricName = name + ".snapshot." + key;
			this.names.put(metricName, name);
			synchronized (this.monitor) {
				this.reverse.add(name, metricName);
			}
		}
	}

	@Override
	public void onHistogramRemoved(String name) {
		remove(name);
	}

	@Override
	public void onMeterAdded(String name, Meter meter) {
		for (String key : getNumberKeys(meter)) {
			String metricName = name + "." + key;
			this.names.put(metricName, name);
			synchronized (this.monitor) {
				this.reverse.add(name, metricName);
			}
		}
	}

	@Override
	public void onMeterRemoved(String name) {
		remove(name);
	}

	@Override
	public void onTimerAdded(String name, Timer timer) {
		for (String key : getNumberKeys(timer)) {
			String metricName = name + "." + key;
			this.names.put(metricName, name);
			synchronized (this.monitor) {
				this.reverse.add(name, metricName);
			}
		}
		for (String key : getNumberKeys(timer.getSnapshot())) {
			String metricName = name + ".snapshot." + key;
			this.names.put(metricName, name);
			synchronized (this.monitor) {
				this.reverse.add(name, metricName);
			}
		}
	}

	@Override
	public void onTimerRemoved(String name) {
		remove(name);
	}

	private void remove(String name) {
		List<String> keys;
		synchronized (this.monitor) {
			keys = this.reverse.remove(name);
		}
		if (keys != null) {
			for (String key : keys) {
				this.names.remove(name + "." + key);
			}
		}
	}

	private static Set<String> getNumberKeys(Object metric) {
		Set<String> result = numberKeys.get(metric.getClass());
		if (result == null) {
			result = new HashSet<String>();
		}
		if (result.isEmpty()) {
			for (PropertyDescriptor descriptor : BeanUtils
					.getPropertyDescriptors(metric.getClass())) {
				if (ClassUtils.isAssignable(Number.class, descriptor.getPropertyType())) {
					result.add(descriptor.getName());
				}
			}
			numberKeys.put(metric.getClass(), result);
		}
		return result;
	}

	private static Number getMetric(Object metric, String metricName) {
		String key = StringUtils.getFilenameExtension(metricName);
		return (Number) new BeanWrapperImpl(metric).getPropertyValue(key);
	}

}

##PublicMetricsAutoConfiguration ~/.m2/repository/org/springframework/boot/spring-boot-actuator/1.4.3.RELEASE/spring-boot-actuator-1.4.3.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java

@Configuration
@AutoConfigureBefore(EndpointAutoConfiguration.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, CacheAutoConfiguration.class,
		MetricRepositoryAutoConfiguration.class, CacheStatisticsAutoConfiguration.class,
		IntegrationAutoConfiguration.class })
public class PublicMetricsAutoConfiguration {

	private final List<MetricReader> metricReaders;

	public PublicMetricsAutoConfiguration(
			@ExportMetricReader ObjectProvider<List<MetricReader>> metricReadersProvider) {
		this.metricReaders = metricReadersProvider.getIfAvailable();
	}

	@Bean
	public SystemPublicMetrics systemPublicMetrics() {
		return new SystemPublicMetrics();
	}

	@Bean
	public MetricReaderPublicMetrics metricReaderPublicMetrics() {
		return new MetricReaderPublicMetrics(
				new CompositeMetricReader(this.metricReaders == null ? new MetricReader[0]
						: this.metricReaders
								.toArray(new MetricReader[this.metricReaders.size()])));
	}

	@Bean
	@ConditionalOnBean(RichGaugeReader.class)
	public RichGaugeReaderPublicMetrics richGaugePublicMetrics(
			RichGaugeReader richGaugeReader) {
		return new RichGaugeReaderPublicMetrics(richGaugeReader);
	}

	@Configuration
	@ConditionalOnClass(DataSource.class)
	@ConditionalOnBean(DataSource.class)
	static class DataSourceMetricsConfiguration {

		@Bean
		@ConditionalOnMissingBean
		@ConditionalOnBean(DataSourcePoolMetadataProvider.class)
		public DataSourcePublicMetrics dataSourcePublicMetrics() {
			return new DataSourcePublicMetrics();
		}

	}

	@Configuration
	@ConditionalOnClass({ Servlet.class, Tomcat.class })
	@ConditionalOnWebApplication
	static class TomcatMetricsConfiguration {

		@Bean
		@ConditionalOnMissingBean
		public TomcatPublicMetrics tomcatPublicMetrics() {
			return new TomcatPublicMetrics();
		}

	}

	@Configuration
	@ConditionalOnClass(CacheManager.class)
	@ConditionalOnBean(CacheManager.class)
	static class CacheStatisticsConfiguration {

		@Bean
		@ConditionalOnMissingBean
		@ConditionalOnBean(CacheStatisticsProvider.class)
		public CachePublicMetrics cachePublicMetrics() {
			return new CachePublicMetrics();
		}

	}

	@Configuration
	@ConditionalOnClass(IntegrationMBeanExporter.class)
	@ConditionalOnBean(IntegrationMBeanExporter.class)
	@ConditionalOnJava(JavaVersion.SEVEN)
	@UsesJava7
	static class IntegrationMetricsConfiguration {

		@Bean
		@ConditionalOnMissingBean(name = "springIntegrationPublicMetrics")
		public MetricReaderPublicMetrics springIntegrationPublicMetrics(
				IntegrationMBeanExporter exporter) {
			return new MetricReaderPublicMetrics(
					new SpringIntegrationMetricReader(exporter));
		}

	}

}

这里既有SystemPublicMetrics,也有MetricReaderPublicMetrics,使用了CompositeMetricReader

##MetricsEndpoint ~/.m2/repository/org/springframework/boot/spring-boot-actuator/1.4.3.RELEASE/spring-boot-actuator-1.4.3.RELEASE-sources.jar!/org/springframework/boot/actuate/endpoint/MetricsEndpoint.java

@ConfigurationProperties(prefix = "endpoints.metrics")
public class MetricsEndpoint extends AbstractEndpoint<Map<String, Object>> {

	private final List<PublicMetrics> publicMetrics;

	/**
	 * Create a new {@link MetricsEndpoint} instance.
	 * @param publicMetrics the metrics to expose
	 */
	public MetricsEndpoint(PublicMetrics publicMetrics) {
		this(Collections.singleton(publicMetrics));
	}

	/**
	 * Create a new {@link MetricsEndpoint} instance.
	 * @param publicMetrics the metrics to expose. The collection will be sorted using the
	 * {@link AnnotationAwareOrderComparator}.
	 */
	public MetricsEndpoint(Collection<PublicMetrics> publicMetrics) {
		super("metrics");
		Assert.notNull(publicMetrics, "PublicMetrics must not be null");
		this.publicMetrics = new ArrayList<PublicMetrics>(publicMetrics);
		AnnotationAwareOrderComparator.sort(this.publicMetrics);
	}

	public void registerPublicMetrics(PublicMetrics metrics) {
		this.publicMetrics.add(metrics);
		AnnotationAwareOrderComparator.sort(this.publicMetrics);
	}

	public void unregisterPublicMetrics(PublicMetrics metrics) {
		this.publicMetrics.remove(metrics);
	}

	@Override
	public Map<String, Object> invoke() {
		Map<String, Object> result = new LinkedHashMap<String, Object>();
		List<PublicMetrics> metrics = new ArrayList<PublicMetrics>(this.publicMetrics);
		for (PublicMetrics publicMetric : metrics) {
			try {
				for (Metric<?> metric : publicMetric.metrics()) {
					result.put(metric.getName(), metric.getValue());
				}
			}
			catch (Exception ex) {
				// Could not evaluate metrics
			}
		}
		return result;
	}

}

这里将public metric暴露在/metrics的endpoint上

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34346099/article/details/91663782

智能推荐

Seaborn常见绘图总结_seaborn清晰度-程序员宅基地

文章浏览阅读747次。以前粗略的学习过Matplotlib绘图、Pandas绘图(这里是pandas的常见绘图总结),但是都未深入的去学习过,一遇到问题就翻..._seaborn清晰度

Win32:三菱FX3U/FX5U的32位和64位MX插件注意事项_mx component通讯fx3u 64位-程序员宅基地

文章浏览阅读1.1k次。FX5U FX3U MX 三菱 PLC _mx component通讯fx3u 64位

2013计算机二级考试c语言试题及答案第二套,2013全国计算机等级考试新大纲二级C语言题库及参考答案...-程序员宅基地

文章浏览阅读95次。2013年全国计算机等级考试,二级C语言,新大纲,无纸化考试,题库,真题,答案参考答案 第一套题二、程序填空题本题是根据给定的公式来计算函数的值。第一处:程序中使用双精度double类型进行计算,所以函数的返回值类型也为double,所 以应填:double。第二处:当i等于1时,则返回f1函数的值,所以应填:f1。 第三处:如果i不等于1,则返回f2函数的值,所以应填:f2。 三、程序修改题 ...

毕业设计c语言课程设计,大学毕业设计论文-—c语言课程设计.doc-程序员宅基地

文章浏览阅读210次。大学毕业设计论文-—c语言课程设计课 程 设 计 报 告课程名称 C语言程序设计课题名称 通讯录管理系统专 业 汽车服务班 级 0901班学 号 200902180114姓 名 伏铄臻指导教师 王宁 陈多2010年9月12日湖南工程学院课 程 设 计 任 务 书课程名称 ..._基于c语言的毕业设计

Netty入门 -- 什么是Netty?_什么是netty?-程序员宅基地

文章浏览阅读1.6k次,点赞29次,收藏27次。通俗易懂,一文让你搞懂Netty~_什么是netty?

Android 开发 AudioRecord音频录制_android audiohal in_read 录音-程序员宅基地

文章浏览阅读190次。前言Android SDK 提供了两套音频采集的API,分别是:MediaRecorder 和 AudioRecord,前者是一个更加上层一点的API,它可以直接把手机麦克风录入的音频数据进行编码压缩(如AMR、MP3等)并存成文件,而后者则更接近底层,能够更加自由灵活地控制,可以得到原始的一帧帧PCM音频数据。实现流程获取权限初始化获取每一帧流的Size初始化音频录制AudioReco..._android audiohal in_read 录音

随便推点

vue使用qrcode2生成二维码内容不变问题_vue-qr生成的二维码会变吗-程序员宅基地

文章浏览阅读1.5k次。今天学习使用vue前端生成二维码并保存功能;发现生成内容不变;最后发现text赋值出现问题;下面直接上代码。安装插件#二维码npm install qrcodejs2代码引用<template> <div class="app-container"> <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="6..._vue-qr生成的二维码会变吗

取消jupyter notebook的密码_jupyter notebook怎么不设置密码-程序员宅基地

文章浏览阅读1.4w次,点赞9次,收藏11次。取消jupyter notebook的密码1。终端输入:jupyter notebook --generate-config 会生成一个配置文件,成功后会显示文件路径(/Users/kyousugi/.jupyter/jupyter_notebook_config.py) 2。打开路径下的jupyter_notebook_config.py配置文件,找到jupyter_notebook_c..._jupyter notebook怎么不设置密码

基于ZYNQ的开源CANopen协议栈CANFestival移植_canfestival driver api-程序员宅基地

文章浏览阅读1w次,点赞26次,收藏149次。1 概述 CanFestival是一个免费而且开源的CANopen协议栈,较为适合于对CANopen协议栈功能完备性和工作性能要求不高的应用场合。对于功能和性能要求较高的应用,也有很多第三方的商用CANopen协议栈可供购买使用。目前,CanFestival在嵌入式控制(PLC、单片机、ARM等)领域中使用较多。 本文讲解了CanFestival库的基本架构和原理,针对ZYNQ平台详细介绍了移植的原理和过程。最后通过测试实例,介绍了CanFestival中主要常用功能及相..._canfestival driver api

Android笔记之IPC机制(二)AIDL-程序员宅基地

文章浏览阅读51次。一、AIDL:Android Interface Definition Language,即Android接口定义语言。Android系统中的进程之间不能[共享内存]因此,需要提供一些机制在不同进程之间进行数据通信。二、AIDL的创建:1、服务端服务端首先要创建一个Service用来监听客户端的连接请求,然后创建一个AIDL文件,将暴露给客户端的接口在这个AIDL文件中声明,最后在Ser...

C#中对DatagridView的部分常用操作_"this.datagridview1.columns[\"宽\"].displayindex"-程序员宅基地

文章浏览阅读770次,点赞2次,收藏10次。  C#DataGridView中的常用技巧  只列出技巧部分,后面会有补充  (最基本的技巧). 获取某列中的某行(某单元格)中的内容 this.currentposition = this.dataGridView1.BindingContext [this.dataGridView1.DataSource, this.dataGridView1.Da_"this.datagridview1.columns[\"宽\"].displayindex"

Building The LinkedIn Knowledge Graph-程序员宅基地

文章浏览阅读467次。https://engineering.linkedin.com/blog/2016/10/building-the-linkedin-knowledge-graphAuthors: Qi He, Bee-Chung Chen, Deepak AgarwalA shorter version of this post first appeared on ..._building the linkedin knowledge graph

推荐文章

热门文章

相关标签