prometheus-client-mmap 0.28.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.tool-versions +1 -1
- data/README.md +2 -30
- data/ext/fast_mmaped_file_rs/extconf.rb +1 -3
- data/ext/fast_mmaped_file_rs/src/error.rs +8 -0
- data/ext/fast_mmaped_file_rs/src/mmap/inner.rs +38 -13
- data/ext/fast_mmaped_file_rs/src/mmap.rs +71 -5
- data/lib/prometheus/client/configuration.rb +1 -2
- data/lib/prometheus/client/formats/text.rb +1 -12
- data/lib/prometheus/client/helper/mmaped_file.rb +3 -14
- data/lib/prometheus/client/rack/exporter.rb +1 -3
- data/lib/prometheus/client/version.rb +1 -1
- metadata +4 -43
- data/ext/fast_mmaped_file/extconf.rb +0 -30
- data/ext/fast_mmaped_file/fast_mmaped_file.c +0 -122
- data/ext/fast_mmaped_file/file_format.c +0 -5
- data/ext/fast_mmaped_file/file_format.h +0 -11
- data/ext/fast_mmaped_file/file_parsing.c +0 -195
- data/ext/fast_mmaped_file/file_parsing.h +0 -27
- data/ext/fast_mmaped_file/file_reading.c +0 -102
- data/ext/fast_mmaped_file/file_reading.h +0 -30
- data/ext/fast_mmaped_file/globals.h +0 -14
- data/ext/fast_mmaped_file/mmap.c +0 -428
- data/ext/fast_mmaped_file/mmap.h +0 -61
- data/ext/fast_mmaped_file/rendering.c +0 -199
- data/ext/fast_mmaped_file/rendering.h +0 -8
- data/ext/fast_mmaped_file/utils.c +0 -56
- data/ext/fast_mmaped_file/utils.h +0 -22
- data/ext/fast_mmaped_file/value_access.c +0 -242
- data/ext/fast_mmaped_file/value_access.h +0 -15
- data/lib/prometheus/client/helper/loader.rb +0 -44
- data/vendor/c/hashmap/.gitignore +0 -52
- data/vendor/c/hashmap/LICENSE +0 -21
- data/vendor/c/hashmap/README.md +0 -90
- data/vendor/c/hashmap/_config.yml +0 -1
- data/vendor/c/hashmap/src/hashmap.c +0 -692
- data/vendor/c/hashmap/src/hashmap.h +0 -267
- data/vendor/c/hashmap/test/Makefile +0 -22
- data/vendor/c/hashmap/test/hashmap_test.c +0 -608
- data/vendor/c/jsmn/.travis.yml +0 -4
- data/vendor/c/jsmn/LICENSE +0 -20
- data/vendor/c/jsmn/Makefile +0 -41
- data/vendor/c/jsmn/README.md +0 -168
- data/vendor/c/jsmn/example/jsondump.c +0 -126
- data/vendor/c/jsmn/example/simple.c +0 -76
- data/vendor/c/jsmn/jsmn.c +0 -314
- data/vendor/c/jsmn/jsmn.h +0 -76
- data/vendor/c/jsmn/library.json +0 -16
- data/vendor/c/jsmn/test/test.h +0 -27
- data/vendor/c/jsmn/test/tests.c +0 -407
- data/vendor/c/jsmn/test/testutil.h +0 -94
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97fc31e7c9aad5a4b25d1d02cc7aa5b44f2a74d05a80776aa6d9f961b51a3631
|
4
|
+
data.tar.gz: '010394948353bb52e8aa4cd12dd45f22d3026099ae05b6d600905872ac094fc2'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fcd7c42ca842979e64b2e510f18cd9113ace7ab6d68a1f017555defd16940a52aac7a081d86a50654045229f098db2bc53de38e7a47e63edab8ed049b1e32629
|
7
|
+
data.tar.gz: b2f6438a636775e0bf902f244fcd58b0c97fbe3f1f46edf593a5838f0db9c35219de452322cf03b627e2053bbc72b81e2ff98ac7f1f2bbdb20e26c53bdce79df
|
data/.tool-versions
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rust 1.
|
1
|
+
rust 1.73.0
|
data/README.md
CHANGED
@@ -53,19 +53,9 @@ http_requests.increment
|
|
53
53
|
|
54
54
|
## Rust extension
|
55
55
|
|
56
|
-
|
56
|
+
This gem now uses a rewritten Rust extension instead of C.
|
57
57
|
implementation that reads the metric files and outputs the multiprocess
|
58
|
-
metrics to text.
|
59
|
-
be built automatically. The `use_rust` keyword argument can be used:
|
60
|
-
|
61
|
-
```ruby
|
62
|
-
puts Prometheus::Client::Formats::Text.marshal_multiprocess(use_rust: true)
|
63
|
-
```
|
64
|
-
|
65
|
-
Starting with v0.26.0, `use_rust` defaults to `true`.
|
66
|
-
|
67
|
-
Note that this parameter will likely be deprecated and removed once the Rust
|
68
|
-
extension becomes the only supported mode.
|
58
|
+
metrics to text. This implementation is significantly faster than the C extension.
|
69
59
|
|
70
60
|
### Rack middleware
|
71
61
|
|
@@ -219,24 +209,6 @@ Set `prometheus_multiproc_dir` environment variable to the path where you want m
|
|
219
209
|
prometheus_multiproc_dir=/tmp
|
220
210
|
```
|
221
211
|
|
222
|
-
### Multiprocess metrics via Rust extension
|
223
|
-
|
224
|
-
By default, the Rust extension will be used to read and write multiprocess
|
225
|
-
metrics if the `fast_mmaped_file_rs` extension is available. This should
|
226
|
-
be significantly faster than the C extension.
|
227
|
-
|
228
|
-
If the environment variable `prometheus_rust_multiprocess_metrics=false`
|
229
|
-
is set or if the `rust_multiprocess_metrics` configuration setting is
|
230
|
-
`false` , the C extension will be used.
|
231
|
-
|
232
|
-
### Read and write metrics via Rust extension
|
233
|
-
|
234
|
-
By default, the Rust extension will be used to read and write metrics
|
235
|
-
from the mmaped file if the `fast_mmaped_file_rs` extension is available.
|
236
|
-
|
237
|
-
To use the C extension, set the environment variable
|
238
|
-
`prometheus_rust_mmaped_file=false`.
|
239
|
-
|
240
212
|
## Pitfalls
|
241
213
|
|
242
214
|
### PID cardinality
|
@@ -100,6 +100,13 @@ pub enum MmapError {
|
|
100
100
|
/// No mmap open.
|
101
101
|
#[error("unmapped file")]
|
102
102
|
UnmappedFile,
|
103
|
+
/// File length changed by another process.
|
104
|
+
#[error("size of {path} {len} does not match previous size {expected_len}. Another process may have modified it.")]
|
105
|
+
UnexpectedFileLength {
|
106
|
+
path: String,
|
107
|
+
len: usize,
|
108
|
+
expected_len: usize,
|
109
|
+
},
|
103
110
|
/// A custom error message with `strerror(3)` appended.
|
104
111
|
#[error("{0}")]
|
105
112
|
WithErrno(String),
|
@@ -162,6 +169,7 @@ impl MmapError {
|
|
162
169
|
MmapError::Other(_) => RubyError::Arg,
|
163
170
|
MmapError::PromParsing(_) => RubyError::PromParsing,
|
164
171
|
MmapError::UnmappedFile => RubyError::Io,
|
172
|
+
MmapError::UnexpectedFileLength { .. } => RubyError::Runtime,
|
165
173
|
MmapError::WithErrno(_) => RubyError::Io,
|
166
174
|
}
|
167
175
|
}
|
@@ -5,7 +5,7 @@ use std::fs::File;
|
|
5
5
|
use std::mem::size_of;
|
6
6
|
use std::ops::Range;
|
7
7
|
use std::os::unix::prelude::{AsRawFd, RawFd};
|
8
|
-
use std::path::PathBuf;
|
8
|
+
use std::path::{Path, PathBuf};
|
9
9
|
|
10
10
|
use crate::error::{MmapError, RubyError};
|
11
11
|
use crate::raw_entry::RawEntry;
|
@@ -34,6 +34,8 @@ pub(super) struct InnerMmap {
|
|
34
34
|
///
|
35
35
|
/// Equivalent to `i_mm->t->real` in the C implementation.
|
36
36
|
len: usize,
|
37
|
+
/// The length of the file being mmapped at the time of mapping.
|
38
|
+
file_len: usize,
|
37
39
|
}
|
38
40
|
|
39
41
|
impl InnerMmap {
|
@@ -41,19 +43,12 @@ impl InnerMmap {
|
|
41
43
|
/// Use when mmapping a file for the first time. When re-mapping a file
|
42
44
|
/// after expanding it the `reestablish` function should be used.
|
43
45
|
pub fn new(path: PathBuf, file: File) -> Result<Self> {
|
44
|
-
let
|
45
|
-
MmapError::legacy(
|
46
|
-
format!("Can't stat {}: {e}", path.display()),
|
47
|
-
RubyError::Arg,
|
48
|
-
)
|
49
|
-
})?;
|
50
|
-
|
51
|
-
let file_size = util::cast_chk::<_, usize>(stat.len(), "file length")?;
|
46
|
+
let initial_file_len = get_file_len(&path, &file)?;
|
52
47
|
|
53
48
|
// We need to ensure the underlying file descriptor is at least a page size.
|
54
49
|
// Otherwise, we could get a SIGBUS error if mmap() attempts to read or write
|
55
50
|
// past the file.
|
56
|
-
let reserve_size = Self::next_page_boundary(
|
51
|
+
let reserve_size = Self::next_page_boundary(initial_file_len)?;
|
57
52
|
|
58
53
|
// Cast: no-op.
|
59
54
|
Self::reserve_mmap_file_bytes(file.as_raw_fd(), reserve_size as off_t).map_err(|e| {
|
@@ -67,21 +62,23 @@ impl InnerMmap {
|
|
67
62
|
})?;
|
68
63
|
|
69
64
|
// Ensure we always have space for the header.
|
70
|
-
let map_len =
|
65
|
+
let map_len = initial_file_len.max(HEADER_SIZE);
|
71
66
|
|
72
67
|
// SAFETY: There is the possibility of UB if the file is modified outside of
|
73
68
|
// this program.
|
74
69
|
let map = unsafe { MmapOptions::new().len(map_len).map_mut(&file) }.map_err(|e| {
|
75
70
|
MmapError::legacy(format!("mmap failed ({}): {e}", errno()), RubyError::Arg)
|
76
71
|
})?;
|
72
|
+
let file_len = util::cast_chk::<_, usize>(reserve_size, "file length")?;
|
77
73
|
|
78
|
-
let len =
|
74
|
+
let len = initial_file_len;
|
79
75
|
|
80
76
|
Ok(Self {
|
81
77
|
file,
|
82
78
|
path,
|
83
79
|
map,
|
84
80
|
len,
|
81
|
+
file_len,
|
85
82
|
})
|
86
83
|
}
|
87
84
|
|
@@ -97,12 +94,14 @@ impl InnerMmap {
|
|
97
94
|
// to the old length at this point if closing the file. Matching C implementation
|
98
95
|
// for now.
|
99
96
|
let len = map_len;
|
97
|
+
let file_len = get_file_len(&path, &file)?;
|
100
98
|
|
101
99
|
Ok(Self {
|
102
100
|
file,
|
103
101
|
path,
|
104
102
|
map,
|
105
103
|
len,
|
104
|
+
file_len,
|
106
105
|
})
|
107
106
|
}
|
108
107
|
|
@@ -186,7 +185,7 @@ impl InnerMmap {
|
|
186
185
|
self.len
|
187
186
|
}
|
188
187
|
|
189
|
-
/// The total length in bytes of the mmapped file.
|
188
|
+
/// The total length in bytes of the mmapped region of the file.
|
190
189
|
///
|
191
190
|
/// Equivalent to `i_mm->t->len` in the C implementation.
|
192
191
|
#[inline]
|
@@ -194,6 +193,21 @@ impl InnerMmap {
|
|
194
193
|
self.map.len()
|
195
194
|
}
|
196
195
|
|
196
|
+
/// `stat` the mmapped file and return its length.
|
197
|
+
pub fn check_file_len(&self) -> Result<usize> {
|
198
|
+
get_file_len(&self.path, &self.file)
|
199
|
+
}
|
200
|
+
|
201
|
+
/// The length of the file at the time it was mmapped.
|
202
|
+
pub fn file_len(&self) -> usize {
|
203
|
+
self.file_len
|
204
|
+
}
|
205
|
+
|
206
|
+
/// The path of the mmapped file.
|
207
|
+
pub fn path(&self) -> String {
|
208
|
+
self.path.to_string_lossy().to_string()
|
209
|
+
}
|
210
|
+
|
197
211
|
/// Update the length of the mmap considered to be written.
|
198
212
|
pub fn set_len(&mut self, len: usize) {
|
199
213
|
self.len = len;
|
@@ -312,6 +326,17 @@ impl InnerMmap {
|
|
312
326
|
}
|
313
327
|
}
|
314
328
|
|
329
|
+
fn get_file_len(path: &Path, file: &File) -> Result<usize> {
|
330
|
+
let stat = file.metadata().map_err(|e| {
|
331
|
+
MmapError::legacy(
|
332
|
+
format!("Can't stat {}: {e}", path.display()),
|
333
|
+
RubyError::Arg,
|
334
|
+
)
|
335
|
+
})?;
|
336
|
+
|
337
|
+
util::cast_chk::<_, usize>(stat.len(), "file length")
|
338
|
+
}
|
339
|
+
|
315
340
|
#[cfg(test)]
|
316
341
|
mod test {
|
317
342
|
use nix::unistd::{self, SysconfVar};
|
@@ -441,17 +441,49 @@ impl MmapedFile {
|
|
441
441
|
}
|
442
442
|
|
443
443
|
/// Check that the mmap is large enough to contain the value to be added,
|
444
|
-
/// and expand it to fit if necessary.
|
444
|
+
/// and expand it to fit if necessary. Will return an error if the file
|
445
|
+
/// has been resized by another process.
|
445
446
|
fn check_expand(&self, rb_self: Obj<Self>, key_len: usize) -> magnus::error::Result<()> {
|
446
447
|
// CAST: no-op on 32-bit, widening on 64-bit.
|
447
448
|
let used = self.inner(|inner| inner.load_used())? as usize;
|
448
449
|
let entry_len = RawEntry::calc_total_len(key_len)?;
|
450
|
+
let required_len = used.add_chk(entry_len)?;
|
451
|
+
let mut target_cap = self.capacity();
|
449
452
|
|
453
|
+
let mut needs_resize = false;
|
450
454
|
// We need the mmapped region to contain at least one byte beyond the
|
451
|
-
// written data to create a NUL-
|
452
|
-
// new length does not exactly match
|
453
|
-
|
454
|
-
|
455
|
+
// written data to create a NUL-terminated C string. Validate that
|
456
|
+
// new length does not exactly match the length of the mmap.
|
457
|
+
if target_cap <= required_len {
|
458
|
+
needs_resize = true;
|
459
|
+
target_cap = required_len + 1;
|
460
|
+
}
|
461
|
+
|
462
|
+
let (current_file_len, original_file_len) =
|
463
|
+
self.inner(|inner| Ok((inner.check_file_len()?, inner.file_len())))?;
|
464
|
+
|
465
|
+
let file_modified = current_file_len != original_file_len;
|
466
|
+
if file_modified {
|
467
|
+
// Ensure our new capacity is at least as large as the actual file.
|
468
|
+
// Erroring out without first resizing the mmap would leave us stuck
|
469
|
+
// in a bad state.
|
470
|
+
target_cap = current_file_len
|
471
|
+
}
|
472
|
+
|
473
|
+
if needs_resize {
|
474
|
+
self.expand_to_fit(rb_self, target_cap)?;
|
475
|
+
}
|
476
|
+
|
477
|
+
if file_modified {
|
478
|
+
// Return an error so the caller is alerted that there were concurrent writes to the
|
479
|
+
// file.
|
480
|
+
let path = self.inner(|inner| Ok(inner.path()))?;
|
481
|
+
return Err(MmapError::UnexpectedFileLength {
|
482
|
+
path,
|
483
|
+
len: current_file_len,
|
484
|
+
expected_len: original_file_len,
|
485
|
+
}
|
486
|
+
.into());
|
455
487
|
}
|
456
488
|
|
457
489
|
Ok(())
|
@@ -652,6 +684,7 @@ mod test {
|
|
652
684
|
use super::*;
|
653
685
|
use crate::raw_entry::RawEntry;
|
654
686
|
use crate::testhelper::TestFile;
|
687
|
+
use std::os::unix::prelude::AsRawFd;
|
655
688
|
|
656
689
|
/// Create a wrapped MmapedFile object.
|
657
690
|
fn create_obj() -> Obj<MmapedFile> {
|
@@ -881,4 +914,37 @@ mod test {
|
|
881
914
|
// Validate that we have expanded the mmap, ensuring a trailing NUL.
|
882
915
|
assert!(rs_self.capacity() > current_cap);
|
883
916
|
}
|
917
|
+
|
918
|
+
#[test]
|
919
|
+
fn test_detect_external_resize() {
|
920
|
+
let _cleanup = unsafe { magnus::embed::init() };
|
921
|
+
let ruby = magnus::Ruby::get().unwrap();
|
922
|
+
crate::init(&ruby).unwrap();
|
923
|
+
|
924
|
+
let TestFile {
|
925
|
+
file,
|
926
|
+
path,
|
927
|
+
dir: _dir,
|
928
|
+
} = TestFile::new(&[0u8; 8]);
|
929
|
+
|
930
|
+
let path_str = path.display().to_string();
|
931
|
+
let rpath = RString::new(&path_str);
|
932
|
+
|
933
|
+
// Object created successfully
|
934
|
+
let result: std::result::Result<Obj<MmapedFile>, Error> =
|
935
|
+
eval!("FastMmapedFileRs.new(path)", path = rpath);
|
936
|
+
assert!(result.is_ok());
|
937
|
+
let obj = result.unwrap();
|
938
|
+
|
939
|
+
let rs_self = &*obj;
|
940
|
+
|
941
|
+
let file_len = 1 << 32;
|
942
|
+
nix::unistd::ftruncate(file.as_raw_fd(), file_len).unwrap();
|
943
|
+
|
944
|
+
// We error when the file is externally modified.
|
945
|
+
assert!(rs_self.check_expand(obj, 512).is_err());
|
946
|
+
|
947
|
+
// We updated the object to use the new size.
|
948
|
+
assert_eq!(rs_self.capacity(), file_len as usize);
|
949
|
+
}
|
884
950
|
}
|
@@ -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
|
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', 'true') == '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
|
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}/
|
7
|
+
require_relative "../../../#{ruby_version}/fast_mmaped_file_rs"
|
9
8
|
rescue LoadError
|
10
|
-
require '
|
9
|
+
require 'fast_mmaped_file_rs'
|
11
10
|
end
|
12
11
|
|
13
12
|
module Prometheus
|
14
13
|
module Client
|
15
14
|
module Helper
|
16
|
-
|
17
|
-
if (ENV.fetch('prometheus_rust_mmaped_file', 'true') == "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
|
@@ -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
|
66
|
+
format.marshal_multiprocess
|
69
67
|
else
|
70
68
|
format.marshal
|
71
69
|
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.
|
4
|
+
version: 1.0.0
|
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-
|
14
|
+
date: 2023-11-15 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rb_sys
|
@@ -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
|
@@ -195,26 +176,6 @@ files:
|
|
195
176
|
- lib/prometheus/client/support/unicorn.rb
|
196
177
|
- lib/prometheus/client/uses_value_type.rb
|
197
178
|
- lib/prometheus/client/version.rb
|
198
|
-
- vendor/c/hashmap/.gitignore
|
199
|
-
- vendor/c/hashmap/LICENSE
|
200
|
-
- vendor/c/hashmap/README.md
|
201
|
-
- vendor/c/hashmap/_config.yml
|
202
|
-
- vendor/c/hashmap/src/hashmap.c
|
203
|
-
- vendor/c/hashmap/src/hashmap.h
|
204
|
-
- vendor/c/hashmap/test/Makefile
|
205
|
-
- vendor/c/hashmap/test/hashmap_test.c
|
206
|
-
- vendor/c/jsmn/.travis.yml
|
207
|
-
- vendor/c/jsmn/LICENSE
|
208
|
-
- vendor/c/jsmn/Makefile
|
209
|
-
- vendor/c/jsmn/README.md
|
210
|
-
- vendor/c/jsmn/example/jsondump.c
|
211
|
-
- vendor/c/jsmn/example/simple.c
|
212
|
-
- vendor/c/jsmn/jsmn.c
|
213
|
-
- vendor/c/jsmn/jsmn.h
|
214
|
-
- vendor/c/jsmn/library.json
|
215
|
-
- vendor/c/jsmn/test/test.h
|
216
|
-
- vendor/c/jsmn/test/tests.c
|
217
|
-
- vendor/c/jsmn/test/testutil.h
|
218
179
|
homepage: https://gitlab.com/gitlab-org/prometheus-client-mmap
|
219
180
|
licenses:
|
220
181
|
- Apache-2.0
|
@@ -237,6 +198,6 @@ requirements: []
|
|
237
198
|
rubygems_version: 3.3.26
|
238
199
|
signing_key:
|
239
200
|
specification_version: 4
|
240
|
-
summary: A suite of instrumentation metric
|
241
|
-
web services interface.
|
201
|
+
summary: A suite of instrumentation metric primitives that can be exposed through
|
202
|
+
a web services interface.
|
242
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
|
-
}
|