prometheus-client-mmap 0.19.1 → 0.20.0
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 +4 -4
- data/README.md +14 -0
- data/ext/fast_mmaped_file/extconf.rb +1 -1
- data/ext/fast_mmaped_file_rs/.cargo/config.toml +23 -0
- data/ext/fast_mmaped_file_rs/.tool-versions +1 -0
- data/ext/fast_mmaped_file_rs/Cargo.lock +782 -0
- data/ext/fast_mmaped_file_rs/Cargo.toml +30 -0
- data/ext/fast_mmaped_file_rs/README.md +52 -0
- data/ext/fast_mmaped_file_rs/extconf.rb +22 -0
- data/ext/fast_mmaped_file_rs/src/error.rs +174 -0
- data/ext/fast_mmaped_file_rs/src/file_entry.rs +544 -0
- data/ext/fast_mmaped_file_rs/src/file_info.rs +190 -0
- data/ext/fast_mmaped_file_rs/src/lib.rs +79 -0
- data/ext/fast_mmaped_file_rs/src/macros.rs +14 -0
- data/ext/fast_mmaped_file_rs/src/map.rs +458 -0
- data/ext/fast_mmaped_file_rs/src/mmap.rs +151 -0
- data/ext/fast_mmaped_file_rs/src/parser.rs +346 -0
- data/ext/fast_mmaped_file_rs/src/raw_entry.rs +473 -0
- data/ext/fast_mmaped_file_rs/src/testhelper.rs +222 -0
- data/ext/fast_mmaped_file_rs/src/util.rs +121 -0
- data/lib/prometheus/client/configuration.rb +2 -1
- data/lib/prometheus/client/formats/text.rb +26 -2
- data/lib/prometheus/client/page_size.rb +17 -0
- data/lib/prometheus/client/version.rb +1 -1
- data/vendor/c/hashmap/.gitignore +52 -0
- data/vendor/c/jsmn/.travis.yml +4 -0
- metadata +38 -3
@@ -0,0 +1,121 @@
|
|
1
|
+
use nix::errno::Errno;
|
2
|
+
use nix::libc::c_long;
|
3
|
+
use std::fmt::Display;
|
4
|
+
use std::io;
|
5
|
+
use std::mem::size_of;
|
6
|
+
|
7
|
+
use crate::error::MmapError;
|
8
|
+
use crate::Result;
|
9
|
+
|
10
|
+
/// Wrapper around `checked_add()` that converts failures
|
11
|
+
/// to `MmapError::Overflow`.
|
12
|
+
pub trait CheckedOps: Sized {
|
13
|
+
fn add_chk(self, rhs: Self) -> Result<Self>;
|
14
|
+
fn mul_chk(self, rhs: Self) -> Result<Self>;
|
15
|
+
}
|
16
|
+
|
17
|
+
impl CheckedOps for usize {
|
18
|
+
fn add_chk(self, rhs: Self) -> Result<Self> {
|
19
|
+
self.checked_add(rhs)
|
20
|
+
.ok_or_else(|| MmapError::overflowed(self, rhs, "adding"))
|
21
|
+
}
|
22
|
+
|
23
|
+
fn mul_chk(self, rhs: Self) -> Result<Self> {
|
24
|
+
self.checked_mul(rhs)
|
25
|
+
.ok_or_else(|| MmapError::overflowed(self, rhs, "multiplying"))
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
impl CheckedOps for c_long {
|
30
|
+
fn add_chk(self, rhs: Self) -> Result<Self> {
|
31
|
+
self.checked_add(rhs)
|
32
|
+
.ok_or_else(|| MmapError::overflowed(self, rhs, "adding"))
|
33
|
+
}
|
34
|
+
|
35
|
+
fn mul_chk(self, rhs: Self) -> Result<Self> {
|
36
|
+
self.checked_mul(rhs)
|
37
|
+
.ok_or_else(|| MmapError::overflowed(self, rhs, "multiplying"))
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
/// A wrapper around `TryFrom`, returning `MmapError::FailedCast` on error.
|
42
|
+
pub fn cast_chk<T, U>(val: T, name: &str) -> Result<U>
|
43
|
+
where
|
44
|
+
T: Copy + Display,
|
45
|
+
U: std::convert::TryFrom<T>,
|
46
|
+
{
|
47
|
+
U::try_from(val).map_err(|_| MmapError::failed_cast::<T, U>(val, name))
|
48
|
+
}
|
49
|
+
|
50
|
+
/// Retrieve errno(3).
|
51
|
+
pub fn errno() -> i32 {
|
52
|
+
// UNWRAP: This will always return `Some` when called from `last_os_error()`.
|
53
|
+
io::Error::last_os_error().raw_os_error().unwrap()
|
54
|
+
}
|
55
|
+
|
56
|
+
/// Get the error string associated with errno(3).
|
57
|
+
/// Equivalent to strerror(3).
|
58
|
+
pub fn strerror(errno: i32) -> &'static str {
|
59
|
+
Errno::from_i32(errno).desc()
|
60
|
+
}
|
61
|
+
|
62
|
+
/// Read a `u32` value from a byte slice starting from `offset`.
|
63
|
+
#[inline]
|
64
|
+
pub fn read_u32(buf: &[u8], offset: usize) -> Result<u32> {
|
65
|
+
if let Some(slice) = buf.get(offset..offset + size_of::<u32>()) {
|
66
|
+
// UNWRAP: We can safely unwrap the conversion from slice to array as we
|
67
|
+
// the source and targets are constructed here with the same length.
|
68
|
+
let out: &[u8; size_of::<u32>()] = slice.try_into().unwrap();
|
69
|
+
|
70
|
+
return Ok(u32::from_ne_bytes(*out));
|
71
|
+
}
|
72
|
+
Err(MmapError::out_of_bounds(offset, buf.len()))
|
73
|
+
}
|
74
|
+
|
75
|
+
/// Read an `f64` value from a byte slice starting from `offset`.
|
76
|
+
#[inline]
|
77
|
+
pub fn read_f64(buf: &[u8], offset: usize) -> Result<f64> {
|
78
|
+
if let Some(slice) = buf.get(offset..offset + size_of::<f64>()) {
|
79
|
+
// UNWRAP: We can safely unwrap the conversion from slice to array as we
|
80
|
+
// can be sure the target array has same length as the source slice.
|
81
|
+
let out: &[u8; size_of::<f64>()] = slice.try_into().unwrap();
|
82
|
+
|
83
|
+
return Ok(f64::from_ne_bytes(*out));
|
84
|
+
}
|
85
|
+
Err(MmapError::out_of_bounds(
|
86
|
+
offset + size_of::<f64>(),
|
87
|
+
buf.len(),
|
88
|
+
))
|
89
|
+
}
|
90
|
+
|
91
|
+
#[cfg(test)]
|
92
|
+
mod test {
|
93
|
+
use super::*;
|
94
|
+
|
95
|
+
#[test]
|
96
|
+
fn test_read_u32() {
|
97
|
+
let buf = 1u32.to_ne_bytes();
|
98
|
+
|
99
|
+
assert!(matches!(read_u32(&buf, 0), Ok(1)), "index ok");
|
100
|
+
assert!(read_u32(&buf, 10).is_err(), "index out of range");
|
101
|
+
assert!(
|
102
|
+
read_u32(&buf, 1).is_err(),
|
103
|
+
"index in range but end out of range"
|
104
|
+
);
|
105
|
+
}
|
106
|
+
|
107
|
+
#[test]
|
108
|
+
fn test_read_f64() {
|
109
|
+
let buf = 1.00f64.to_ne_bytes();
|
110
|
+
|
111
|
+
let ok = read_f64(&buf, 0);
|
112
|
+
assert!(ok.is_ok());
|
113
|
+
assert_eq!(ok.unwrap(), 1.00);
|
114
|
+
|
115
|
+
assert!(read_f64(&buf, 10).is_err(), "index out of range");
|
116
|
+
assert!(
|
117
|
+
read_f64(&buf, 1).is_err(),
|
118
|
+
"index in range but end out of range"
|
119
|
+
);
|
120
|
+
}
|
121
|
+
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'prometheus/client/registry'
|
2
2
|
require 'prometheus/client/mmaped_value'
|
3
|
+
require 'prometheus/client/page_size'
|
3
4
|
require 'logger'
|
4
5
|
require 'tmpdir'
|
5
6
|
|
@@ -10,7 +11,7 @@ module Prometheus
|
|
10
11
|
|
11
12
|
def initialize
|
12
13
|
@value_class = ::Prometheus::Client::MmapedValue
|
13
|
-
@initial_mmap_file_size =
|
14
|
+
@initial_mmap_file_size = ::Prometheus::Client::PageSize.page_size(fallback_page_size: 4096)
|
14
15
|
@logger = Logger.new($stdout)
|
15
16
|
@pid_provider = Process.method(:pid)
|
16
17
|
@multiprocess_files_dir = ENV.fetch('prometheus_multiproc_dir') do
|
@@ -26,16 +26,40 @@ module Prometheus
|
|
26
26
|
Helper::MetricsRepresentation.to_text(metrics)
|
27
27
|
end
|
28
28
|
|
29
|
-
def marshal_multiprocess(path = Prometheus::Client.configuration.multiprocess_files_dir)
|
29
|
+
def marshal_multiprocess(path = Prometheus::Client.configuration.multiprocess_files_dir, use_rust: false)
|
30
30
|
file_list = Dir.glob(File.join(path, '*.db')).sort
|
31
31
|
.map {|f| Helper::PlainFile.new(f) }
|
32
32
|
.map {|f| [f.filepath, f.multiprocess_mode.to_sym, f.type.to_sym, f.pid] }
|
33
33
|
|
34
|
-
|
34
|
+
if use_rust && rust_impl_available?
|
35
|
+
FastMmapedFileRs.to_metrics(file_list.to_a)
|
36
|
+
else
|
37
|
+
FastMmapedFile.to_metrics(file_list.to_a)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def rust_impl_available?
|
42
|
+
return @rust_available unless @rust_available.nil?
|
43
|
+
|
44
|
+
check_for_rust
|
35
45
|
end
|
36
46
|
|
37
47
|
private
|
38
48
|
|
49
|
+
def check_for_rust
|
50
|
+
# This will be evaluated on each invocation even with `||=` if
|
51
|
+
# `@rust_available` if false. Running a `require` statement is slow,
|
52
|
+
# so the `rust_impl_available?` method memoizes the result, external
|
53
|
+
# callers can only trigger this method a single time.
|
54
|
+
@rust_available = begin
|
55
|
+
require 'fast_mmaped_file_rs'
|
56
|
+
true
|
57
|
+
rescue LoadError
|
58
|
+
Prometheus::Client.logger.info('FastMmapedFileRs unavailable')
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
39
63
|
def load_metrics(path)
|
40
64
|
metrics = {}
|
41
65
|
Dir.glob(File.join(path, '*.db')).sort.each do |f|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module Prometheus
|
4
|
+
module Client
|
5
|
+
module PageSize
|
6
|
+
def self.page_size(fallback_page_size: 4096)
|
7
|
+
stdout, status = Open3.capture2('getconf PAGESIZE')
|
8
|
+
return fallback_page_size if status.nil? || !status.success?
|
9
|
+
|
10
|
+
page_size = stdout.chomp.to_i
|
11
|
+
return fallback_page_size if page_size <= 0
|
12
|
+
|
13
|
+
page_size
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Prerequisites
|
2
|
+
*.d
|
3
|
+
|
4
|
+
# Object files
|
5
|
+
*.o
|
6
|
+
*.ko
|
7
|
+
*.obj
|
8
|
+
*.elf
|
9
|
+
|
10
|
+
# Linker output
|
11
|
+
*.ilk
|
12
|
+
*.map
|
13
|
+
*.exp
|
14
|
+
|
15
|
+
# Precompiled Headers
|
16
|
+
*.gch
|
17
|
+
*.pch
|
18
|
+
|
19
|
+
# Libraries
|
20
|
+
*.lib
|
21
|
+
*.a
|
22
|
+
*.la
|
23
|
+
*.lo
|
24
|
+
|
25
|
+
# Shared objects (inc. Windows DLLs)
|
26
|
+
*.dll
|
27
|
+
*.so
|
28
|
+
*.so.*
|
29
|
+
*.dylib
|
30
|
+
|
31
|
+
# Executables
|
32
|
+
*.exe
|
33
|
+
*.out
|
34
|
+
*.app
|
35
|
+
*.i*86
|
36
|
+
*.x86_64
|
37
|
+
*.hex
|
38
|
+
|
39
|
+
# Debug files
|
40
|
+
*.dSYM/
|
41
|
+
*.su
|
42
|
+
*.idb
|
43
|
+
*.pdb
|
44
|
+
|
45
|
+
# Kernel Module Compile Results
|
46
|
+
*.mod*
|
47
|
+
*.cmd
|
48
|
+
.tmp_versions/
|
49
|
+
modules.order
|
50
|
+
Module.symvers
|
51
|
+
Mkfile.old
|
52
|
+
dkms.conf
|
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: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Schmidt
|
@@ -9,8 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-04-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rb_sys
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0.9'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0.9'
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: fuzzbert
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +108,7 @@ email:
|
|
94
108
|
executables: []
|
95
109
|
extensions:
|
96
110
|
- ext/fast_mmaped_file/extconf.rb
|
111
|
+
- ext/fast_mmaped_file_rs/extconf.rb
|
97
112
|
extra_rdoc_files: []
|
98
113
|
files:
|
99
114
|
- README.md
|
@@ -114,6 +129,23 @@ files:
|
|
114
129
|
- ext/fast_mmaped_file/utils.h
|
115
130
|
- ext/fast_mmaped_file/value_access.c
|
116
131
|
- ext/fast_mmaped_file/value_access.h
|
132
|
+
- ext/fast_mmaped_file_rs/.cargo/config.toml
|
133
|
+
- ext/fast_mmaped_file_rs/.tool-versions
|
134
|
+
- ext/fast_mmaped_file_rs/Cargo.lock
|
135
|
+
- ext/fast_mmaped_file_rs/Cargo.toml
|
136
|
+
- ext/fast_mmaped_file_rs/README.md
|
137
|
+
- ext/fast_mmaped_file_rs/extconf.rb
|
138
|
+
- ext/fast_mmaped_file_rs/src/error.rs
|
139
|
+
- ext/fast_mmaped_file_rs/src/file_entry.rs
|
140
|
+
- ext/fast_mmaped_file_rs/src/file_info.rs
|
141
|
+
- ext/fast_mmaped_file_rs/src/lib.rs
|
142
|
+
- ext/fast_mmaped_file_rs/src/macros.rs
|
143
|
+
- ext/fast_mmaped_file_rs/src/map.rs
|
144
|
+
- ext/fast_mmaped_file_rs/src/mmap.rs
|
145
|
+
- ext/fast_mmaped_file_rs/src/parser.rs
|
146
|
+
- ext/fast_mmaped_file_rs/src/raw_entry.rs
|
147
|
+
- ext/fast_mmaped_file_rs/src/testhelper.rs
|
148
|
+
- ext/fast_mmaped_file_rs/src/util.rs
|
117
149
|
- lib/prometheus.rb
|
118
150
|
- lib/prometheus/client.rb
|
119
151
|
- lib/prometheus/client/configuration.rb
|
@@ -132,6 +164,7 @@ files:
|
|
132
164
|
- lib/prometheus/client/metric.rb
|
133
165
|
- lib/prometheus/client/mmaped_dict.rb
|
134
166
|
- lib/prometheus/client/mmaped_value.rb
|
167
|
+
- lib/prometheus/client/page_size.rb
|
135
168
|
- lib/prometheus/client/push.rb
|
136
169
|
- lib/prometheus/client/rack/collector.rb
|
137
170
|
- lib/prometheus/client/rack/exporter.rb
|
@@ -141,6 +174,7 @@ files:
|
|
141
174
|
- lib/prometheus/client/support/unicorn.rb
|
142
175
|
- lib/prometheus/client/uses_value_type.rb
|
143
176
|
- lib/prometheus/client/version.rb
|
177
|
+
- vendor/c/hashmap/.gitignore
|
144
178
|
- vendor/c/hashmap/LICENSE
|
145
179
|
- vendor/c/hashmap/README.md
|
146
180
|
- vendor/c/hashmap/_config.yml
|
@@ -148,6 +182,7 @@ files:
|
|
148
182
|
- vendor/c/hashmap/src/hashmap.h
|
149
183
|
- vendor/c/hashmap/test/Makefile
|
150
184
|
- vendor/c/hashmap/test/hashmap_test.c
|
185
|
+
- vendor/c/jsmn/.travis.yml
|
151
186
|
- vendor/c/jsmn/LICENSE
|
152
187
|
- vendor/c/jsmn/Makefile
|
153
188
|
- vendor/c/jsmn/README.md
|
@@ -178,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
213
|
- !ruby/object:Gem::Version
|
179
214
|
version: '0'
|
180
215
|
requirements: []
|
181
|
-
rubygems_version: 3.4.
|
216
|
+
rubygems_version: 3.4.10
|
182
217
|
signing_key:
|
183
218
|
specification_version: 4
|
184
219
|
summary: A suite of instrumentation metric primitivesthat can be exposed through a
|