• Prometheus系列第七篇一核心一ClientLib源码分析-Collector系列


    源码分析一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);
      }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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,
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    采样簇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};
          }
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    采样点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;
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    源码分析一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;
        }
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    源码分析一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));
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    总结

    • 概述Collector体系以及Counter实现,Gauge等其他收集器原理相同
    • counter 通过incr生成数据存储与Counter.Child中
    • counter注册后.外部prometheus会定时拉取counter.collect方法的数据,存储到prometheus的tsdb中
  • 相关阅读:
    数据结构——栈
    代码(Python、Java)实现分组求和
    AI Scaling的神话
    1.7.3、计算机网络体系结构分层思想举例
    等参单元与数值积分
    【代码源每日一题】饿饿 饭饭「二分答案」
    IDEA一键启动多个微服务
    单字段纵向分栏
    单例模式坑这么多,不会用别乱用
    MYSQL 敏感数据加密后进行模糊查询
  • 原文地址:https://blog.csdn.net/qq_35529969/article/details/126913361