prometheus-client-mmap 0.9.10 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea7b6fe48f2d5019181dcc236a5a8d187ea5aeb7e7d8e2acc8d31bfb6bc62207
4
- data.tar.gz: 6231f6c5e44fc07b7084d4f9e816c9eb97916bb00235829349b9903af4c9621b
3
+ metadata.gz: 77dda8e211c5981651a160500f0332b886e124935e969136abe4fd234ae311e1
4
+ data.tar.gz: 4ba3176b93611a3bcf63b0aed029408a5f22f33ca16635d05c9c244e33b0bfaa
5
5
  SHA512:
6
- metadata.gz: 48cc3fa10e0879d90340349ccc118dbd4b3eca40ee8e513f5600f58354f089c4ac7e8598ede6a696b24aafca51f75baeb8e2f4b1967a42b32dcacb2d408c83bb
7
- data.tar.gz: 2a01473c292535c2931efdbb1b5e958389d71521cb55f25edddef6f097eddec7d5cac08e0e4bab3b85ee5757626f67930312fefce99f24d7184541a1ab07b559
6
+ metadata.gz: 75cbb10eed65af805c4cccda2e91783ec0ce0987150881ecc763d8de07ea3af150eb20bc41fbaf414dc66d4341141d163cf83514f7f4c913aaf1fdb0efc99dad
7
+ data.tar.gz: d4b2e4e7a3a78a315cb490a5d07125eaeb2782c6e7c0cb1cbfa0ff302d44ca343b752a29912d3f46b2acc7a6999d84ffe5ee3903d2004a501c2d4dac62f93846
@@ -1,20 +1,17 @@
1
1
  #include <errno.h>
2
+ #include <hashmap.h>
3
+ #include <jsmn.h>
2
4
  #include <ruby.h>
3
5
  #include <ruby/intern.h>
4
-
5
6
  #include <sys/mman.h>
6
7
 
7
- #include <hashmap.h>
8
- #include <jsmn.h>
9
-
10
- #include "globals.h"
11
- #include "utils.h"
12
- #include "value_access.h"
13
-
14
8
  #include "file_parsing.h"
15
9
  #include "file_reading.h"
10
+ #include "globals.h"
16
11
  #include "mmap.h"
17
12
  #include "rendering.h"
13
+ #include "utils.h"
14
+ #include "value_access.h"
18
15
 
19
16
  VALUE MMAPED_FILE = Qnil;
20
17
 
@@ -1,9 +1,9 @@
1
+ #include "file_parsing.h"
2
+
1
3
  #include <hashmap.h>
2
4
  #include <jsmn.h>
3
- #include <ruby.h>
4
5
 
5
6
  #include "file_format.h"
6
- #include "file_parsing.h"
7
7
  #include "globals.h"
8
8
  #include "utils.h"
9
9
 
@@ -2,6 +2,7 @@
2
2
  #define FILE_PARSING_H
3
3
  #include <file_reading.h>
4
4
  #include <hashmap.h>
5
+ #include <ruby.h>
5
6
 
