File: histogram.rb

package info (click to toggle)
ruby-prometheus-client-mmap 1.2.9-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 700 kB
  • sloc: ruby: 3,149; sh: 54; makefile: 21
file content (80 lines) | stat: -rw-r--r-- 2,480 bytes parent folder | download | duplicates (4)
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
require 'prometheus/client/metric'
require 'prometheus/client/uses_value_type'

module Prometheus
  module Client
    # A histogram samples observations (usually things like request durations
    # or response sizes) and counts them in configurable buckets. It also
    # provides a sum of all observed values.
    class Histogram < Metric
      # Value represents the state of a Histogram at a given point.
      class Value < Hash
        include UsesValueType
        attr_accessor :sum, :total, :total_inf

        def initialize(type, name, labels, buckets)
          @sum = value_object(type, name, "#{name}_sum", labels)
          @total = value_object(type, name, "#{name}_count", labels)
          @total_inf = value_object(type, name, "#{name}_bucket", labels.merge(le: "+Inf"))

          buckets.each do |bucket|
            self[bucket] = value_object(type, name, "#{name}_bucket", labels.merge(le: bucket.to_s))
          end
        end

        def observe(value)
          @sum.increment(value)
          @total.increment()
          @total_inf.increment()

          each_key do |bucket|
            self[bucket].increment() if value <= bucket
          end
        end

        def get()
          hash = {}
          each_key do |bucket|
            hash[bucket] = self[bucket].get()
          end
          hash
        end
      end

      # DEFAULT_BUCKETS are the default Histogram buckets. The default buckets
      # are tailored to broadly measure the response time (in seconds) of a
      # network service. (From DefBuckets client_golang)
      DEFAULT_BUCKETS = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1,
                         2.5, 5, 10].freeze

      # Offer a way to manually specify buckets
      def initialize(name, docstring, base_labels = {},
                     buckets = DEFAULT_BUCKETS)
        raise ArgumentError, 'Unsorted buckets, typo?' unless sorted? buckets

        @buckets = buckets
        super(name, docstring, base_labels)
      end

      def type
        :histogram
      end

      def observe(labels, value)
        label_set = label_set_for(labels)
        synchronize { @values[label_set].observe(value) }
      end

      private

      def default(labels)
        # TODO: default function needs to know key of hash info (label names and values)
        Value.new(type, @name, labels, @buckets)
      end

      def sorted?(bucket)
        bucket.each_cons(2).all? { |i, j| i <= j }
      end
    end
  end
end