custom-prometheus-client 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 59513bdd6f293705f4f34c864ba6406d0fa9522d
4
+ data.tar.gz: a5f20ee8c59ff151cec16de150afff6924669fc9
5
+ SHA512:
6
+ metadata.gz: c2f628acc7b16dbfe82db00b854705a8a20d53660d6e03e295afe5373284656b404852234ab209b40e895bcecfcc2534bf6f29609767026d77d32a8f7c8f97d7
7
+ data.tar.gz: da87469693d2646d160927edb6a928530a1f57cfb7bb4f5aafb79bdf4058dc162f450b7f15738a3558dfbd982e8ae12d81b83deba3400d8cdaafc0a55e2396b4
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # Custom Prometheus Ruby Client
2
+
3
+ This repo is essentially a fork of https://github.com/prometheus/client_ruby and adds the following behaviour to the captured metrics.
4
+
5
+ - It takes the service_name as an options to the rake middleware (see usage)
6
+ - It adds the following labels to the metrics
7
+ * User Agent
8
+ * Accept
9
+ * Content Type
10
+
11
+ ## Usage
12
+ Add the following to your Gemfile
13
+ ```
14
+ gem 'custom-prometheus-client'
15
+ ```
16
+
17
+ Then in your config.ru add the following (Change 'my_app' to the name of your app being monitored)
18
+ ```
19
+ require 'prometheus/client/rack/collector'
20
+ require 'prometheus/client/rack/exporter'
21
+
22
+ options = { service_name: 'my_app'}
23
+ use Prometheus::Client::Rack::Collector, options
24
+ use Prometheus::Client::Rack::Exporter
25
+ ```
26
+
27
+ Configure your prometheus.yml to scrape /metrics from rails service
data/lib/prometheus.rb ADDED
@@ -0,0 +1,5 @@
1
+ # encoding: UTF-8
2
+
3
+ # Prometheus is a generic time-series collection and computation server.
4
+ module Prometheus
5
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'prometheus/client/registry'
4
+
5
+ module Prometheus
6
+ # Client is a ruby implementation for a Prometheus compatible client.
7
+ module Client
8
+ # Returns a default registry object
9
+ def self.registry
10
+ @registry ||= Registry.new
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'prometheus/client/metric'
4
+
5
+ module Prometheus
6
+ module Client
7
+ # Counter is a metric that exposes merely a sum or tally of things.
8
+ class Counter < Metric
9
+ def type
10
+ :counter
11
+ end
12
+
13
+ def increment(labels = {}, by = 1)
14
+ fail ArgumentError, 'increment must be a non-negative number' if by < 0
15
+
16
+ label_set = label_set_for(labels)
17
+ synchronize { @values[label_set] += by }
18
+ end
19
+
20
+ private
21
+
22
+ def default
23
+ 0
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'json'
4
+
5
+ module Prometheus
6
+ module Client
7
+ module Formats
8
+ # JSON format is a deprecated, human-readable format to expose the state
9
+ # of a given registry.
10
+ module JSON
11
+ MEDIA_TYPE = 'application/json'
12
+ SCHEMA = 'prometheus/telemetry'
13
+ VERSION = '0.0.2'
14
+ CONTENT_TYPE = %(#{MEDIA_TYPE}; schema="#{SCHEMA}"; version=#{VERSION})
15
+
16
+ MAPPING = { summary: :histogram }
17
+
18
+ def self.marshal(registry)
19
+ registry.metrics.map do |metric|
20
+ {
21
+ baseLabels: metric.base_labels.merge(__name__: metric.name),
22
+ docstring: metric.docstring,
23
+ metric: {
24
+ type: MAPPING[metric.type] || metric.type,
25
+ value: metric.values.map { |l, v| { labels: l, value: v } },
26
+ },
27
+ }
28
+ end.to_json
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,81 @@
1
+ # encoding: UTF-8
2
+
3
+ module Prometheus
4
+ module Client
5
+ module Formats
6
+ # Text format is human readable mainly used for manual inspection.
7
+ module Text
8
+ MEDIA_TYPE = 'text/plain'
9
+ VERSION = '0.0.4'
10
+ CONTENT_TYPE = "#{MEDIA_TYPE}; version=#{VERSION}"
11
+
12
+ METRIC_LINE = '%s%s %s'
13
+ TYPE_LINE = '# TYPE %s %s'
14
+ HELP_LINE = '# HELP %s %s'
15
+
16
+ LABEL = '%s="%s"'
17
+ SEPARATOR = ','
18
+ DELIMITER = "\n"
19
+
20
+ REGEX = { doc: /[\n\\]/, label: /[\n\\"]/ }
21
+ REPLACE = { "\n" => '\n', '\\' => '\\\\', '"' => '\"' }
22
+
23
+ def self.marshal(registry)
24
+ lines = []
25
+
26
+ registry.metrics.each do |metric|
27
+ lines << format(TYPE_LINE, metric.name, metric.type)
28
+ lines << format(HELP_LINE, metric.name, escape(metric.docstring))
29
+
30
+ metric.values.each do |label_set, value|
31
+ representation(metric, label_set, value) { |l| lines << l }
32
+ end
33
+ end
34
+
35
+ # there must be a trailing delimiter
36
+ (lines << nil).join(DELIMITER)
37
+ end
38
+
39
+ private
40
+
41
+ def self.representation(metric, label_set, value, &block)
42
+ set = metric.base_labels.merge(label_set)
43
+
44
+ if metric.type == :summary
45
+ summary(metric.name, set, value, &block)
46
+ else
47
+ yield metric(metric.name, labels(set), value)
48
+ end
49
+ end
50
+
51
+ def self.summary(name, set, value)
52
+ value.each do |q, v|
53
+ yield metric(name, labels(set.merge(quantile: q)), v)
54
+ end
55
+
56
+ l = labels(set)
57
+ yield metric("#{name}_sum", l, value.sum)
58
+ yield metric("#{name}_count", l, value.total)
59
+ end
60
+
61
+ def self.metric(name, labels, value)
62
+ format(METRIC_LINE, name, labels, value)
63
+ end
64
+
65
+ def self.labels(set)
66
+ return if set.empty?
67
+
68
+ strings = set.each_with_object([]) do |(key, value), memo|
69
+ memo << format(LABEL, key, escape(value, :label))
70
+ end
71
+
72
+ "{#{strings.join(SEPARATOR)}}"
73
+ end
74
+
75
+ def self.escape(string, format = :doc)
76
+ string.to_s.gsub(REGEX[format], REPLACE)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'prometheus/client/metric'
4
+
5
+ module Prometheus
6
+ module Client
7
+ # A Gauge is a metric that exposes merely an instantaneous value or some
8
+ # snapshot thereof.
9
+ class Gauge < Metric
10
+ def type
11
+ :gauge
12
+ end
13
+
14
+ # Sets the value for the given label set
15
+ def set(labels, value)
16
+ @values[label_set_for(labels)] = value
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: UTF-8
2
+
3
+ module Prometheus
4
+ module Client
5
+ # LabelSetValidator ensures that all used label sets comply with the
6
+ # Prometheus specification.
7
+ class LabelSetValidator
8
+ # TODO: we might allow setting :instance in the future
9
+ RESERVED_LABELS = [:job, :instance]
10
+
11
+ class LabelSetError < StandardError; end
12
+ class InvalidLabelSetError < LabelSetError; end
13
+ class InvalidLabelError < LabelSetError; end
14
+ class ReservedLabelError < LabelSetError; end
15
+
16
+ def initialize
17
+ @validated = {}
18
+ end
19
+
20
+ def valid?(labels)
21
+ unless labels.respond_to?(:all?)
22
+ fail InvalidLabelSetError, "#{labels} is not a valid label set"
23
+ end
24
+
25
+ labels.all? do |key, _|
26
+ validate_symbol(key)
27
+ validate_name(key)
28
+ validate_reserved_key(key)
29
+ end
30
+ end
31
+
32
+ def validate(labels)
33
+ return labels if @validated.key?(labels.hash)
34
+
35
+ valid?(labels)
36
+
37
+ unless @validated.empty? || match?(labels, @validated.first.last)
38
+ fail InvalidLabelSetError, 'labels must have the same signature'
39
+ end
40
+
41
+ @validated[labels.hash] = labels
42
+ end
43
+
44
+ private
45
+
46
+ def match?(a, b)
47
+ a.keys.sort == b.keys.sort
48
+ end
49
+
50
+ def validate_symbol(key)
51
+ return true if key.is_a?(Symbol)
52
+
53
+ fail InvalidLabelError, "label #{key} is not a symbol"
54
+ end
55
+
56
+ def validate_name(key)
57
+ return true unless key.to_s.start_with?('__')
58
+
59
+ fail ReservedLabelError, "label #{key} must not start with __"
60
+ end
61
+
62
+ def validate_reserved_key(key)
63
+ return true unless RESERVED_LABELS.include?(key)
64
+
65
+ fail ReservedLabelError, "#{key} is reserved"
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'thread'
4
+ require 'prometheus/client/label_set_validator'
5
+
6
+ module Prometheus
7
+ module Client
8
+ # Metric
9
+ class Metric
10
+ attr_reader :name, :docstring, :base_labels
11
+
12
+ def initialize(name, docstring, base_labels = {})
13
+ @mutex = Mutex.new
14
+ @validator = LabelSetValidator.new
15
+ @values = Hash.new { |hash, key| hash[key] = default }
16
+
17
+ validate_name(name)
18
+ validate_docstring(docstring)
19
+ @validator.valid?(base_labels)
20
+
21
+ @name = name
22
+ @docstring = docstring
23
+ @base_labels = base_labels
24
+ end
25
+
26
+ # Returns the metric type
27
+ def type
28
+ fail NotImplementedError
29
+ end
30
+
31
+ # Returns the value for the given label set
32
+ def get(labels = {})
33
+ @validator.valid?(labels)
34
+
35
+ @values[labels]
36
+ end
37
+
38
+ # Returns all label sets with their values
39
+ def values
40
+ synchronize do
41
+ @values.each_with_object({}) do |(labels, value), memo|
42
+ memo[labels] = value
43
+ end
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def default
50
+ nil
51
+ end
52
+
53
+ def validate_name(name)
54
+ return true if name.is_a?(Symbol)
55
+
56
+ fail ArgumentError, 'given name must be a symbol'
57
+ end
58
+
59
+ def validate_docstring(docstring)
60
+ return true if docstring.respond_to?(:empty?) && !docstring.empty?
61
+
62
+ fail ArgumentError, 'docstring must be given'
63
+ end
64
+
65
+ def label_set_for(labels)
66
+ @validator.validate(labels)
67
+ end
68
+
69
+ def synchronize(&block)
70
+ @mutex.synchronize(&block)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ require 'prometheus/client'
7
+ require 'prometheus/client/formats/text'
8
+
9
+ module Prometheus
10
+ # Client is a ruby implementation for a Prometheus compatible client.
11
+ module Client
12
+ # Push implements a simple way to transmit a given registry to a given
13
+ # Pushgateway.
14
+ class Push
15
+ DEFAULT_GATEWAY = 'http://localhost:9091'
16
+ PATH = '/metrics/jobs/%s'
17
+ INSTANCE_PATH = '/metrics/jobs/%s/instances/%s'
18
+ HEADER = { 'Content-Type' => Formats::Text::CONTENT_TYPE }
19
+
20
+ attr_reader :job, :instance, :gateway, :path
21
+
22
+ def initialize(job, instance = nil, gateway = nil)
23
+ @job = job
24
+ @instance = instance
25
+ @gateway = gateway || DEFAULT_GATEWAY
26
+ @uri = parse(@gateway)
27
+ @path = build_path(job, instance)
28
+ @http = Net::HTTP.new(@uri.host, @uri.port)
29
+ end
30
+
31
+ def add(registry)
32
+ request('POST', registry)
33
+ end
34
+
35
+ def replace(registry)
36
+ request('PUT', registry)
37
+ end
38
+
39
+ private
40
+
41
+ def parse(url)
42
+ uri = URI.parse(url)
43
+
44
+ if uri.scheme == 'http'
45
+ uri
46
+ else
47
+ fail ArgumentError, 'only HTTP gateway URLs are supported currently.'
48
+ end
49
+ rescue URI::InvalidURIError => e
50
+ raise ArgumentError, "#{url} is not a valid URL: #{e}"
51
+ end
52
+
53
+ def build_path(job, instance)
54
+ if instance
55
+ format(INSTANCE_PATH, URI.escape(job), URI.escape(instance))
56
+ else
57
+ format(PATH, URI.escape(job))
58
+ end
59
+ end
60
+
61
+ def request(method, registry)
62
+ data = Formats::Text.marshal(registry)
63
+
64
+ @http.send_request(method, path, data, HEADER)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,92 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'prometheus/client'
4
+
5
+ module Prometheus
6
+ module Client
7
+ module Rack
8
+ # Collector is a Rack middleware that provides a sample implementation of
9
+ # a HTTP tracer. The default label builder can be modified to export a
10
+ # different set of labels per recorded metric.
11
+ class Collector
12
+ attr_reader :app, :registry
13
+
14
+ def initialize(app, options = {}, &label_builder)
15
+ @app = app
16
+ @registry = options[:registry] || Client.registry
17
+ @label_builder = label_builder || DEFAULT_LABEL_BUILDER
18
+ # The service name should be read from config or could be git repo name
19
+ @service_name = options[:service_name]
20
+ init_request_metrics
21
+ init_exception_metrics
22
+ end
23
+
24
+ def call(env) # :nodoc:
25
+ trace(env) { @app.call(env) }
26
+ end
27
+
28
+ protected
29
+
30
+ DEFAULT_LABEL_BUILDER = proc do |env|
31
+ {
32
+ method: env['REQUEST_METHOD'].downcase,
33
+ ua: env['HTTP_USER_AGENT'].to_s,
34
+ accept: env['HTTP_ACCEPT'],
35
+ host: env['HTTP_HOST'].to_s,
36
+ path: env['PATH_INFO'].to_s,
37
+ content_type: env['CONTENT_TYPE'].to_s
38
+ }
39
+ end
40
+
41
+ def init_request_metrics
42
+ @request_metrics = @service_name + "__counter_requests_total"
43
+ @response_metrics = @service_name + "__counter_responses_total"
44
+ @response_time_metrics = @service_name + "__summary_responses_duration_microseconds"
45
+
46
+ @requests = @registry.counter(
47
+ @request_metrics.to_sym,
48
+ 'Total number of HTTP requests.')
49
+ @requests_duration = @registry.counter(
50
+ @response_metrics.to_sym,
51
+ 'Total time spent answering HTTP requests ' \
52
+ '(microseconds).')
53
+ @durations = @registry.summary(
54
+ @response_time_metrics.to_sym,
55
+ 'A histogram of the response latency (microseconds).')
56
+ end
57
+
58
+ def init_exception_metrics
59
+ @exceptions = @registry.counter(
60
+ :http_exceptions_total,
61
+ 'A counter of the total number of exceptions raised.')
62
+ end
63
+
64
+ def trace(env)
65
+ start = Time.now
66
+ yield.tap do |response|
67
+ duration = ((Time.now - start) * 1_000_000).to_i
68
+ record(labels(env, response), duration)
69
+ end
70
+ rescue => exception
71
+ @exceptions.increment(exception: exception.class.name)
72
+ raise
73
+ end
74
+
75
+ def labels(env, response)
76
+ @label_builder.call(env).tap do |labels|
77
+ labels[:code] = response.first.to_s
78
+ end
79
+ end
80
+
81
+ def record(labels, duration)
82
+ @requests.increment(labels)
83
+ @requests_duration.increment(labels, duration)
84
+ @durations.add(labels, duration)
85
+ rescue
86
+ # TODO: log unexpected exception during request recording
87
+ nil
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,92 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'prometheus/client'
4
+ require 'prometheus/client/formats/json'
5
+ require 'prometheus/client/formats/text'
6
+
7
+ module Prometheus
8
+ module Client
9
+ module Rack
10
+ # Exporter is a Rack middleware that provides a sample implementation of
11
+ # a Prometheus HTTP client API.
12
+ class Exporter
13
+ attr_reader :app, :registry, :path
14
+
15
+ FORMATS = [Formats::Text, Formats::JSON]
16
+ FALLBACK = Formats::JSON
17
+
18
+ def initialize(app, options = {})
19
+ @app = app
20
+ @registry = options[:registry] || Client.registry
21
+ @path = options[:path] || '/metrics'
22
+ @acceptable = build_dictionary(FORMATS, FALLBACK)
23
+ end
24
+
25
+ def call(env)
26
+ if env['PATH_INFO'] == @path
27
+ format = negotiate(env['HTTP_ACCEPT'], @acceptable)
28
+ format ? respond_with(format) : not_acceptable(FORMATS)
29
+ else
30
+ @app.call(env)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def negotiate(accept, formats)
37
+ accept = '*/*' if accept.to_s.empty?
38
+
39
+ parse(accept).each do |content_type, _|
40
+ return formats[content_type] if formats.key?(content_type)
41
+ end
42
+
43
+ nil
44
+ end
45
+
46
+ def parse(header)
47
+ header.to_s.split(/\s*,\s*/).map do |type|
48
+ attributes = type.split(/\s*;\s*/)
49
+ quality = extract_quality(attributes)
50
+
51
+ [attributes.join('; '), quality]
52
+ end.sort_by(&:last).reverse
53
+ end
54
+
55
+ def extract_quality(attributes, default = 1.0)
56
+ quality = default
57
+
58
+ attributes.delete_if do |attr|
59
+ quality = attr.split('q=').last.to_f if attr.start_with?('q=')
60
+ end
61
+
62
+ quality
63
+ end
64
+
65
+ def respond_with(format)
66
+ [
67
+ 200,
68
+ { 'Content-Type' => format::CONTENT_TYPE },
69
+ [format.marshal(@registry)],
70
+ ]
71
+ end
72
+
73
+ def not_acceptable(formats)
74
+ types = formats.map { |format| format::MEDIA_TYPE }
75
+
76
+ [
77
+ 406,
78
+ { 'Content-Type' => 'text/plain' },
79
+ ["Supported media types: #{types.join(', ')}"],
80
+ ]
81
+ end
82
+
83
+ def build_dictionary(formats, fallback)
84
+ formats.each_with_object('*/*' => fallback) do |format, memo|
85
+ memo[format::CONTENT_TYPE] = format
86
+ memo[format::MEDIA_TYPE] = format
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'thread'
4
+
5
+ require 'prometheus/client/counter'
6
+ require 'prometheus/client/summary'
7
+ require 'prometheus/client/gauge'
8
+
9
+ module Prometheus
10
+ module Client
11
+ # Registry
12
+ class Registry
13
+ class AlreadyRegisteredError < StandardError; end
14
+
15
+ def initialize
16
+ @metrics = {}
17
+ @mutex = Mutex.new
18
+ end
19
+
20
+ def register(metric)
21
+ name = metric.name
22
+
23
+ @mutex.synchronize do
24
+ if exist?(name.to_sym)
25
+ fail AlreadyRegisteredError, "#{name} has already been registered"
26
+ else
27
+ @metrics[name.to_sym] = metric
28
+ end
29
+ end
30
+
31
+ metric
32
+ end
33
+
34
+ def counter(name, docstring, base_labels = {})
35
+ register(Counter.new(name, docstring, base_labels))
36
+ end
37
+
38
+ def summary(name, docstring, base_labels = {})
39
+ register(Summary.new(name, docstring, base_labels))
40
+ end
41
+
42
+ def gauge(name, docstring, base_labels = {})
43
+ register(Gauge.new(name, docstring, base_labels))
44
+ end
45
+
46
+ def exist?(name)
47
+ @metrics.key?(name)
48
+ end
49
+
50
+ def get(name)
51
+ @metrics[name.to_sym]
52
+ end
53
+
54
+ def metrics
55
+ @metrics.values
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'quantile'
4
+ require 'prometheus/client/metric'
5
+
6
+ module Prometheus
7
+ module Client
8
+ # Summary is an accumulator for samples. It captures Numeric data and
9
+ # provides an efficient quantile calculation mechanism.
10
+ class Summary < Metric
11
+ # Value represents the state of a Summary at a given point.
12
+ class Value < Hash
13
+ attr_accessor :sum, :total
14
+
15
+ def initialize(estimator)
16
+ @sum = estimator.sum
17
+ @total = estimator.observations
18
+
19
+ estimator.invariants.each do |invariant|
20
+ self[invariant.quantile] = estimator.query(invariant.quantile)
21
+ end
22
+ end
23
+ end
24
+
25
+ def type
26
+ :summary
27
+ end
28
+
29
+ # Records a given value.
30
+ def add(labels, value)
31
+ label_set = label_set_for(labels)
32
+ synchronize { @values[label_set].observe(value) }
33
+ end
34
+
35
+ # Returns the value for the given label set
36
+ def get(labels = {})
37
+ @validator.valid?(labels)
38
+
39
+ synchronize do
40
+ Value.new(@values[labels])
41
+ end
42
+ end
43
+
44
+ # Returns all label sets with their values
45
+ def values
46
+ synchronize do
47
+ @values.each_with_object({}) do |(labels, value), memo|
48
+ memo[labels] = Value.new(value)
49
+ end
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def default
56
+ Quantile::Estimator.new
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ module Prometheus
4
+ module Client
5
+ VERSION = '0.4.3'
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: custom-prometheus-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.3
5
+ platform: ruby
6
+ authors:
7
+ - Shah Bagdadi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: quantile
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.0
27
+ description:
28
+ email:
29
+ - email.shanu@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - README.md
35
+ - lib/prometheus.rb
36
+ - lib/prometheus/client.rb
37
+ - lib/prometheus/client/counter.rb
38
+ - lib/prometheus/client/formats/json.rb
39
+ - lib/prometheus/client/formats/text.rb
40
+ - lib/prometheus/client/gauge.rb
41
+ - lib/prometheus/client/label_set_validator.rb
42
+ - lib/prometheus/client/metric.rb
43
+ - lib/prometheus/client/push.rb
44
+ - lib/prometheus/client/rack/collector.rb
45
+ - lib/prometheus/client/rack/exporter.rb
46
+ - lib/prometheus/client/registry.rb
47
+ - lib/prometheus/client/summary.rb
48
+ - lib/prometheus/client/version.rb
49
+ homepage: https://github.com/prometheus/client_ruby
50
+ licenses:
51
+ - Apache 2.0
52
+ metadata: {}
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 2.4.8
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: A suite of instrumentation metric primitivesthat can be exposed through a
73
+ web services interface.
74
+ test_files: []