6
7
  typedef struct {
7
8
  char *json;
@@ -1,8 +1,8 @@
1
+ #include "file_reading.h"
2
+
1
3
  #include <errno.h>
2
4
  #include <fcntl.h>
3
- #include <ruby.h>
4
5
 
5
- #include "file_reading.h"
6
6
  #include "utils.h"
7
7
 
8
8
  static int file_open(file_t *source, const char *filepath) {
@@ -1,11 +1,11 @@
1
+ #include "mmap.h"
2
+
1
3
  #include <errno.h>
2
4
  #include <fcntl.h>
3
- #include <ruby.h>
4
5
  #include <ruby/util.h>
5
6
  #include <sys/mman.h>
6
7
 
7
8
  #include "file_format.h"
8
- #include "mmap.h"
9
9
  #include "utils.h"
10
10
 
11
11
  #if 0
@@ -42,7 +42,6 @@ static VALUE mm_str(VALUE obj, int modify) {
42
42
  GET_MMAP(obj, i_mm, modify & ~MM_ORIGIN);
43
43
  if (modify & MM_MODIFY) {
44
44
  if (i_mm->t->flag & MM_FROZEN) rb_error_frozen("mmap");
45
- if (!OBJ_TAINTED(ret) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't modify mmap");
46
45
  }
47
46
  ret = rb_obj_alloc(rb_cString);
48
47
  if (rb_obj_tainted(obj)) {
@@ -170,6 +169,35 @@ VALUE mm_s_alloc(VALUE obj) {
170
169
  return res;
171
170
  }
172
171
 
172
+ size_t next_page_boundary(size_t value) {
173
+ size_t page_size = sysconf(_SC_PAGESIZE);
174
+
175
+ while (page_size < value) {
176
+ page_size *= 2;
177
+ }
178
+
179
+ return page_size;
180
+ }
181
+
182
+ /* Reference implementations:
183
+ * mozilla: https://hg.mozilla.org/mozilla-central/file/3d846420a907/xpcom/glue/FileUtils.cpp#l71
184
+ * glibc: https://github.com/lattera/glibc/blob/master/sysdeps/posix/posix_fallocate.c
185
+ */
186
+ int reserve_mmap_file_bytes(int fd, size_t size) {
187
+ #if __linux__
188
+ /* From https://stackoverflow.com/a/22820221: The difference with
189
+ * ftruncate(2) is that (on file systems supporting it, e.g. Ext4)
190
+ * disk space is indeed reserved by posix_fallocate but ftruncate
191
+ * extends the file by adding holes (and without reserving disk
192
+ * space). */
193
+ return posix_fallocate(fd, 0, size);
194
+ #else
195
+ /* We simplify the reference implemnetations since we generally
196
+ * don't need to reserve more than a page size. */
197
+ return ftruncate(fd, size);
198
+ #endif
199
+ }
200
+
173
201
  VALUE mm_init(VALUE obj, VALUE fname) {
174
202
  struct stat st;
175
203
  int fd, smode = 0, pmode = 0, vscope, perm, init;
@@ -187,13 +215,6 @@ VALUE mm_init(VALUE obj, VALUE fname) {
187
215
  SafeStringValue(fname);
188
216
  path = StringValuePtr(fname);
189
217
 
190
- {
191
- if (rb_safe_level() > 0 && OBJ_TAINTED(fname)) {
192
- rb_raise(rb_eSecurityError, "Insecure operation");
193
- }
194
- rb_secure(1);
195
- }
196
-
197
218
  vscope = MAP_SHARED;
198
219
  size = 0;
199
220
  perm = 0666;
@@ -206,6 +227,7 @@ VALUE mm_init(VALUE obj, VALUE fname) {
206
227
  }
207
228
 
208
229
  if (fstat(fd, &st) == -1) {
230
+ close(fd);
209
231
  rb_raise(rb_eArgError, "Can't stat %s", path);
210
232
  }
211
233
  size = st.st_size;
@@ -215,17 +237,21 @@ VALUE mm_init(VALUE obj, VALUE fname) {
215
237
  offset = 0;
216
238
  init = 0;
217
239
 
218
- if (size == 0 && (smode & O_RDWR)) {
219
- if (lseek(fd, INITIAL_SIZE - 1, SEEK_END) == -1) {
220
- rb_raise(rb_eIOError, "Can't lseek %zu", INITIAL_SIZE - 1);
221
- }
222
- if (write(fd, "\000", 1) != 1) {
223
- rb_raise(rb_eIOError, "Can't extend %s", path);
224
- }
240
+ if (size == 0) {
225
241
  init = 1;
226
242
  size = INITIAL_SIZE;
227
243
  }
228
244
 
245
+ /* We need to ensure the underlying file descriptor is at least a page size.
246
+ * Otherwise, we could get a SIGBUS error if mmap() attempts to read or write
247
+ * past the file. */
248
+ size_t reserve_size = next_page_boundary(size);
249
+
250
+ if (reserve_mmap_file_bytes(fd, reserve_size) != 0) {
251
+ close(fd);
252
+ rb_raise(rb_eIOError, "Can't reserve %zu bytes for memory-mapped file in %s", reserve_size, path);
253
+ }
254
+
229
255
  addr = mmap(0, size, pmode, vscope, fd, offset);
230
256
 
231
257
  if (addr == MAP_FAILED || !addr) {
@@ -1,9 +1,10 @@
1
+ #include "rendering.h"
2
+
1
3
  #include <float.h>
2
4
  #include <jsmn.h>
3
5
 
4
6
  #include "file_parsing.h"
5
7
  #include "globals.h"
6
- #include "rendering.h"
7
8
  #include "utils.h"
8
9
 
9
10
  #ifndef DBL_DECIMAL_DIG
@@ -1,8 +1,7 @@
1
- #include <errno.h>
2
- #include <ruby.h>
3
-
4
1
  #include "utils.h"
5
2
 
3
+ #include <errno.h>
4
+
6
5
  static void rb_save_exception(VALUE exception, VALUE message) {
7
6
  VALUE current_thread = rb_thread_current();
8
7
 
@@ -1,5 +1,6 @@
1
1
  #ifndef UNUSED_H
2
2
  #define UNUSED_H
3
+ #include <ruby.h>
3
4
 
4
5
  #ifdef UNUSED
5
6
  #elif defined(__GNUC__)
@@ -1,15 +1,13 @@
1
- #include <ruby.h>
2
- #include <ruby/intern.h>
1
+ #include "value_access.h"
3
2
 
4
3
  #include <errno.h>
5
4
  #include <fcntl.h>
5
+ #include <ruby/intern.h>
6
6
  #include <sys/mman.h>
7
7
  #include <unistd.h>
8
8
 
9
9
  #include "file_format.h"
10
10
  #include "mmap.h"
11
- #include "value_access.h"
12
-
13
11
  #include "utils.h"
14
12
 
15
13
  static void close_file(mm_ipc *i_mm) {
@@ -1,5 +1,6 @@
1
1
  #ifndef VALUE_ACCESS_H
2
2
  #define VALUE_ACCESS_H
3
+ #include <ruby.h>
3
4
 
4
5
  VALUE method_load_used(VALUE self);
5
6
 
Binary file
@@ -31,6 +31,10 @@ module Prometheus
31
31
  def increment(labels, value)
32
32
  @values[label_set_for(labels)].increment(value)
33
33
  end
34
+
35
+ def decrement(labels, value)
36
+ @values[label_set_for(labels)].decrement(value)
37
+ end
34
38
  end
35
39
  end
36
40
  end
@@ -57,6 +57,10 @@ module Prometheus
57
57
  Prometheus::Client.logger.warn("munmap raised error #{e}")
58
58
  end
59
59
 
60
+ def inspect
61
+ "#<#{self.class}:0x#{(object_id << 1).to_s(16)}>"
62
+ end
63
+
60
64
  private
61
65
 
62
66
  def init_value(key)
@@ -36,6 +36,10 @@ module Prometheus
36
36
  end
37
37
  end
38
38
 
39
+ def decrement(amount = 1)
40
+ increment(-amount)
41
+ end
42
+
39
43
  def set(value)
40
44
  @mutex.synchronize do
41
45
  initialize_file if pid_changed?
@@ -1,7 +1,9 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'thread'
3
4
  require 'net/http'
4
5
  require 'uri'
6
+ require 'erb'
5
7
 
6
8
  require 'prometheus/client'
7
9
  require 'prometheus/client/formats/text'
@@ -13,31 +15,45 @@ module Prometheus
13
15
  # Pushgateway.
14
16
  class Push
15
17
  DEFAULT_GATEWAY = 'http://localhost:9091'.freeze
16
- PATH = '/metrics/jobs/%s'.freeze
17
- INSTANCE_PATH = '/metrics/jobs/%s/instances/%s'.freeze
18
- HEADER = { 'Content-Type' => Formats::Text::CONTENT_TYPE }.freeze
18
+ PATH = '/metrics/job/%s'.freeze
19
+ INSTANCE_PATH = '/metrics/job/%s/instance/%s'.freeze
20
+ SUPPORTED_SCHEMES = %w(http https).freeze
19
21
 
20
22
  attr_reader :job, :instance, :gateway, :path
21
23
 
22
- def initialize(job, instance = nil, gateway = nil)
24
+ def initialize(job:, instance: nil, gateway: DEFAULT_GATEWAY, **kwargs)
25
+ raise ArgumentError, "job cannot be nil" if job.nil?
26
+ raise ArgumentError, "job cannot be empty" if job.empty?
27
+
28
+ @mutex = Mutex.new
23
29
  @job = job
24
30
  @instance = instance
25
31
  @gateway = gateway || DEFAULT_GATEWAY
26
- @uri = parse(@gateway)
27
32
  @path = build_path(job, instance)
33
+ @uri = parse("#{@gateway}#{@path}")
34
+
28
35
  @http = Net::HTTP.new(@uri.host, @uri.port)
36
+ @http.use_ssl = (@uri.scheme == 'https')
37
+ @http.open_timeout = kwargs[:open_timeout] if kwargs[:open_timeout]
38
+ @http.read_timeout = kwargs[:read_timeout] if kwargs[:read_timeout]
29
39
  end
30
40
 
31
41
  def add(registry)
32
- request('POST', registry)
42
+ synchronize do
43
+ request(Net::HTTP::Post, registry)
44
+ end
33
45
  end
34
46
 
35
47
  def replace(registry)
36
- request('PUT', registry)
48
+ synchronize do
49
+ request(Net::HTTP::Put, registry)
50
+ end
37
51
  end
38
52
 
39
53
  def delete
40
- @http.send_request('DELETE', path)
54
+ synchronize do
55
+ request(Net::HTTP::Delete)
56
+ end
41
57
  end
42
58
 
43
59
  private
@@ -45,27 +61,34 @@ module Prometheus
45
61
  def parse(url)
46
62
  uri = URI.parse(url)
47
63
 
48
- if uri.scheme == 'http'
49
- uri
50
- else
64
+ unless SUPPORTED_SCHEMES.include?(uri.scheme)
51
65
  raise ArgumentError, 'only HTTP gateway URLs are supported currently.'
52
66
  end
67
+
68
+ uri
53
69
  rescue URI::InvalidURIError => e
54
70
  raise ArgumentError, "#{url} is not a valid URL: #{e}"
55
71
  end
56
72
 
57
73
  def build_path(job, instance)
58
- if instance
59
- format(INSTANCE_PATH, URI.escape(job), URI.escape(instance))
74
+ if instance && !instance.empty?
75
+ format(INSTANCE_PATH, ERB::Util::url_encode(job), ERB::Util::url_encode(instance))
60
76
  else
61
- format(PATH, URI.escape(job))
77
+ format(PATH, ERB::Util::url_encode(job))
62
78
  end
63
79
  end
64
80
 
65
- def request(method, registry)
66
- data = Formats::Text.marshal(registry)
81
+ def request(req_class, registry = nil)
82
+ req = req_class.new(@uri)
83
+ req.content_type = Formats::Text::CONTENT_TYPE
84
+ req.basic_auth(@uri.user, @uri.password) if @uri.user
85
+ req.body = Formats::Text.marshal(registry) if registry
86
+
87
+ @http.request(req)
88
+ end
67
89
 
68
- @http.send_request(method, path, data, HEADER)
90
+ def synchronize
91
+ @mutex.synchronize { yield }
69
92
  end
70
93
  end
71
94
  end
@@ -15,6 +15,10 @@ module Prometheus
15
15
  @value += by
16
16
  end
17
17
 
18
+ def decrement(by = 1)
19
+ @value -= by
20
+ end
21
+
18
22
  def get
19
23
  @value
20
24
  end
@@ -1,5 +1,5 @@
1
1
  module Prometheus
2
2
  module Client
3
- VERSION = '0.9.10'.freeze
3
+ VERSION = '0.13.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prometheus-client-mmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.10
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Schmidt
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-09-16 00:00:00.000000000 Z
12
+ date: 2021-07-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fuzzbert
@@ -181,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
181
  - !ruby/object:Gem::Version
182
182
  version: '0'
183
183
  requirements: []
184
- rubygems_version: 3.0.3
184
+ rubygems_version: 3.1.4
185
185
  signing_key:
186
186
  specification_version: 4
187
187
  summary: A suite of instrumentation metric primitivesthat can be exposed through a