prometheus-client-mmap 0.20.3-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +253 -0
  3. data/ext/fast_mmaped_file/extconf.rb +30 -0
  4. data/ext/fast_mmaped_file/fast_mmaped_file.c +122 -0
  5. data/ext/fast_mmaped_file/file_format.c +5 -0
  6. data/ext/fast_mmaped_file/file_format.h +11 -0
  7. data/ext/fast_mmaped_file/file_parsing.c +195 -0
  8. data/ext/fast_mmaped_file/file_parsing.h +27 -0
  9. data/ext/fast_mmaped_file/file_reading.c +102 -0
  10. data/ext/fast_mmaped_file/file_reading.h +30 -0
  11. data/ext/fast_mmaped_file/globals.h +14 -0
  12. data/ext/fast_mmaped_file/mmap.c +427 -0
  13. data/ext/fast_mmaped_file/mmap.h +61 -0
  14. data/ext/fast_mmaped_file/rendering.c +199 -0
  15. data/ext/fast_mmaped_file/rendering.h +8 -0
  16. data/ext/fast_mmaped_file/utils.c +56 -0
  17. data/ext/fast_mmaped_file/utils.h +22 -0
  18. data/ext/fast_mmaped_file/value_access.c +242 -0
  19. data/ext/fast_mmaped_file/value_access.h +15 -0
  20. data/ext/fast_mmaped_file_rs/.cargo/config.toml +23 -0
  21. data/ext/fast_mmaped_file_rs/Cargo.lock +790 -0
  22. data/ext/fast_mmaped_file_rs/Cargo.toml +30 -0
  23. data/ext/fast_mmaped_file_rs/README.md +52 -0
  24. data/ext/fast_mmaped_file_rs/extconf.rb +30 -0
  25. data/ext/fast_mmaped_file_rs/src/error.rs +174 -0
  26. data/ext/fast_mmaped_file_rs/src/file_entry.rs +579 -0
  27. data/ext/fast_mmaped_file_rs/src/file_info.rs +190 -0
  28. data/ext/fast_mmaped_file_rs/src/lib.rs +79 -0
  29. data/ext/fast_mmaped_file_rs/src/macros.rs +14 -0
  30. data/ext/fast_mmaped_file_rs/src/map.rs +492 -0
  31. data/ext/fast_mmaped_file_rs/src/mmap.rs +151 -0
  32. data/ext/fast_mmaped_file_rs/src/parser.rs +346 -0
  33. data/ext/fast_mmaped_file_rs/src/raw_entry.rs +473 -0
  34. data/ext/fast_mmaped_file_rs/src/testhelper.rs +222 -0
  35. data/ext/fast_mmaped_file_rs/src/util.rs +121 -0
  36. data/lib/2.7/fast_mmaped_file.so +0 -0
  37. data/lib/2.7/fast_mmaped_file_rs.so +0 -0
  38. data/lib/3.0/fast_mmaped_file.so +0 -0
  39. data/lib/3.0/fast_mmaped_file_rs.so +0 -0
  40. data/lib/3.1/fast_mmaped_file.so +0 -0
  41. data/lib/3.1/fast_mmaped_file_rs.so +0 -0
  42. data/lib/3.2/fast_mmaped_file.so +0 -0
  43. data/lib/3.2/fast_mmaped_file_rs.so +0 -0
  44. data/lib/prometheus/client/configuration.rb +23 -0
  45. data/lib/prometheus/client/counter.rb +27 -0
  46. data/lib/prometheus/client/formats/text.rb +118 -0
  47. data/lib/prometheus/client/gauge.rb +40 -0
  48. data/lib/prometheus/client/helper/entry_parser.rb +132 -0
  49. data/lib/prometheus/client/helper/file_locker.rb +50 -0
  50. data/lib/prometheus/client/helper/json_parser.rb +23 -0
  51. data/lib/prometheus/client/helper/metrics_processing.rb +45 -0
  52. data/lib/prometheus/client/helper/metrics_representation.rb +51 -0
  53. data/lib/prometheus/client/helper/mmaped_file.rb +64 -0
  54. data/lib/prometheus/client/helper/plain_file.rb +29 -0
  55. data/lib/prometheus/client/histogram.rb +80 -0
  56. data/lib/prometheus/client/label_set_validator.rb +86 -0
  57. data/lib/prometheus/client/metric.rb +80 -0
  58. data/lib/prometheus/client/mmaped_dict.rb +79 -0
  59. data/lib/prometheus/client/mmaped_value.rb +154 -0
  60. data/lib/prometheus/client/page_size.rb +17 -0
  61. data/lib/prometheus/client/push.rb +203 -0
  62. data/lib/prometheus/client/rack/collector.rb +88 -0
  63. data/lib/prometheus/client/rack/exporter.rb +96 -0
  64. data/lib/prometheus/client/registry.rb +65 -0
  65. data/lib/prometheus/client/simple_value.rb +31 -0
  66. data/lib/prometheus/client/summary.rb +69 -0
  67. data/lib/prometheus/client/support/unicorn.rb +35 -0
  68. data/lib/prometheus/client/uses_value_type.rb +20 -0
  69. data/lib/prometheus/client/version.rb +5 -0
  70. data/lib/prometheus/client.rb +58 -0
  71. data/lib/prometheus.rb +3 -0
  72. data/vendor/c/hashmap/.gitignore +52 -0
  73. data/vendor/c/hashmap/LICENSE +21 -0
  74. data/vendor/c/hashmap/README.md +90 -0
  75. data/vendor/c/hashmap/_config.yml +1 -0
  76. data/vendor/c/hashmap/src/hashmap.c +692 -0
  77. data/vendor/c/hashmap/src/hashmap.h +267 -0
  78. data/vendor/c/hashmap/test/Makefile +22 -0
  79. data/vendor/c/hashmap/test/hashmap_test.c +608 -0
  80. data/vendor/c/jsmn/.travis.yml +4 -0
  81. data/vendor/c/jsmn/LICENSE +20 -0
  82. data/vendor/c/jsmn/Makefile +41 -0
  83. data/vendor/c/jsmn/README.md +168 -0
  84. data/vendor/c/jsmn/example/jsondump.c +126 -0
  85. data/vendor/c/jsmn/example/simple.c +76 -0
  86. data/vendor/c/jsmn/jsmn.c +314 -0
  87. data/vendor/c/jsmn/jsmn.h +76 -0
  88. data/vendor/c/jsmn/library.json +16 -0
  89. data/vendor/c/jsmn/test/test.h +27 -0
  90. data/vendor/c/jsmn/test/tests.c +407 -0
  91. data/vendor/c/jsmn/test/testutil.h +94 -0
  92. metadata +243 -0
