prometheus-client-mmap 0.25.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +1 -1
  3. data/README.md +32 -28
  4. data/ext/fast_mmaped_file_rs/Cargo.lock +195 -234
  5. data/ext/fast_mmaped_file_rs/Cargo.toml +7 -7
  6. data/ext/fast_mmaped_file_rs/extconf.rb +1 -3
  7. data/ext/fast_mmaped_file_rs/src/file_info.rs +51 -1
  8. data/ext/fast_mmaped_file_rs/src/mmap/inner.rs +0 -10
  9. data/ext/fast_mmaped_file_rs/src/mmap.rs +2 -5
  10. data/lib/prometheus/client/configuration.rb +1 -2
  11. data/lib/prometheus/client/formats/text.rb +1 -12
  12. data/lib/prometheus/client/helper/mmaped_file.rb +3 -14
  13. data/lib/prometheus/client/label_set_validator.rb +1 -2
  14. data/lib/prometheus/client/rack/exporter.rb +1 -3
  15. data/lib/prometheus/client/support/puma.rb +44 -0
  16. data/lib/prometheus/client/version.rb +1 -1
  17. metadata +9 -47
  18. data/ext/fast_mmaped_file/extconf.rb +0 -30
  19. data/ext/fast_mmaped_file/fast_mmaped_file.c +0 -122
  20. data/ext/fast_mmaped_file/file_format.c +0 -5
  21. data/ext/fast_mmaped_file/file_format.h +0 -11
  22. data/ext/fast_mmaped_file/file_parsing.c +0 -195
  23. data/ext/fast_mmaped_file/file_parsing.h +0 -27
  24. data/ext/fast_mmaped_file/file_reading.c +0 -102
  25. data/ext/fast_mmaped_file/file_reading.h +0 -30
  26. data/ext/fast_mmaped_file/globals.h +0 -14
  27. data/ext/fast_mmaped_file/mmap.c +0 -438
  28. data/ext/fast_mmaped_file/mmap.h +0 -61
  29. data/ext/fast_mmaped_file/rendering.c +0 -199
  30. data/ext/fast_mmaped_file/rendering.h +0 -8
  31. data/ext/fast_mmaped_file/utils.c +0 -56
  32. data/ext/fast_mmaped_file/utils.h +0 -22
  33. data/ext/fast_mmaped_file/value_access.c +0 -242
  34. data/ext/fast_mmaped_file/value_access.h +0 -15
  35. data/lib/prometheus/client/helper/loader.rb +0 -40
  36. data/vendor/c/hashmap/.gitignore +0 -52
  37. data/vendor/c/hashmap/LICENSE +0 -21
  38. data/vendor/c/hashmap/README.md +0 -90
  39. data/vendor/c/hashmap/_config.yml +0 -1
  40. data/vendor/c/hashmap/src/hashmap.c +0 -692
  41. data/vendor/c/hashmap/src/hashmap.h +0 -267
  42. data/vendor/c/hashmap/test/Makefile +0 -22
  43. data/vendor/c/hashmap/test/hashmap_test.c +0 -608
  44. data/vendor/c/jsmn/.travis.yml +0 -4
  45. data/vendor/c/jsmn/LICENSE +0 -20
  46. data/vendor/c/jsmn/Makefile +0 -41
  47. data/vendor/c/jsmn/README.md +0 -168
  48. data/vendor/c/jsmn/example/jsondump.c +0 -126
  49. data/vendor/c/jsmn/example/simple.c +0 -76
  50. data/vendor/c/jsmn/jsmn.c +0 -314
  51. data/vendor/c/jsmn/jsmn.h +0 -76
  52. data/vendor/c/jsmn/library.json +0 -16
  53. data/vendor/c/jsmn/test/test.h +0 -27
  54. data/vendor/c/jsmn/test/tests.c +0 -407
  55. data/vendor/c/jsmn/test/testutil.h +0 -94
@@ -6,26 +6,26 @@ edition = "2021"
6
6
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
7
 
8
8
  [dependencies]
9
- hashbrown = "0.13"
9
+ hashbrown = "0.14"
10
10
  libc = "0.2"
