源码分析一Collector
- 负责功能定义[采集指标]以及注册
public abstract class Collector {
public abstract List<MetricFamilySamples> collect();
/**
* Register the Collector with the default registry.
*/
public <T extends Collector> T register() {
return register(CollectorRegistry.defaultRegistry);
}
}
collector类型
- 常见为COUNTER,GAUGE,HISTOGRAM,SUMMARY
public enum Type {
UNKNOWN, // This is untyped in Prometheus text format.
COUNTER,
GAUGE,
STATE_SET,
INFO,
HISTOGRAM,
GAUGE_HISTOGRAM,
SUMMARY,
}
采样簇MetricFamilySamples
- MetricFamilySamples包含一个指标的所有度量信息,如下所示
static public class MetricFamilySamples {
public final String name;
public final String unit;
public final Type type;
public final String help;
public final List<Sample> samples;
// 一个指标除了定义的name 还包括一些内置name
public String[] getNames() {
switch (type) {
case COUNTER:
return new String[]{
name + "_total",
name + "_created",
name
};
case SUMMARY:
return new String[]{
name + "_count",
name + "_sum",
name + "_created",
name
};
case HISTOGRAM:
return new String[]{
name + "_count",
name + "_sum",
name + "_bucket",
name + "_created",
name
};
case GAUGE_HISTOGRAM:
return new String[]{
name + "_gcount",
name + "_gsum",
name + "_bucket",
name
};
case INFO:
return new String[]{
name + "_info",
name
};
default:
return new String[]{name};
}
}
}
采样点Sample
- 一个sample代表如下所示信息
jvm_memory_used_bytes{application=“appcenter”,area=“nonheap”,id=“CodeHeap ‘non-profiled nmethods’”,} 2.1102592E7
public static class Sample {
public final String name;
public final List<String> labelNames;
public final List<String> labelValues;
public final double value;
// 样本示例点
public final Exemplar exemplar;
public final Long timestampMs;
public Sample(String name, List<String> labelNames, List<String> labelValues, double value, Exemplar exemplar, Long timestampMs) {
this.name = name;
this.labelNames = labelNames;
this.labelValues = labelValues;
this.value = value;
this.exemplar = exemplar;
this.timestampMs = timestampMs;
}
源码分析一SimpleCollector
- 对度量进一步明确
- 这段代码说明指标的名称,帮助,类型
- 以及labelNames
- metrics由指标名称以及label kv键值对构成
- 每一个label_values数组构成一个child对象,内含所有的指标度量信息
public abstract class SimpleCollector<Child> extends Collector {
protected final String fullname;
protected final String help;
protected final String unit;
protected final List<String> labelNames;
protected final ConcurrentMap<List<String>, Child> children = new ConcurrentHashMap<List<String>, Child>();
protected Child noLabelsChild;
/**
* labels表示label键值对的key,labelValues 表示键值对的values
* labelValues一组对应一个Child,child内部包含指标信息
*/
public Child labels(String... labelValues) {
if (labelValues.length != labelNames.size()) {
throw new IllegalArgumentException("Incorrect number of labels.");
}
for (String label: labelValues) {
if (label == null) {
throw new IllegalArgumentException("Label cannot be null.");
}
}
List<String> key = Arrays.asList(labelValues);
Child c = children.get(key);
if (c != null) {
return c;
}
Child c2 = newChild();
Child tmp = children.putIfAbsent(key, c2);
return tmp == null ? c2 : tmp;
}
protected abstract Child newChild();
public abstract static class Builder<B extends Builder<B, C>, C extends SimpleCollector> {
String namespace = "";
String subsystem = "";
String name = "";
String fullname = "";
String unit = "";
String help = "";
String[] labelNames = new String[]{};
// Some metrics require additional setup before the initialization can be done.
boolean dontInitializeNoLabelsChild;
public abstract C create();
public C register() {
return register(CollectorRegistry.defaultRegistry);
}
public C register(CollectorRegistry registry) {
C sc = create();
registry.register(sc);
return sc;
}
}
}
源码分析一Counter
- child内含指标信息
- collect方法根据Child构建MetricFamilySamples可观测指标信息
- incr设置Counter的指标值
- 包含incr和含有打点样本的exemplar
exemplar的标签可以不同于Counter已定的标签以及长度
counter_total{label1=“val1”} 888.0 # {exemplar_key=“exemplar_val1”,exemplar_key2=“exemplar_val2”} 222.0 1663441608.646
public class Counter extends SimpleCollector<Counter.Child> implements Collector.Describable {
private final Boolean exemplarsEnabled;
private final CounterExemplarSampler exemplarSampler;
public static class Child {
private final DoubleAdder value = new DoubleAdder();
private final long created = System.currentTimeMillis();
private final Boolean exemplarsEnabled;
private final CounterExemplarSampler exemplarSampler;
private final AtomicReference<Exemplar> exemplar = new AtomicReference<Exemplar>();
public void inc() {
inc(1);
}
public void incWithExemplar(String... exemplarLabels) {
incWithExemplar(1, exemplarLabels);
}
public void incWithExemplar(Map<String, String> exemplarLabels) {
incWithExemplar(1, exemplarLabels);
}
public void inc() {
inc(1);
}
public void incWithExemplar(Map<String, String> exemplarLabels) {
incWithExemplar(1, exemplarLabels);
}
public void inc(double amt) {
noLabelsChild.inc(amt);
}
@Override
public List<MetricFamilySamples> collect() {
/* 一般Counter的list size为1 表示 metric的全部数据*/
List<MetricFamilySamples.Sample> samples = new ArrayList<MetricFamilySamples.Sample>(children.size());
for(Map.Entry<List<String>, Child> c: children.entrySet()) {
samples.add(new MetricFamilySamples.Sample(fullname + "_total", labelNames, c.getKey(), c.getValue().get(), c.getValue().getExemplar()));
if (Environment.includeCreatedSeries()) {
samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), c.getValue().created() / 1000.0));
}
}
return familySamplesList(Type.COUNTER, samples);
}
@Override
public List<MetricFamilySamples> describe() {
return Collections.<MetricFamilySamples>singletonList(new CounterMetricFamily(fullname, help, labelNames));
}
}
总结
- 概述Collector体系以及Counter实现,Gauge等其他收集器原理相同
- counter 通过incr生成数据存储与Counter.Child中
- counter注册后.外部prometheus会定时拉取counter.collect方法的数据,存储到prometheus的tsdb中