Class: Metrics::Instruments::Histogram

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-metrics/instruments/histogram.rb

Direct Known Subclasses

ExponentialHistogram, UniformHistogram

Instance Method Summary collapse

Constructor Details

#initialize(type = :uniform) ⇒ Histogram

Returns a new instance of Histogram.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/ruby-metrics/instruments/histogram.rb', line 8

def initialize(type = :uniform)
  @count = 0
  case type
  when :uniform
    @sample = Metrics::Statistics::UniformSample.new
  when :exponential
    @sample = Metrics::Statistics::ExponentialSample.new
  end
  @min = nil
  @max = nil
  @sum = 0
  @variance_s = 0
  @variance_m = -1
end

Instance Method Details

#as_json(*_) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/ruby-metrics/instruments/histogram.rb', line 159

def as_json(*_)
  percentiles = self.quantiles([0.5, 0.75, 0.95, 0.98, 0.99, 0.999])
  {
    :type => 'histogram',
    :min => self.min,
    :max => self.max,
    :mean => self.mean,
    :median => percentiles[0.5],
    :std_dev => self.std_dev,
    :p75 => percentiles[0.75],
    :p95 => percentiles[0.95],
    :p98 => percentiles[0.98],
    :p99 => percentiles[0.99],
    :p999 => percentiles[0.999],
  }
end

#clearObject



32
33
34
35
36
37
38
39
40
# File 'lib/ruby-metrics/instruments/histogram.rb', line 32

def clear
  @sample.clear
  @min = nil
  @max = nil
  @sum = 0
  @count = 0
  @variance_m = -1
  @variance_s = 0
end

#countObject



105
106
107
108
# File 'lib/ruby-metrics/instruments/histogram.rb', line 105

def count
  count = @count
  return count
end

#maxObject



111
112
113
114
115
116
117
118
# File 'lib/ruby-metrics/instruments/histogram.rb', line 111

def max
  max = @max
  if max != nil
    return max
  else
    return 0.0
  end
end

#meanObject



129
130
131
132
133
134
135
136
137
138
# File 'lib/ruby-metrics/instruments/histogram.rb', line 129

def mean
  count = @count
  sum = @sum

  if count > 0
    return sum / count
  else
    return 0.0
  end
end

#minObject



120
121
122
123
124
125
126
127
# File 'lib/ruby-metrics/instruments/histogram.rb', line 120

def min
  min = @min
  if min != nil
    return min
  else
    return 0.0
  end
end

#quantiles(percentiles) ⇒ Object



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
# File 'lib/ruby-metrics/instruments/histogram.rb', line 42

def quantiles(percentiles)
  # Calculated using the same logic as R and Excel use
  # as outlined by the NIST here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc252.htm
  count = @count
  scores = {}
  values = @sample.values[0..count-1]

  percentiles.each do |pct|
    scores[pct] = 0.0
  end

  if count > 0
    values.sort!
    percentiles.each do |pct|
      idx = pct * (values.length - 1) + 1.0
      if idx <= 1
        scores[pct] = values[0]
      elsif idx >= values.length
        scores[pct] = values[values.length-1]
      else
        lower = values[idx.to_i - 1]
        upper = values[idx.to_i]
        scores[pct] = lower + (idx - idx.floor) * (upper - lower)
      end
    end
  end

  return scores
end

#std_devObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/ruby-metrics/instruments/histogram.rb', line 140

def std_dev
  count = @count
  variance = self.variance()

  if count > 0
    if variance < 0
      # TODO: FIX THIS, THIS SHOULD NEVER EVER HAPPEN
      return 0
    end
    return Math.sqrt(variance)
  else
    return 0.0
  end
end

#to_json(*_) ⇒ Object



176
177
178
# File 'lib/ruby-metrics/instruments/histogram.rb', line 176

def to_json(*_)
  as_json.to_json
end

#update(value) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/ruby-metrics/instruments/histogram.rb', line 23

def update(value)
	@count += 1
	@sum += value
	@sample.update(value)
	update_max(value)
	update_min(value)
  update_variance(value);
end

#update_max(value) ⇒ Object



78
79
80
81
82
# File 'lib/ruby-metrics/instruments/histogram.rb', line 78

def update_max(value)
  if (@max == nil || value > @max)
    @max = value
  end
end

#update_min(value) ⇒ Object



72
73
74
75
76
# File 'lib/ruby-metrics/instruments/histogram.rb', line 72

def update_min(value)
  if (@min == nil || value < @min)
    @min = value
  end
end

#update_variance(value) ⇒ Object



84
85
86
87
88
89
90
91
92
# File 'lib/ruby-metrics/instruments/histogram.rb', line 84

def update_variance(value)
  count = @count
  old_m = @variance_m
  new_m = @variance_m + ((value - old_m) / count)
  new_s = @variance_s + ((value - old_m) * (value - new_m))

  @variance_m = new_m
  @variance_s = new_s
end

#valuesObject



155
156
157
# File 'lib/ruby-metrics/instruments/histogram.rb', line 155

def values
  @sample.values
end

#varianceObject



94
95
96
97
98
99
100
101
102
103
# File 'lib/ruby-metrics/instruments/histogram.rb', line 94

def variance
  count = @count
  variance_s = @variance_s

  if count <= 1
    return 0.0
  else
    return variance_s.to_f / (count - 1).to_i
  end
end