11
- magnus = { git = "https://github.com/matsadler/magnus", branch = "main", features = ["rb-sys"] }
12
- memmap2 = "0.5"
11
+ magnus = { version = "0.6", features = ["rb-sys"] }
12
+ memmap2 = "0.9"
13
13
  # v0.26 cannot be built on CentOS 7 https://github.com/nix-rust/nix/issues/1972
14
14
  nix = { version = "0.25", features = ["mman"] } # mman used for MsFlags
15
- rb-sys = "0.9"
15
+ rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
16
16
  serde = { version = "1.0", features = ["derive"] }
17
17
  serde_json = { version = "1.0", features = ["raw_value"] }
18
18
  smallvec = { version = "1.10", features = ["serde"] }
19
19
  thiserror = "1.0"
20
20
 
21
21
  [dev-dependencies]
22
- bstr = "1.4"
22
+ bstr = "1.9"
23
23
  indoc = "2.0"
24
24
  # We need the `embed` feature to run tests, but this triggers failures when building as a Gem.
25
- magnus = { git = "https://github.com/matsadler/magnus", branch = "main", features = ["rb-sys","embed"] }
25
+ magnus = { version = "0.6", features = ["rb-sys","embed"] }
26
26
  rand = "0.8"
27
27
  sha2 = "0.10"
28
- tempfile = "3.5"
28
+ tempfile = "3.9"
29
29
 
30
30
  [build-dependencies]
31
31
  rb-sys-env = "0.1"
@@ -24,7 +24,5 @@ if find_executable('rustc')
24
24
  ARGV = trimmed_argv
25
25
  end
26
26
  else
27
- puts 'rustc not found, skipping Rust extension.'
28
-
29
- File.write('Makefile', dummy_makefile($srcdir).join(''))
27
+ raise 'rustc not found. prometheus-client-mmap now requires Rust.'
30
28
  end
