From 0ea6e4fe64152a21546e3d586aac9f741e2f2ef9 Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Fri, 3 Feb 2017 12:12:29 +0100 Subject: [PATCH] WIP exchangeable value types --- example.rb | 30 +++++++++++++++++++++++++++ lib/prometheus/client/counter.rb | 7 ++++--- lib/prometheus/client/formats/text.rb | 16 +++++++------- lib/prometheus/client/gauge.rb | 2 +- lib/prometheus/client/histogram.rb | 20 ++++++++++-------- lib/prometheus/client/metric.rb | 8 +++---- lib/prometheus/client/summary.rb | 8 +++---- lib/prometheus/client/valuetype.rb | 25 ++++++++++++++++++++++ 8 files changed, 87 insertions(+), 29 deletions(-) create mode 100644 example.rb create mode 100644 lib/prometheus/client/valuetype.rb diff --git a/example.rb b/example.rb new file mode 100644 index 00000000..af7bf66c --- /dev/null +++ b/example.rb @@ -0,0 +1,30 @@ +$LOAD_PATH.unshift("./lib") + +require 'prometheus/client' +require 'prometheus/client/formats/text.rb' + +prometheus = Prometheus::Client.registry + +counter = Prometheus::Client::Counter.new(:counter, 'Example counter') +gauge = Prometheus::Client::Gauge.new(:gauge, 'Example gauge') +histogram = Prometheus::Client::Histogram.new(:histogram, 'Example histogram', {}, [0, 1, 2]) +summary = Prometheus::Client::Histogram.new(:summary, 'Example summary', {}) +prometheus.register(counter) +prometheus.register(gauge) +prometheus.register(histogram) +prometheus.register(summary) + +counter.increment({'foo': 'bar'}, 2) +counter.increment({'foo': 'biz'}, 4) +gauge.set({'foo': 'bar'}, 3) +gauge.set({'foo': 'biz'}, 3) +histogram.observe({'foo': 'bar'}, 0.5) +histogram.observe({'foo': 'biz'}, 0.5) +histogram.observe({'foo': 'bar'}, 1.5) +histogram.observe({'foo': 'biz'}, 2) +summary.observe({'foo': 'bar'}, 0.5) +summary.observe({'foo': 'biz'}, 0.5) +summary.observe({'foo': 'bar'}, 1.5) +summary.observe({'foo': 'biz'}, 2) + +puts Prometheus::Client::Formats::Text.marshal(prometheus) diff --git a/lib/prometheus/client/counter.rb b/lib/prometheus/client/counter.rb index 9228b6ea..cff354b5 100644 --- a/lib/prometheus/client/counter.rb +++ b/lib/prometheus/client/counter.rb @@ -1,6 +1,7 @@ # encoding: UTF-8 require 'prometheus/client/metric' +require 'prometheus/client/valuetype' module Prometheus module Client @@ -14,13 +15,13 @@ def increment(labels = {}, by = 1) raise ArgumentError, 'increment must be a non-negative number' if by < 0 label_set = label_set_for(labels) - synchronize { @values[label_set] += by } + synchronize { @values[label_set].increment(by) } end private - def default - 0 + def default(labels) + Prometheus::Client::ValueType.new(type, @name, @name, labels) end end end diff --git a/lib/prometheus/client/formats/text.rb b/lib/prometheus/client/formats/text.rb index 47510026..f86c3efd 100644 --- a/lib/prometheus/client/formats/text.rb +++ b/lib/prometheus/client/formats/text.rb @@ -47,29 +47,29 @@ def representation(metric, label_set, value, &block) elsif metric.type == :histogram histogram(metric.name, set, value, &block) else - yield metric(metric.name, labels(set), value) + yield metric(metric.name, labels(set), value.get) end end def summary(name, set, value) value.each do |q, v| - yield metric(name, labels(set.merge(quantile: q)), v) + yield metric(name, labels(set.merge(quantile: q)), v.get) end l = labels(set) - yield metric("#{name}_sum", l, value.sum) - yield metric("#{name}_count", l, value.total) + yield metric("#{name}_sum", l, value.sum.get) + yield metric("#{name}_count", l, value.total.get) end def histogram(name, set, value) value.each do |q, v| - yield metric(name, labels(set.merge(le: q)), v) + yield metric(name, labels(set.merge(le: q)), v.get) end - yield metric(name, labels(set.merge(le: '+Inf')), value.total) + yield metric(name, labels(set.merge(le: '+Inf')), value.total.get) l = labels(set) - yield metric("#{name}_sum", l, value.sum) - yield metric("#{name}_count", l, value.total) + yield metric("#{name}_sum", l, value.sum.get) + yield metric("#{name}_count", l, value.total.get) end def metric(name, labels, value) diff --git a/lib/prometheus/client/gauge.rb b/lib/prometheus/client/gauge.rb index f7990427..00a56247 100644 --- a/lib/prometheus/client/gauge.rb +++ b/lib/prometheus/client/gauge.rb @@ -13,7 +13,7 @@ def type # Sets the value for the given label set def set(labels, value) - @values[label_set_for(labels)] = value + @values[label_set_for(labels)].set(value) end end end diff --git a/lib/prometheus/client/histogram.rb b/lib/prometheus/client/histogram.rb index 18103239..0ccd3429 100644 --- a/lib/prometheus/client/histogram.rb +++ b/lib/prometheus/client/histogram.rb @@ -12,21 +12,22 @@ class Histogram < Metric class Value < Hash attr_accessor :sum, :total - def initialize(buckets) - @sum = 0.0 - @total = 0 + def initialize(type, name, labels, buckets) + @sum = ValueType.new(type, name, name.to_s + '_sum', labels) + # TODO: get rid of total and use +Inf bucket instead. + @total = ValueType.new(type, name, name.to_s + '_count', labels) buckets.each do |bucket| - self[bucket] = 0 + self[bucket] = ValueType.new(type, name, name.to_s + '_count', labels) end end def observe(value) - @sum += value - @total += 1 + @sum.increment(value) + @total.increment() each_key do |bucket| - self[bucket] += 1 if value <= bucket + self[bucket].increment() if value <= bucket end end end @@ -61,8 +62,9 @@ def observe(labels, value) private - def default - Value.new(@buckets) + 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) diff --git a/lib/prometheus/client/metric.rb b/lib/prometheus/client/metric.rb index e2dd91e6..69cc9c43 100644 --- a/lib/prometheus/client/metric.rb +++ b/lib/prometheus/client/metric.rb @@ -12,7 +12,7 @@ class Metric def initialize(name, docstring, base_labels = {}) @mutex = Mutex.new @validator = LabelSetValidator.new - @values = Hash.new { |hash, key| hash[key] = default } + @values = Hash.new { |hash, key| hash[key] = default(key) } validate_name(name) validate_docstring(docstring) @@ -27,7 +27,7 @@ def initialize(name, docstring, base_labels = {}) def get(labels = {}) @validator.valid?(labels) - @values[labels] + @values[labels].get end # Returns all label sets with their values @@ -41,8 +41,8 @@ def values private - def default - nil + def default(labels) + ValueType.new(@name, @name, labels, nil) end def validate_name(name) diff --git a/lib/prometheus/client/summary.rb b/lib/prometheus/client/summary.rb index 7b78610e..fb974910 100644 --- a/lib/prometheus/client/summary.rb +++ b/lib/prometheus/client/summary.rb @@ -14,12 +14,12 @@ class Summary < Metric class Value < Hash attr_accessor :sum, :total - def initialize(estimator) - @sum = estimator.sum - @total = estimator.observations + def initialize(name, labels, estimator) + @sum = ValueType.new(name, name + '_sum', labels, estimator.sum) + @total = ValueType.new(name, name + '_count', labels, estimator.observations) estimator.invariants.each do |invariant| - self[invariant.quantile] = estimator.query(invariant.quantile) + self[invariant.quantile] = ValueType.new(name, labels, estimator.query(invariant.quantile), nil) end end end diff --git a/lib/prometheus/client/valuetype.rb b/lib/prometheus/client/valuetype.rb new file mode 100644 index 00000000..711c351d --- /dev/null +++ b/lib/prometheus/client/valuetype.rb @@ -0,0 +1,25 @@ +# encoding: UTF-8 + +module Prometheus + module Client + class SimpleValue + def initialize(type, metric_name, name, labels, value = 0) + @value = value + end + + def set(value) + @value = value + end + + def increment(by = 1) + @value += by + end + + def get() + @value + end + end + + ValueType = SimpleValue + end +end