prometheus-client-mmap 0.19.1 → 0.20.1
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/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 +546 -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 +37 -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.1
|
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-15 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,22 @@ 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/Cargo.lock
|
134
|
+
- ext/fast_mmaped_file_rs/Cargo.toml
|
135
|
+
- ext/fast_mmaped_file_rs/README.md
|
136
|
+
- ext/fast_mmaped_file_rs/extconf.rb
|
137
|
+
- ext/fast_mmaped_file_rs/src/error.rs
|
138
|
+
- ext/fast_mmaped_file_rs/src/file_entry.rs
|
139
|
+
- ext/fast_mmaped_file_rs/src/file_info.rs
|
140
|
+
- ext/fast_mmaped_file_rs/src/lib.rs
|
141
|
+
- ext/fast_mmaped_file_rs/src/macros.rs
|
142
|
+
- ext/fast_mmaped_file_rs/src/map.rs
|
143
|
+
- ext/fast_mmaped_file_rs/src/mmap.rs
|
144
|
+
- ext/fast_mmaped_file_rs/src/parser.rs
|
145
|
+
- ext/fast_mmaped_file_rs/src/raw_entry.rs
|
146
|
+
- ext/fast_mmaped_file_rs/src/testhelper.rs
|
147
|
+
- ext/fast_mmaped_file_rs/src/util.rs
|
117
148
|
- lib/prometheus.rb
|
118
149
|
- lib/prometheus/client.rb
|
119
150
|
- lib/prometheus/client/configuration.rb
|
@@ -132,6 +163,7 @@ files:
|
|
132
163
|
- lib/prometheus/client/metric.rb
|
133
164
|
- lib/prometheus/client/mmaped_dict.rb
|
134
165
|
- lib/prometheus/client/mmaped_value.rb
|
166
|
+
- lib/prometheus/client/page_size.rb
|
135
167
|
- lib/prometheus/client/push.rb
|
136
168
|
- lib/prometheus/client/rack/collector.rb
|
137
169
|
- lib/prometheus/client/rack/exporter.rb
|
@@ -141,6 +173,7 @@ files:
|
|
141
173
|
- lib/prometheus/client/support/unicorn.rb
|
142
174
|
- lib/prometheus/client/uses_value_type.rb
|
143
175
|
- lib/prometheus/client/version.rb
|
176
|
+
- vendor/c/hashmap/.gitignore
|
144
177
|
- vendor/c/hashmap/LICENSE
|
145
178
|
- vendor/c/hashmap/README.md
|
146
179
|
- vendor/c/hashmap/_config.yml
|
@@ -148,6 +181,7 @@ files:
|
|
148
181
|
- vendor/c/hashmap/src/hashmap.h
|
149
182
|
- vendor/c/hashmap/test/Makefile
|
150
183
|
- vendor/c/hashmap/test/hashmap_test.c
|
184
|
+
- vendor/c/jsmn/.travis.yml
|
151
185
|
- vendor/c/jsmn/LICENSE
|
152
186
|
- vendor/c/jsmn/Makefile
|
153
187
|
- vendor/c/jsmn/README.md
|
@@ -178,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
212
|
- !ruby/object:Gem::Version
|
179
213
|
version: '0'
|
180
214
|
requirements: []
|
181
|
-
rubygems_version: 3.4.
|
215
|
+
rubygems_version: 3.4.12
|
182
216
|
signing_key:
|
183
217
|
specification_version: 4
|
184
218
|
summary: A suite of instrumentation metric primitivesthat can be exposed through a
|