@@ -0,0 +1,203 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'base64'
4
+ require 'thread'
5
+ require 'net/http'
6
+ require 'uri'
7
+ require 'erb'
8
+ require 'set'
9
+
10
+ require 'prometheus/client'
11
+ require 'prometheus/client/formats/text'
12
+ require 'prometheus/client/label_set_validator'
13
+
14
+ module Prometheus
15
+ # Client is a ruby implementation for a Prometheus compatible client.
16
+ module Client
17
+ # Push implements a simple way to transmit a given registry to a given
18
+ # Pushgateway.
19
+ class Push
20
+ class HttpError < StandardError; end
21
+ class HttpRedirectError < HttpError; end
22
+ class HttpClientError < HttpError; end
23
+ class HttpServerError < HttpError; end
24
+
25
+ DEFAULT_GATEWAY = 'http://localhost:9091'.freeze
26
+ PATH = '/metrics/job/%s'.freeze
27
+ SUPPORTED_SCHEMES = %w(http https).freeze
28
+
29
+ attr_reader :job, :gateway, :path
30
+
31
+ def initialize(job:, gateway: DEFAULT_GATEWAY, grouping_key: {}, **kwargs)
32
+ raise ArgumentError, "job cannot be nil" if job.nil?
33
+ raise ArgumentError, "job cannot be empty" if job.empty?
34
+ @validator = LabelSetValidator.new()
35
+ @validator.validate(grouping_key)
36
+
37
+ @mutex = Mutex.new
38
+ @job = job
39
+ @gateway = gateway || DEFAULT_GATEWAY
40
+ @grouping_key = grouping_key
41
+ @path = build_path(job, grouping_key)
42
+
43
+ @uri = parse("#{@gateway}#{@path}")
44
+ validate_no_basic_auth!(@uri)
45
+
46
+ @http = Net::HTTP.new(@uri.host, @uri.port)
47
+ @http.use_ssl = (@uri.scheme == 'https')
48
+ @http.open_timeout = kwargs[:open_timeout] if kwargs[:open_timeout]
49
+ @http.read_timeout = kwargs[:read_timeout] if kwargs[:read_timeout]
50
+ end
51
+
52
+ def basic_auth(user, password)
53
+ @user = user
54
+ @password = password
55
+ end
56
+
57
+ def add(registry)
58
+ synchronize do
59
+ request(Net::HTTP::Post, registry)
60
+ end
61
+ end
62
+
63
+ def replace(registry)
64
+ synchronize do
65
+ request(Net::HTTP::Put, registry)
66
+ end
67
+ end
68
+
69
+ def delete
70
+ synchronize do
71
+ request(Net::HTTP::Delete)
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def parse(url)
78
+ uri = URI.parse(url)
79
+
80
+ unless SUPPORTED_SCHEMES.include?(uri.scheme)
81
+ raise ArgumentError, 'only HTTP gateway URLs are supported currently.'
82
+ end
83
+
84
+ uri
85
+ rescue URI::InvalidURIError => e
86
+ raise ArgumentError, "#{url} is not a valid URL: #{e}"
87
+ end
88
+
89
+ def build_path(job, grouping_key)
90
+ path = format(PATH, ERB::Util::url_encode(job))
91
+
92
+ grouping_key.each do |label, value|
93
+ if value.include?('/')
94
+ encoded_value = Base64.urlsafe_encode64(value)
95
+ path += "/#{label}@base64/#{encoded_value}"
96
+ # While it's valid for the urlsafe_encode64 function to return an
97
+ # empty string when the input string is empty, it doesn't work for
98
+ # our specific use case as we're putting the result into a URL path
99
+ # segment. A double slash (`//`) can be normalised away by HTTP
100
+ # libraries, proxies, and web servers.
101
+ #
102
+ # For empty strings, we use a single padding character (`=`) as the
103
+ # value.
104
+ #
105
+ # See the pushgateway docs for more details:
106
+ #
107
+ # https://github.com/prometheus/pushgateway/blob/6393a901f56d4dda62cd0f6ab1f1f07c495b6354/README.md#url
108
+ elsif value.empty?
109
+ path += "/#{label}@base64/="
110
+ else
111
+ path += "/#{label}/#{ERB::Util::url_encode(value)}"
112
+ end
113
+ end
114
+
115
+ path
116
+ end
117
+
118
+ def request(req_class, registry = nil)
119
+ validate_no_label_clashes!(registry) if registry
120
+
121
+ req = req_class.new(@uri)
122
+ req.content_type = Formats::Text::CONTENT_TYPE
123
+ req.basic_auth(@user, @password) if @user
124
+ req.body = Formats::Text.marshal(registry) if registry
125
+
126
+ response = @http.request(req)
127
+ validate_response!(response)
128
+
129
+ response
130
+ end
131
+
132
+ def synchronize
133
+ @mutex.synchronize { yield }
134
+ end
135
+
136
+ def validate_no_basic_auth!(uri)
137
+ if uri.user || uri.password
138
+ raise ArgumentError, <<~EOF
139
+ Setting Basic Auth credentials in the gateway URL is not supported, please call the `basic_auth` method.
140
+
141
+ Received username `#{uri.user}` in gateway URL. Instead of passing
142
+ Basic Auth credentials like this:
143
+
144
+ ```
145
+ push = Prometheus::Client::Push.new(job: "my-job", gateway: "http://user:password@localhost:9091")
146
+ ```
147
+
148
+ please pass them like this:
149
+
150
+ ```
151
+ push = Prometheus::Client::Push.new(job: "my-job", gateway: "http://localhost:9091")
152
+ push.basic_auth("user", "password")
153
+ ```
154
+
155
+ While URLs do support passing Basic Auth credentials using the
156
+ `http://user:password@example.com/` syntax, the username and
157
+ password in that syntax have to follow the usual rules for URL
158
+ encoding of characters per RFC 3986
159
+ (https://datatracker.ietf.org/doc/html/rfc3986#section-2.1).
160
+
161
+ Rather than place the burden of correctly performing that encoding
162
+ on users of this gem, we decided to have a separate method for
163
+ supplying Basic Auth credentials, with no requirement to URL encode
164
+ the characters in them.
165
+ EOF
166
+ end
167
+ end
168
+
169
+ def validate_no_label_clashes!(registry)
170
+ # There's nothing to check if we don't have a grouping key
171
+ return if @grouping_key.empty?
172
+
173
+ # We could be doing a lot of comparisons, so let's do them against a
174
+ # set rather than an array
175
+ grouping_key_labels = @grouping_key.keys.to_set
176
+
177
+ registry.metrics.each do |metric|
178
+ metric.values.keys.first.keys.each do |label|
179
+ if grouping_key_labels.include?(label)
180
+ raise LabelSetValidator::InvalidLabelSetError,
181
+ "label :#{label} from grouping key collides with label of the " \
182
+ "same name from metric :#{metric.name} and would overwrite it"
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ def validate_response!(response)
189
+ status = Integer(response.code)
190
+ if status >= 300
191
+ message = "status: #{response.code}, message: #{response.message}, body: #{response.body}"
192
+ if status <= 399
193
+ raise HttpRedirectError, message
194
+ elsif status <= 499
195
+ raise HttpClientError, message
196
+ else
197
+ raise HttpServerError, message
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,88 @@
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
+
19
+ init_request_metrics
20
+ init_exception_metrics
21
+ end
22
+
23
+ def call(env) # :nodoc:
24
+ trace(env) { @app.call(env) }
25
+ end
26
+
27
+ protected
28
+
29
+ DEFAULT_LABEL_BUILDER = proc do |env|
30
+ {
31
+ method: env['REQUEST_METHOD'].downcase,
32
+ host: env['HTTP_HOST'].to_s,
33
+ path: env['PATH_INFO'].to_s,
34
+ }
35
+ end
36
+
37
+ def init_request_metrics
38
+ @requests = @registry.counter(
39
+ :http_requests_total,
40
+ 'A counter of the total number of HTTP requests made.',
41
+ )
42
+ @durations = @registry.summary(
43
+ :http_request_duration_seconds,
44
+ 'A summary of the response latency.',
45
+ )
46
+ @durations_hist = @registry.histogram(
47
+ :http_req_duration_seconds,
48
+ 'A histogram of the response latency.',
49
+ )
50
+ end
51
+
52
+ def init_exception_metrics
53
+ @exceptions = @registry.counter(
54
+ :http_exceptions_total,
55
+ 'A counter of the total number of exceptions raised.',
56
+ )
57
+ end
58
+
59
+ def trace(env)
60
+ start = Time.now
61
+ yield.tap do |response|
62
+ duration = (Time.now - start).to_f
63
+ record(labels(env, response), duration)
64
+ end
65
+ rescue => exception
66
+ @exceptions.increment(exception: exception.class.name)
67
+ raise
68
+ end
69
+
70
+ def labels(env, response)
71
+ @label_builder.call(env).tap do |labels|
72
+ labels[:code] = response.first.to_s
73
+ end
74
+ end
75
+
76
+ def record(labels, duration)
77
+ @requests.increment(labels)
78
+ @durations.observe(labels, duration)
79
+ @durations_hist.observe(labels, duration)
80
+ rescue => exception
81
+ @exceptions.increment(exception: exception.class.name)
82
+ raise
83
+ nil
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,96 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'prometheus/client'
4
+ require 'prometheus/client/formats/text'
5
+
6
+ module Prometheus
7
+ module Client
8
+ module Rack
9
+ # Exporter is a Rack middleware that provides a sample implementation of
10
+ # a Prometheus HTTP client API.
11
+ class Exporter
12
+ attr_reader :app, :registry, :path
13
+
14
+ FORMATS = [Formats::Text].freeze
15
+ FALLBACK = Formats::Text
16
+
17
+ def initialize(app, options = {})
18
+ @app = app
19
+ @registry = options[:registry] || Client.registry
20
+ @path = options[:path] || '/metrics'
21
+ @acceptable = build_dictionary(FORMATS, FALLBACK)
22
+ end
23
+
24
+ def call(env)
25
+ if env['PATH_INFO'] == @path
26
+ format = negotiate(env['HTTP_ACCEPT'], @acceptable)
27
+ format ? respond_with(format) : not_acceptable(FORMATS)
28
+ else
29
+ @app.call(env)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def negotiate(accept, formats)
36
+ accept = '*/*' if accept.to_s.empty?
37
+
38
+ parse(accept).each do |content_type, _|
39
+ return formats[content_type] if formats.key?(content_type)
40
+ end
41
+
42
+ nil
43
+ end
44
+
45
+ def parse(header)
46
+ header.to_s.split(/\s*,\s*/).map do |type|
47
+ attributes = type.split(/\s*;\s*/)
48
+ quality = extract_quality(attributes)
49
+
50
+ [attributes.join('; '), quality]
51
+ end.sort_by(&:last).reverse
52
+ end
53
+
54
+ def extract_quality(attributes, default = 1.0)
55
+ quality = default
56
+
57
+ attributes.delete_if do |attr|
58
+ quality = attr.split('q=').last.to_f if attr.start_with?('q=')
59
+ end
60
+
61
+ quality
62
+ end
63
+
64
+ def respond_with(format)
65
+ response = if Prometheus::Client.configuration.value_class.multiprocess
66
+ format.marshal_multiprocess
67
+ else
68
+ format.marshal
69
+ end
70
+ [
71
+ 200,
72
+ { 'Content-Type' => format::CONTENT_TYPE },
73
+ [response],
74
+ ]
75
+ end
76
+
77
+ def not_acceptable(formats)
78
+ types = formats.map { |format| format::MEDIA_TYPE }
79
+
80
+ [
81
+ 406,
82
+ { 'Content-Type' => 'text/plain' },
83
+ ["Supported media types: #{types.join(', ')}"],
84
+ ]
85
+ end
86
+
87
+ def build_dictionary(formats, fallback)
88
+ formats.each_with_object('*/*' => fallback) do |format, memo|
89
+ memo[format::CONTENT_TYPE] = format
90
+ memo[format::MEDIA_TYPE] = format
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,65 @@
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
+ require 'prometheus/client/histogram'
9
+
10
+ module Prometheus
11
+ module Client
12
+ # Registry
13
+ class Registry
14
+ class AlreadyRegisteredError < StandardError; end
15
+
16
+ def initialize
17
+ @metrics = {}
18
+ @mutex = Mutex.new
19
+ end
20
+
21
+ def register(metric)
22
+ name = metric.name
23
+
24
+ @mutex.synchronize do
25
+ if exist?(name.to_sym)
26
+ raise AlreadyRegisteredError, "#{name} has already been registered"
27
+ else
28
+ @metrics[name.to_sym] = metric
29
+ end
30
+ end
31
+
32
+ metric
33
+ end
34
+
35
+ def counter(name, docstring, base_labels = {})
36
+ register(Counter.new(name, docstring, base_labels))
37
+ end
38
+
39
+ def summary(name, docstring, base_labels = {})
40
+ register(Summary.new(name, docstring, base_labels))
41
+ end
42
+
43
+ def gauge(name, docstring, base_labels = {}, multiprocess_mode = :all)
44
+ register(Gauge.new(name, docstring, base_labels, multiprocess_mode))
45
+ end
46
+
47
+ def histogram(name, docstring, base_labels = {},
48
+ buckets = Histogram::DEFAULT_BUCKETS)
49
+ register(Histogram.new(name, docstring, base_labels, buckets))
50
+ end
51
+
52
+ def exist?(name)
53
+ @metrics.key?(name)
54
+ end
55
+
56
+ def get(name)
57
+ @metrics[name.to_sym]
58
+ end
59
+
60
+ def metrics
61
+ @metrics.values
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,31 @@
1
+ require 'json'
2
+
3
+ module Prometheus
4
+ module Client
5
+ class SimpleValue
6
+ def initialize(_type, _metric_name, _name, _labels, *_args)
7
+ @value = 0.0
8
+ end
9
+
10
+ def set(value)
11
+ @value = value
12
+ end
13
+
14
+ def increment(by = 1)
15
+ @value += by
16
+ end
17
+
18
+ def decrement(by = 1)
19
+ @value -= by
20
+ end
21
+
22
+ def get
23
+ @value
24
+ end
25
+
26
+ def self.multiprocess
27
+ false
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,69 @@
1
+ require 'prometheus/client/metric'
2
+ require 'prometheus/client/uses_value_type'
3
+
4
+ module Prometheus
5
+ module Client
6
+ # Summary is an accumulator for samples. It captures Numeric data and
7
+ # provides an efficient quantile calculation mechanism.
8
+ class Summary < Metric
9
+ extend Gem::Deprecate
10
+
11
+ # Value represents the state of a Summary at a given point.
12
+ class Value < Hash
13
+ include UsesValueType
14
+ attr_accessor :sum, :total
15
+
16
+ def initialize(type, name, labels)
17
+ @sum = value_object(type, name, "#{name}_sum", labels)
18
+ @total = value_object(type, name, "#{name}_count", labels)
19
+ end
20
+
21
+ def observe(value)
22
+ @sum.increment(value)
23
+ @total.increment
24
+ end
25
+ end
26
+
27
+ def initialize(name, docstring, base_labels = {})
28
+ super(name, docstring, base_labels)
29
+ end
30
+
31
+ def type
32
+ :summary
33
+ end
34
+
35
+ # Records a given value.
36
+ def observe(labels, value)
37
+ label_set = label_set_for(labels)
38
+ synchronize { @values[label_set].observe(value) }
39
+ end
40
+
41
+ alias add observe
42
+ deprecate :add, :observe, 2016, 10
43
+
44
+ # Returns the value for the given label set
45
+ def get(labels = {})
46
+ @validator.valid?(labels)
47
+
48
+ synchronize do
49
+ @values[labels].sum.get
50
+ end
51
+ end
52
+
53
+ # Returns all label sets with their values
54
+ def values
55
+ synchronize do
56
+ @values.each_with_object({}) do |(labels, value), memo|
57
+ memo[labels] = value.sum
58
+ end
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def default(labels)
65
+ Value.new(type, @name, labels)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,35 @@
1
+ module Prometheus
2
+ module Client
3
+ module Support
4
+ module Unicorn
5
+ def self.worker_pid_provider
6
+ wid = worker_id
7
+ if wid.nil?
8
+ "process_id_#{Process.pid}"
9
+ else
10
+ "worker_id_#{wid}"
11
+ end
12
+ end
13
+
14
+ def self.worker_id
15
+ match = $0.match(/worker\[([^\]]+)\]/)
16
+ if match
17
+ match[1]
18
+ else
19
+ object_based_worker_id
20
+ end
21
+ end
22
+
23
+ def self.object_based_worker_id
24
+ return unless defined?(::Unicorn::Worker)
25
+
26
+ workers = ObjectSpace.each_object(::Unicorn::Worker)
27
+ return if workers.nil?
28
+
29
+ workers_first = workers.first
30
+ workers_first.nr unless workers_first.nil?
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ require 'prometheus/client/simple_value'
2
+
3
+ module Prometheus
4
+ module Client
5
+ # Module providing convenience methods for creating value_object
6
+ module UsesValueType
7
+ def value_class
8
+ Prometheus::Client.configuration.value_class
9
+ end
10
+
11
+ def value_object(type, metric_name, name, labels, *args)
12
+ value_class.new(type, metric_name, name, labels, *args)
13
+ rescue StandardError => e
14
+ Prometheus::Client.logger.info("error #{e} while creating instance of #{value_class} defaulting to SimpleValue")
15
+ Prometheus::Client.logger.debug("error #{e} backtrace #{e.backtrace.join("\n")}")
16
+ Prometheus::Client::SimpleValue.new(type, metric_name, name, labels)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ module Prometheus
2
+ module Client
3
+ VERSION = '0.20.3'.freeze
4
+ end
5
+ end
@@ -0,0 +1,58 @@
1
+ require 'prometheus/client/registry'
2
+ require 'prometheus/client/configuration'
3
+ require 'prometheus/client/mmaped_value'
4
+
5
+ module Prometheus
6
+ # Client is a ruby implementation for a Prometheus compatible client.
7
+ module Client
8
+ class << self
9
+ attr_writer :configuration
10
+
11
+ def configuration
12
+ @configuration ||= Configuration.new
13
+ end
14
+
15
+ def configure
16
+ yield(configuration)
17
+ end
18
+
19
+ # Returns a default registry object
20
+ def registry
21
+ @registry ||= Registry.new
22
+ end
23
+
24
+ def logger
25
+ configuration.logger
26
+ end
27
+
28
+ def pid
29
+ configuration.pid_provider.call
30
+ end
31
+
32
+ # Resets the registry and reinitializes all metrics files.
33
+ # Use case: clean up everything in specs `before` block,
34
+ # to prevent leaking the state between specs which are updating metrics.
35
+ def reset!
36
+ @registry = nil
37
+ ::Prometheus::Client::MmapedValue.reset_and_reinitialize
38
+ end
39
+
40
+ def cleanup!
41
+ Dir.glob("#{configuration.multiprocess_files_dir}/*.db").each { |f| File.unlink(f) if File.exist?(f) }
42
+ end
43
+
44
+ # With `force: false`: reinitializes metric files only for processes with the changed PID.
45
+ # With `force: true`: reinitializes all metrics files.
46
+ # Always keeps the registry.
47
+ # Use case (`force: false`): pick up new metric files on each worker start,
48
+ # without resetting already registered files for the master or previously initialized workers.
49
+ def reinitialize_on_pid_change(force: false)
50
+ if force
51
+ ::Prometheus::Client::MmapedValue.reset_and_reinitialize
52
+ else
53
+ ::Prometheus::Client::MmapedValue.reinitialize_on_pid_change
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
data/lib/prometheus.rb ADDED
@@ -0,0 +1,3 @@
1
+ # Prometheus is a generic time-series collection and computation server.
2
+ module Prometheus
3
+ end