@@ -91,6 +91,11 @@ impl FileInfo {
91
91
 
92
92
  match self.file.read_to_end(buf) {
93
93
  Ok(n) if n == self.len => Ok(()),
94
+ // A worker may expand the file between our `stat` and `read`, no harm done.
95
+ Ok(n) if n > self.len => {
96
+ self.len = n;
97
+ Ok(())
98
+ }
94
99
  Ok(_) => Err(MmapError::io(
95
100
  "read",
96
101
  &self.path,
@@ -106,6 +111,8 @@ mod test {
106
111
  use magnus::{eval, RArray, Symbol};
107
112
  use rand::{thread_rng, Rng};
108
113
  use sha2::{Digest, Sha256};
114
+ use std::fs;
115
+ use std::io::Write;
109
116
 
110
117
  use super::*;
111
118
  use crate::testhelper::TestFile;
@@ -165,7 +172,7 @@ mod test {
165
172
 
166
173
  let mut info = FileInfo {
167
174
  file,
168
- path,
175
+ path: path.clone(),
169
176
  len: buf.len(),
170
177
  multiprocess_mode: Symbol::new("puma"),
171
178
  type_: Symbol::new("max"),
@@ -187,4 +194,47 @@ mod test {
187
194
 
188
195
  assert_eq!(in_hash, out_hash, "content hashes");
189
196
  }
197
+
198
+ #[test]
199
+ fn test_read_from_file_resized() {
200
+ let _cleanup = unsafe { magnus::embed::init() };
201
+ let ruby = magnus::Ruby::get().unwrap();
202
+ crate::init(&ruby).unwrap();
203
+
204
+ const BUF_LEN: usize = 1 << 14; // 16KiB
205
+
206
+ // Create a buffer with random data.
207
+ let mut buf = vec![0u8; BUF_LEN];
208
+ thread_rng().fill(buf.as_mut_slice());
209
+
210
+ let TestFile {
211
+ file,
212
+ path,
213
+ dir: _dir,
214
+ } = TestFile::new(&buf);
215
+
216
+ let mut info = FileInfo {
217
+ file,
218
+ path: path.clone(),
219
+ len: buf.len(),
220
+ multiprocess_mode: Symbol::new("puma"),
221
+ type_: Symbol::new("max"),
222
+ pid: "worker-0_0".to_string(),
223
+ };
224
+
225
+ let mut resized_file = fs::OpenOptions::new()
226
+ .write(true)
227
+ .append(true)
228
+ .open(path)
229
+ .unwrap();
230
+
231
+ // Write data to file after it has been `stat`ed in the
232
+ // constructor.
233
+ resized_file.write_all(&[1; 1024]).unwrap();
234
+
235
+ let mut out_buf = Vec::new();
236
+ info.read_from_file(&mut out_buf).unwrap();
237
+
238
+ assert_eq!(BUF_LEN + 1024, info.len, "resized file updated len");
239
+ }
190
240
  }
@@ -224,16 +224,6 @@ impl InnerMmap {
224
224
  }
225
225
  }
226
226
 
227
- /// Truncate the mmapped file to the end of the metrics data.
228
- pub fn truncate_file(&mut self) -> Result<()> {
229
- // CAST: no-op on 64-bit, widening on 32-bit.
230
- let trunc_len = self.len as u64;
231
-
232
- self.file
233
- .set_len(trunc_len)
234
- .map_err(|e| MmapError::legacy(format!("truncate: {e}"), RubyError::Type))
235
- }
236
-
237
227
  /// Load the `used` header containing the size of the metrics data written.
238
228
  pub fn load_used(&self) -> Result<u32> {
239
229
  match read_u32(self.map.as_ref(), 0) {
@@ -225,9 +225,6 @@ impl MmapedFile {
225
225
  let rs_self = &*rb_self;
226
226
 
227
227
  rs_self.inner_mut(|inner| {
228
- // truncate file to actual used size
229
- inner.truncate_file()?;
230
-
231
228
  // We are about to release the backing mmap for Ruby's String
232
229
  // objects. If Ruby attempts to read from them the program will
233
230
  // segfault. We update the length of all Strings to zero so Ruby
@@ -507,14 +504,14 @@ impl MmapedFile {
507
504
  match file.seek(SeekFrom::Start(len - 1)) {
508
505
  Ok(_) => {}
509
506
  Err(_) => {
510
- return Err(MmapError::WithErrno(format!("Can't lseek {}", len - 1)));
507
+ return Err(MmapError::with_errno(format!("Can't lseek {}", len - 1)));
511
508
  }
512
509
  }
513
510
 
514
511
  match file.write(&[0x0]) {
515
512
  Ok(1) => {}
516
513
  _ => {
517
- return Err(MmapError::WithErrno(format!(
514
+ return Err(MmapError::with_errno(format!(
518
515
  "Can't extend {}",
519
516
  path.display()
520
517
  )));
@@ -7,14 +7,13 @@ require 'tmpdir'
7
7
  module Prometheus
8
8
  module Client
9
9
  class Configuration
10
- attr_accessor :value_class, :multiprocess_files_dir, :initial_mmap_file_size, :logger, :pid_provider, :rust_multiprocess_metrics
10
+ attr_accessor :value_class, :multiprocess_files_dir, :initial_mmap_file_size, :logger, :pid_provider
11
11
 
12
12
  def initialize
13
13
  @value_class = ::Prometheus::Client::MmapedValue
14
14
  @initial_mmap_file_size = ::Prometheus::Client::PageSize.page_size(fallback_page_size: 4096)
15
15
  @logger = Logger.new($stdout)
16
16
  @pid_provider = Process.method(:pid)
17
- @rust_multiprocess_metrics = ENV.fetch('prometheus_rust_multiprocess_metrics', nil) == 'true'
18
17
  @multiprocess_files_dir = ENV.fetch('prometheus_multiproc_dir') do
19
18
  Dir.mktmpdir("prometheus-mmap")
20
19
  end
@@ -1,6 +1,5 @@
1
1
  require 'prometheus/client/uses_value_type'
2
2
  require 'prometheus/client/helper/json_parser'
3
- require 'prometheus/client/helper/loader'
4
3
  require 'prometheus/client/helper/plain_file'
5
4
  require 'prometheus/client/helper/metrics_processing'
6
5
  require 'prometheus/client/helper/metrics_representation'
@@ -27,22 +26,12 @@ module Prometheus
27
26
  Helper::MetricsRepresentation.to_text(metrics)
28
27
  end
29
28
 
30
- def marshal_multiprocess(path = Prometheus::Client.configuration.multiprocess_files_dir, use_rust: false)
29
+ def marshal_multiprocess(path = Prometheus::Client.configuration.multiprocess_files_dir)
31
30
  file_list = Dir.glob(File.join(path, '*.db')).sort
32
31
  .map {|f| Helper::PlainFile.new(f) }
33
32
  .map {|f| [f.filepath, f.multiprocess_mode.to_sym, f.type.to_sym, f.pid] }
34
33
 
35
- if use_rust && Prometheus::Client::Helper::Loader.rust_impl_available?
36
34
  FastMmapedFileRs.to_metrics(file_list.to_a)
37
- else
38
- FastMmapedFile.to_metrics(file_list.to_a)
39
- end
40
- end
41
-
42
- def rust_impl_available?
43
- return @rust_available unless @rust_available.nil?
44
-
45
- check_for_rust
46
35
  end
47
36
 
48
37
  private
@@ -1,29 +1,18 @@
1
1
  require 'prometheus/client/helper/entry_parser'
2
2
  require 'prometheus/client/helper/file_locker'
3
- require 'prometheus/client/helper/loader'
4
3
 
5
4
  # load precompiled extension if available
6
5
  begin
7
6
  ruby_version = /(\d+\.\d+)/.match(RUBY_VERSION)
8
- require_relative "../../../#{ruby_version}/fast_mmaped_file"
7
+ require_relative "../../../#{ruby_version}/fast_mmaped_file_rs"
9
8
  rescue LoadError
10
- require 'fast_mmaped_file'
9
+ require 'fast_mmaped_file_rs'
11
10
  end
12
11
 
13
12
  module Prometheus
14
13
  module Client
15
14
  module Helper
16
- # We can't check `Prometheus::Client.configuration` as this creates a circular dependency
17
- if (ENV.fetch('prometheus_rust_mmaped_file', nil) == "true" &&
18
- Prometheus::Client::Helper::Loader.rust_impl_available?)
19
- class MmapedFile < FastMmapedFileRs
20
- end
21
- else
22
- class MmapedFile < FastMmapedFile
23
- end
24
- end
25
-
26
- class MmapedFile
15
+ class MmapedFile < FastMmapedFileRs
27
16
  include EntryParser
28
17
 
29
18
  attr_reader :filepath, :size
@@ -5,8 +5,7 @@ module Prometheus
5
5
  # LabelSetValidator ensures that all used label sets comply with the
6
6
  # Prometheus specification.
7
7
  class LabelSetValidator
8
- # TODO: we might allow setting :instance in the future
9
- RESERVED_LABELS = [:job, :instance].freeze
8
+ RESERVED_LABELS = [].freeze
10
9
 
11
10
  class LabelSetError < StandardError; end
12
11
  class InvalidLabelSetError < LabelSetError; end
@@ -62,10 +62,8 @@ module Prometheus
62
62
  end
63
63
 
64
64
  def respond_with(format)
65
- rust_enabled = Prometheus::Client.configuration.rust_multiprocess_metrics
66
-
67
65
  response = if Prometheus::Client.configuration.value_class.multiprocess
68
- format.marshal_multiprocess(use_rust: rust_enabled)
66
+ format.marshal_multiprocess
69
67
  else
70
68
  format.marshal
71
69
  end
@@ -0,0 +1,44 @@
1
+ module Prometheus
2
+ module Client
3
+ module Support
4
+ module Puma
5
+ extend self
6
+
7
+ def worker_pid_provider
8
+ wid = worker_id
9
+ if wid = worker_id
10
+ wid
11
+ else
12
+ "process_id_#{Process.pid}"
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def object_based_worker_id
19
+ return unless defined?(::Puma::Cluster::Worker)
20
+
21
+ workers = ObjectSpace.each_object(::Puma::Cluster::Worker)
22
+ return if workers.nil?
23
+
24
+ workers_first = workers.first
25
+ workers_first.index unless workers_first.nil?
26
+ end
27
+
28
+ def program_name
29
+ $PROGRAM_NAME
30
+ end
31
+
32
+ def worker_id
33
+ if matchdata = program_name.match(/puma.*cluster worker ([0-9]+):/)
34
+ "puma_#{matchdata[1]}"
35
+ elsif object_worker_id = object_based_worker_id
36
+ "puma_#{object_worker_id}"
37
+ elsif program_name.include?('puma')
38
+ 'puma_master'
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,5 +1,5 @@
1
1
  module Prometheus
2
2
  module Client
3
- VERSION = '0.25.0'.freeze
3
+ VERSION = '1.1.1'.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.25.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Schmidt
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2023-06-15 00:00:00.000000000 Z
14
+ date: 2024-01-30 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rb_sys
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - "~>"
21
21
  - !ruby/object:Gem::Version
22
- version: '0.9'
22
+ version: 0.9.86
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '0.9'
29
+ version: 0.9.86
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: fuzzbert
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -95,14 +95,14 @@ dependencies:
95
95
  requirements:
96
96
  - - "~>"
97
97
  - !ruby/object:Gem::Version
98
- version: 1.3.0
98
+ version: 1.4.0
99
99
  type: :development
100
100
  prerelease: false
101
101
  version_requirements: !ruby/object:Gem::Requirement
102
102
  requirements:
103
103
  - - "~>"
104
104
  - !ruby/object:Gem::Version
105
- version: 1.3.0
105
+ version: 1.4.0
106
106
  - !ruby/object:Gem::Dependency
107
107
  name: ruby-prof
108
108
  requirement: !ruby/object:Gem::Requirement
@@ -125,29 +125,11 @@ email:
125
125
  - wchandler@gitlab.com
126
126
  executables: []
127
127
  extensions:
128
- - ext/fast_mmaped_file/extconf.rb
129
128
  - ext/fast_mmaped_file_rs/extconf.rb
130
129
  extra_rdoc_files: []
131
130
  files:
132
131
  - ".tool-versions"
133
132
  - README.md
134
- - ext/fast_mmaped_file/extconf.rb
135
- - ext/fast_mmaped_file/fast_mmaped_file.c
136
- - ext/fast_mmaped_file/file_format.c
137
- - ext/fast_mmaped_file/file_format.h
138
- - ext/fast_mmaped_file/file_parsing.c
139
- - ext/fast_mmaped_file/file_parsing.h
140
- - ext/fast_mmaped_file/file_reading.c
141
- - ext/fast_mmaped_file/file_reading.h
142
- - ext/fast_mmaped_file/globals.h
143
- - ext/fast_mmaped_file/mmap.c
144
- - ext/fast_mmaped_file/mmap.h
145
- - ext/fast_mmaped_file/rendering.c
146
- - ext/fast_mmaped_file/rendering.h
147
- - ext/fast_mmaped_file/utils.c
148
- - ext/fast_mmaped_file/utils.h
149
- - ext/fast_mmaped_file/value_access.c
150
- - ext/fast_mmaped_file/value_access.h
151
133
  - ext/fast_mmaped_file_rs/.cargo/config.toml
152
134
  - ext/fast_mmaped_file_rs/Cargo.lock
153
135
  - ext/fast_mmaped_file_rs/Cargo.toml
@@ -174,7 +156,6 @@ files:
174
156
  - lib/prometheus/client/helper/entry_parser.rb
175
157
  - lib/prometheus/client/helper/file_locker.rb
176
158
  - lib/prometheus/client/helper/json_parser.rb
177
- - lib/prometheus/client/helper/loader.rb
178
159
  - lib/prometheus/client/helper/metrics_processing.rb
179
160
  - lib/prometheus/client/helper/metrics_representation.rb
180
161
  - lib/prometheus/client/helper/mmaped_file.rb
@@ -191,29 +172,10 @@ files:
191
172
  - lib/prometheus/client/registry.rb
192
173
  - lib/prometheus/client/simple_value.rb
193
174
  - lib/prometheus/client/summary.rb
175
+ - lib/prometheus/client/support/puma.rb
194
176
  - lib/prometheus/client/support/unicorn.rb
195
177
  - lib/prometheus/client/uses_value_type.rb
196
178
  - lib/prometheus/client/version.rb
197
- - vendor/c/hashmap/.gitignore
198
- - vendor/c/hashmap/LICENSE
199
- - vendor/c/hashmap/README.md
200
- - vendor/c/hashmap/_config.yml
201
- - vendor/c/hashmap/src/hashmap.c
202
- - vendor/c/hashmap/src/hashmap.h
203
- - vendor/c/hashmap/test/Makefile
204
- - vendor/c/hashmap/test/hashmap_test.c
205
- - vendor/c/jsmn/.travis.yml
206
- - vendor/c/jsmn/LICENSE
207
- - vendor/c/jsmn/Makefile
208
- - vendor/c/jsmn/README.md
209
- - vendor/c/jsmn/example/jsondump.c
210
- - vendor/c/jsmn/example/simple.c
211
- - vendor/c/jsmn/jsmn.c
212
- - vendor/c/jsmn/jsmn.h
213
- - vendor/c/jsmn/library.json
214
- - vendor/c/jsmn/test/test.h
215
- - vendor/c/jsmn/test/tests.c
216
- - vendor/c/jsmn/test/testutil.h
217
179
  homepage: https://gitlab.com/gitlab-org/prometheus-client-mmap
218
180
  licenses:
219
181
  - Apache-2.0
@@ -236,6 +198,6 @@ requirements: []
236
198
  rubygems_version: 3.3.26
237
199
  signing_key:
238
200
  specification_version: 4
239
- summary: A suite of instrumentation metric primitivesthat can be exposed through a
240
- web services interface.
201
+ summary: A suite of instrumentation metric primitives that can be exposed through
202
+ a web services interface.
241
203
  test_files: []
@@ -1,30 +0,0 @@
1
- require 'mkmf'
2
- require 'fileutils'
3
-
4
- $CFLAGS << ' -std=c99 -D_POSIX_C_SOURCE=200809L -Wall -Wextra'
5
-
6
- if enable_config('fail-on-warning')
7
- $CFLAGS << ' -Werror'
8
- end
9
-
10
- if enable_config('debug')
11
- $CFLAGS << ' -O0 -g'
12
- end
13
-
14
- if enable_config('address-sanitizer')
15
- $CFLAGS << ' -O -fsanitize=address -fno-omit-frame-pointer -g'
16
- end
17
-
18
- CONFIG['warnflags'].slice!(/ -Wdeclaration-after-statement/)
19
-
20
- cwd = File.expand_path(File.dirname(__FILE__))
21
- vendor_dir = File.join(cwd, '../../vendor/c')
22
- src_dir = File.join(cwd, '../../ext/fast_mmaped_file')
23
-
24
- src_files = %W[#{vendor_dir}/jsmn/jsmn.c #{vendor_dir}/hashmap/src/hashmap.c]
25
- FileUtils.cp(src_files, src_dir)
26
-
27
- $INCFLAGS << " -I#{vendor_dir}/jsmn -I#{vendor_dir}/hashmap/src"
28
-
29
- dir_config('fast_mmaped_file')
30
- create_makefile('fast_mmaped_file')
@@ -1,122 +0,0 @@
1
- #include <errno.h>
2
- #include <hashmap.h>
3
- #include <jsmn.h>
4
- #include <ruby.h>
5
- #include <ruby/intern.h>
6
- #include <sys/mman.h>
7
-
8
- #include "file_parsing.h"
9
- #include "file_reading.h"
10
- #include "globals.h"
11
- #include "mmap.h"
12
- #include "rendering.h"
13
- #include "utils.h"
14
- #include "value_access.h"
15
-
16
- VALUE MMAPED_FILE = Qnil;
17
-
18
- ID sym_min;
19
- ID sym_max;
20
- ID sym_livesum;
21
- ID sym_gauge;
22
- ID sym_pid;
23
- ID sym_samples;
24
-
25
- VALUE prom_eParsingError;
26
-
27
- int aggregate_files(struct hashmap *map, VALUE list_of_files) {
28
- buffer_t reading_buffer;
29
- memset(&reading_buffer, 0, sizeof(buffer_t));
30
-
31
- for (int i = 0; i < RARRAY_LEN(list_of_files); i++) {
32
- VALUE params = RARRAY_PTR(list_of_files)[i];
33
- file_t file;
34
-
35
- if (!file_open_from_params(&file, params)) {
36
- buffer_dispose(&reading_buffer);
37
- return 0;
38
- }
39
-
40
- if (!read_from_file(&file, &reading_buffer)) {
41
- buffer_dispose(&reading_buffer);
42
- file_close(&file);
43
- return 0;
44
- }
45
-
46
- if (!process_buffer(&file, &reading_buffer, map)) {
47
- buffer_dispose(&reading_buffer);
48
- file_close(&file);
49
- return 0;
50
- }
51
-
52
- if (!file_close(&file)) {
53
- buffer_dispose(&reading_buffer);
54
- return 0;
55
- }
56
- }
57
-
58
- buffer_dispose(&reading_buffer);
59
- return 1;
60
- }
61
-
62
- VALUE method_to_metrics(VALUE UNUSED(self), VALUE file_list) {
63
- struct hashmap map;
64
- hashmap_setup(&map);
65
-
66
- if (!aggregate_files(&map, file_list)) { // all entries in map are now copies that need to be disposed
67
- hashmap_destroy(&map);
68
- raise_last_exception();
69
- return Qnil;
70
- }
71
-
72
- entry_t **sorted_entries;
73
-
74
- if (!sort_map_entries(&map, &sorted_entries)) {
75
- hashmap_destroy(&map);
76
-
77
- raise_last_exception();
78
- return Qnil;
79
- }
80
-
81
- VALUE rv = rb_str_new("", 0);
82
- if (!entries_to_string(rv, sorted_entries, hashmap_size(&map))) {
83
- free(sorted_entries);
84
- hashmap_destroy(&map);
85
-
86
- raise_last_exception();
87
- return Qnil;
88
- }
89
-
90
- RB_GC_GUARD(file_list); // ensure file list is not GCed before this point
91
- free(sorted_entries);
92
- hashmap_destroy(&map);
93
- return rv;
94
- }
95
-
96
- void Init_fast_mmaped_file() {
97
- sym_gauge = rb_intern("gauge");
98
- sym_min = rb_intern("min");
99
- sym_max = rb_intern("max");
100
- sym_livesum = rb_intern("livesum");
101
- sym_pid = rb_intern("pid");
102
- sym_samples = rb_intern("samples");
103
-
104
- prom_eParsingError = rb_define_class("PrometheusParsingError", rb_eRuntimeError);
105
-
106
- MMAPED_FILE = rb_define_class("FastMmapedFile", rb_cObject);
107
- rb_define_const(MMAPED_FILE, "MAP_SHARED", INT2FIX(MAP_SHARED));
108
-
109
- rb_define_singleton_method(MMAPED_FILE, "to_metrics", method_to_metrics, 1);
110
-
111
- rb_define_alloc_func(MMAPED_FILE, mm_s_alloc);
112
- rb_define_singleton_method(MMAPED_FILE, "new", mm_s_new, -1);
113
- rb_define_method(MMAPED_FILE, "initialize", mm_init, 1);
114
- rb_define_method(MMAPED_FILE, "slice", mm_aref_m, -1);
115
- rb_define_method(MMAPED_FILE, "sync", mm_msync, -1);
116
- rb_define_method(MMAPED_FILE, "munmap", mm_unmap, 0);
117
-
118
- rb_define_method(MMAPED_FILE, "used", method_load_used, 0);
119
- rb_define_method(MMAPED_FILE, "used=", method_save_used, 1);
120
- rb_define_method(MMAPED_FILE, "fetch_entry", method_fetch_entry, 3);
121
- rb_define_method(MMAPED_FILE, "upsert_entry", method_upsert_entry, 3);
122
- }
@@ -1,5 +0,0 @@
1
- #include "file_format.h"
2
-
3
- inline uint32_t padding_length(uint32_t key_length) {
4
- return 8 - (sizeof(uint32_t) + key_length) % 8; // padding | 8 byte aligned
5
- }
@@ -1,11 +0,0 @@
1
- #ifndef FILE_FORMAT_H
2
- #define FILE_FORMAT_H
3
-
4
- #include <stdint.h>
5
-
6
- #define START_POSITION 8
7
- #define INITIAL_SIZE (2 * sizeof(int32_t))
8
-
9
- uint32_t padding_length(uint32_t key_length);
10
-
11
- #endif