前言
本文我们介绍的是RichGaugeReader,RichGaugeRepository相关的实现.其类图如下:
解析
RichGauge
RichGauge–>存储最大值,最小值,平均值的对象.平均值的计算取决于权重(alpha)的设置.如果没有设置,其平均值就是1个算术平均数.如果该值给定了,就会按照NIST的文档计算指数平均数指标
指数平均数指标=EMA(today)=α * Price(today) + ( 1 - α ) * EMA(yesterday)
相关链接如下:
该类的字段如下:
// 统计指标的后缀 public static final String COUNT = ".count"; // 最大值的后缀 public static final String MAX = ".max"; // 最小值的后缀 public static final String MIN = ".min"; // 平均值的后缀 public static final String AVG = ".avg"; // alpha 的后缀 public static final String ALPHA = ".alpha"; // 指标值的后缀 public static final String VAL = ".val"; // 指标名称 private final String name; // 值 private double value; // 如果alpha设置了.则是1个算术平均数,否则是指数平均数指标 private double average; // 最大值 private double max; // 最小值 private double min; // 次数统计 private long count; // 权重因子 private double alpha;
构造器如下:
public RichGauge(String name) { this(name, 0.0); this.count = 0; } public RichGauge(String name, double value) { Assert.notNull(name, "The gauge name cannot be null or empty"); this.name = name; this.value = value; this.average = this.value; this.min = this.value; this.max = this.value; this.alpha = -1.0; this.count = 1; } public RichGauge(String name, double value, double alpha, double mean, double max, double min, long count) { this.name = name; this.value = value; this.alpha = alpha; this.average = mean; this.max = max; this.min = min; this.count = count; }
其声明了2个主要的方法:
set,代码如下:
RichGauge set(double value) { // 1. 如果count等于0,相等于是第一次访问,则设置最大值,最小值为给定的值 if (this.count == 0) { this.max = value; this.min = value; } // 2. 如果value比当前的最大值大,则进行替换 else if (value > this.max) { this.max = value; } // 3. 如果value比当前的最大值小,则进行替换 else if (value < this.min) { this.min = value; } // 4. 如果alpha指定了并且count大于0,则计算指数平均数指标,否则计算算数平均数 if (this.alpha > 0.0 && this.count > 0) { this.average = this.alpha * this.value + (1 - this.alpha) * this.average; } else { double sum = this.average * this.count; sum += value; this.average = sum / (this.count + 1); } // 5. 累加计数器,并修改value值为给定的 this.count++; this.value = value; return this; }
reset–>重置,代码如下:
RichGauge reset() { this.value = 0.0; this.max = 0.0; this.min = 0.0; this.average = 0.0; this.count = 0; return this; }
RichGaugeReader
RichGaugeReader–> 1个基本的对于RichGauge的读 操作的集合.声明的方法如下:
// 通过名字查找
RichGauge findOne(String name);
// 获取所有
Iterable<RichGauge> findAll();
// 返回数量
long count();
MultiMetricRichGaugeReader
MultiMetricRichGaugeReader–>个从MultiMetricRepository(分组名字是RichGauge 中的名字)中读取metric 数据的实现.其格式和RichGaugeExporter 一样,因此,该类可以用在被RichGaugeExporter已经填充过数据的地方.该类不是默认装配的
字段,构造器如下:
private final MultiMetricRepository repository; public MultiMetricRichGaugeReader(MultiMetricRepository repository) { this.repository = repository; }
方法实现如下:
findOne –>根据给定的名字获得给定的RichGauge.代码如下:
public RichGauge findOne(String name) { // 1. 从MultiMetricRepository获得所有以指定名称开头的Metric Iterable<Metric<?>> metrics = this.repository.findAll(name); double value = 0; double average = 0.; double alpha = -1.; double min = 0.; double max = 0.; long count = 0; // 2. 依次遍历之 for (Metric<?> metric : metrics) { // 2.1 如果是.val结尾的,则将其值赋值给value if (metric.getName().endsWith(RichGauge.VAL)) { value = metric.getValue().doubleValue(); } // 2.2 如果是.alpha结尾的,则将其值赋值给alpha else if (metric.getName().endsWith(RichGauge.ALPHA)) { alpha = metric.getValue().doubleValue(); } // 2.3 如果是.avg结尾的,则将其值赋值给average else if (metric.getName().endsWith(RichGauge.AVG)) { average = metric.getValue().doubleValue(); } // 2.4 如果是.min结尾的,则将其值赋值给min else if (metric.getName().endsWith(RichGauge.MIN)) { min = metric.getValue().doubleValue(); } // 2.5 如果是.max结尾的,则将其值赋值给max else if (metric.getName().endsWith(RichGauge.MAX)) { max = metric.getValue().doubleValue(); } // 2.6 如果是.count结尾的,则将其值赋值给count else if (metric.getName().endsWith(RichGauge.COUNT)) { count = metric.getValue().longValue(); } } // 3. 实例化RichGauge return new RichGauge(name, value, alpha, average, max, min, count); }
findAll–> 获得所有的RichGauge,代码如下:
public Iterable<RichGauge> findAll() { List<RichGauge> result = new ArrayList<RichGauge>(); // 1. 遍历MultiMetricRepository中的group for (String name : this.repository.groups()) { // 2. 依次调用findOne方法获得对应的RichGauge,加入到结果集中 result.add(findOne(name)); } return result; }
count–> 调用MultiMetricRepository#countGroups –> 获得group的大小.代码如下:
public long count() { return this.repository.countGroups(); }
RichGaugeRepository
RichGaugeRepository–>合并了RichGaugeReader,MetricWriter 接口.代码如下:
public interface RichGaugeRepository extends RichGaugeReader, MetricWriter {
}
InMemoryRichGaugeRepository
InMemoryRichGaugeRepository–> 使用SimpleInMemoryRepository来实现MetricWriter和RichGaugeReader.其内部持有着1个SimpleInMemoryRepository,泛型为RichGauge.
方法实现如下:
increment:
public void increment(final Delta<?> delta) { this.repository.update(delta.getName(), new Callback<RichGauge>() { @Override public RichGauge modify(RichGauge current) { double value = ((Number) delta.getValue()).doubleValue(); if (current == null) { return new RichGauge(delta.getName(), value); } current.set(current.getValue() + value); return current; } }); }
- 从metrics中获得Delta所对应的RichGauge
- 如果Metric存在的话,则在原先的基础上加上传入的Delta的值
- 如果不存在,则直接根据传入Delta的名称,值实例化1个RichGauge,加入到repository的values中
set–> 代码如下:
public void set(Metric<?> metric) { final String name = metric.getName(); final double value = metric.getValue().doubleValue(); this.repository.update(name, new Callback<RichGauge>() { @Override public RichGauge modify(RichGauge current) { if (current == null) { return new RichGauge(name, value); } current.set(value); return current; } }); }
- 从metrics中获得Metric所对应的RichGauge
- 如果Metric存在的话,则修改其值为传入的Metric
- 如果不存在,则直接根据传入Metric的名称,值实例化1个RichGauge,加入到repository的values中
其他方法比较简单,罗列如下:
public void reset(String metricName) { this.repository.remove(metricName); } @Override public RichGauge findOne(String metricName) { return this.repository.findOne(metricName); } @Override public Iterable<RichGauge> findAll() { return this.repository.findAll(); } @Override public long count() { return this.repository.count(); }