BigW Consortium Gitlab

metric.rb 1.92 KB
Newer Older
1 2 3 4
module Gitlab
  module Metrics
    # Class for storing details of a single metric (label, value, etc).
    class Metric
5 6
      JITTER_RANGE = 0.000001..0.001

7
      attr_reader :series, :values, :tags, :type
8 9 10 11

      # series - The name of the series (as a String) to store the metric in.
      # values - A Hash containing the values to store.
      # tags   - A Hash containing extra tags to add to the metrics.
12
      def initialize(series, values, tags = {}, type = :metric)
13 14 15
        @values = values
        @series = series
        @tags   = tags
16 17 18 19 20
        @type   = type
      end

      def event?
        type == :event
21 22 23 24
      end

      # Returns a Hash in a format that can be directly written to InfluxDB.
      def to_hash
25 26 27 28 29 30 31 32 33
        # InfluxDB overwrites an existing point if a new point has the same
        # series, tag set, and timestamp. In a highly concurrent environment
        # this means that using the number of seconds since the Unix epoch is
        # inevitably going to collide with another timestamp. For example, two
        # Rails requests processed by different processes may end up generating
        # metrics using the _exact_ same timestamp (in seconds).
        #
        # Due to the way InfluxDB is set up there's no solution to this problem,
        # all we can do is lower the amount of collisions. We do this by using
34 35 36 37
        # System.real_time which returns the nanoseconds as a Float providing
        # greater accuracy. We then add a small random value that is large
        # enough to distinguish most timestamps but small enough to not alter
        # the timestamp significantly.
38 39 40
        #
        # See https://gitlab.com/gitlab-com/operations/issues/175 for more
        # information.
41
        time = System.real_time(:nanosecond) + rand(JITTER_RANGE)
42

43
        {
44 45
          series:    @series,
          tags:      @tags,
46
          values:    @values,
47
          timestamp: time.to_i
48 49 50 51 52
        }
      end
    end
  end
end