prometheus-client-mmap 0.19.1 → 0.21.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 +27 -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 +790 -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 +30 -0
- data/ext/fast_mmaped_file_rs/src/error.rs +174 -0
- data/ext/fast_mmaped_file_rs/src/file_entry.rs +579 -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 +492 -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 +35 -2
- data/lib/prometheus/client/helper/mmaped_file.rb +8 -1
- 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 +58 -10
@@ -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,49 @@ 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 load_rust_extension
|
50
|
+
begin
|
51
|
+
ruby_version = /(\d+\.\d+)/.match(RUBY_VERSION)
|
52
|
+
require_relative "../../../#{ruby_version}/fast_mmaped_file_rs"
|
53
|
+
rescue LoadError
|
54
|
+
require 'fast_mmaped_file_rs'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def check_for_rust
|
59
|
+
# This will be evaluated on each invocation even with `||=` if
|
60
|
+
# `@rust_available` if false. Running a `require` statement is slow,
|
61
|
+
# so the `rust_impl_available?` method memoizes the result, external
|
62
|
+
# callers can only trigger this method a single time.
|
63
|
+
@rust_available = begin
|
64
|
+
load_rust_extension
|
65
|
+
true
|
66
|
+
rescue LoadError
|
67
|
+
Prometheus::Client.logger.info('FastMmapedFileRs unavailable')
|
68
|
+
false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
39
72
|
def load_metrics(path)
|
40
73
|
metrics = {}
|
41
74
|
Dir.glob(File.join(path, '*.db')).sort.each do |f|
|
@@ -1,6 +1,13 @@
|
|
1
1
|
require 'prometheus/client/helper/entry_parser'
|
2
2
|
require 'prometheus/client/helper/file_locker'
|
3
|
-
|
3
|
+
|
4
|
+
# load precompiled extension if available
|
5
|
+
begin
|
6
|
+
ruby_version = /(\d+\.\d+)/.match(RUBY_VERSION)
|
7
|
+
require_relative "../../../#{ruby_version}/fast_mmaped_file"
|
8
|
+
rescue LoadError
|
9
|
+
require 'fast_mmaped_file'
|
10
|
+
end
|
4
11
|
|
5
12
|
module Prometheus
|
6
13
|
module Client
|
@@ -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,16 +1,30 @@
|
|
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.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Schmidt
|
8
8
|
- Paweł Chojnacki
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-04-21 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
|
@@ -65,14 +79,28 @@ dependencies:
|
|
65
79
|
requirements:
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
82
|
+
version: 1.2.1
|
69
83
|
type: :development
|
70
84
|
prerelease: false
|
71
85
|
version_requirements: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
89
|
+
version: 1.2.1
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: rake-compiler-dock
|
92
|
+
requirement: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.3.0
|
97
|
+
type: :development
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.3.0
|
76
104
|
- !ruby/object:Gem::Dependency
|
77
105
|
name: ruby-prof
|
78
106
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,13 +115,14 @@ dependencies:
|
|
87
115
|
- - "~>"
|
88
116
|
- !ruby/object:Gem::Version
|
89
117
|
version: 0.16.2
|
90
|
-
description:
|
118
|
+
description:
|
91
119
|
email:
|
92
120
|
- ts@soundcloud.com
|
93
121
|
- pawel@gitlab.com
|
94
122
|
executables: []
|
95
123
|
extensions:
|
96
124
|
- ext/fast_mmaped_file/extconf.rb
|
125
|
+
- ext/fast_mmaped_file_rs/extconf.rb
|
97
126
|
extra_rdoc_files: []
|
98
127
|
files:
|
99
128
|
- README.md
|
@@ -114,6 +143,22 @@ files:
|
|
114
143
|
- ext/fast_mmaped_file/utils.h
|
115
144
|
- ext/fast_mmaped_file/value_access.c
|
116
145
|
- ext/fast_mmaped_file/value_access.h
|
146
|
+
- ext/fast_mmaped_file_rs/.cargo/config.toml
|
147
|
+
- ext/fast_mmaped_file_rs/Cargo.lock
|
148
|
+
- ext/fast_mmaped_file_rs/Cargo.toml
|
149
|
+
- ext/fast_mmaped_file_rs/README.md
|
150
|
+
- ext/fast_mmaped_file_rs/extconf.rb
|
151
|
+
- ext/fast_mmaped_file_rs/src/error.rs
|
152
|
+
- ext/fast_mmaped_file_rs/src/file_entry.rs
|
153
|
+
- ext/fast_mmaped_file_rs/src/file_info.rs
|
154
|
+
- ext/fast_mmaped_file_rs/src/lib.rs
|
155
|
+
- ext/fast_mmaped_file_rs/src/macros.rs
|
156
|
+
- ext/fast_mmaped_file_rs/src/map.rs
|
157
|
+
- ext/fast_mmaped_file_rs/src/mmap.rs
|
158
|
+
- ext/fast_mmaped_file_rs/src/parser.rs
|
159
|
+
- ext/fast_mmaped_file_rs/src/raw_entry.rs
|
160
|
+
- ext/fast_mmaped_file_rs/src/testhelper.rs
|
161
|
+
- ext/fast_mmaped_file_rs/src/util.rs
|
117
162
|
- lib/prometheus.rb
|
118
163
|
- lib/prometheus/client.rb
|
119
164
|
- lib/prometheus/client/configuration.rb
|
@@ -132,6 +177,7 @@ files:
|
|
132
177
|
- lib/prometheus/client/metric.rb
|
133
178
|
- lib/prometheus/client/mmaped_dict.rb
|
134
179
|
- lib/prometheus/client/mmaped_value.rb
|
180
|
+
- lib/prometheus/client/page_size.rb
|
135
181
|
- lib/prometheus/client/push.rb
|
136
182
|
- lib/prometheus/client/rack/collector.rb
|
137
183
|
- lib/prometheus/client/rack/exporter.rb
|
@@ -141,6 +187,7 @@ files:
|
|
141
187
|
- lib/prometheus/client/support/unicorn.rb
|
142
188
|
- lib/prometheus/client/uses_value_type.rb
|
143
189
|
- lib/prometheus/client/version.rb
|
190
|
+
- vendor/c/hashmap/.gitignore
|
144
191
|
- vendor/c/hashmap/LICENSE
|
145
192
|
- vendor/c/hashmap/README.md
|
146
193
|
- vendor/c/hashmap/_config.yml
|
@@ -148,6 +195,7 @@ files:
|
|
148
195
|
- vendor/c/hashmap/src/hashmap.h
|
149
196
|
- vendor/c/hashmap/test/Makefile
|
150
197
|
- vendor/c/hashmap/test/hashmap_test.c
|
198
|
+
- vendor/c/jsmn/.travis.yml
|
151
199
|
- vendor/c/jsmn/LICENSE
|
152
200
|
- vendor/c/jsmn/Makefile
|
153
201
|
- vendor/c/jsmn/README.md
|
@@ -163,7 +211,7 @@ homepage: https://gitlab.com/gitlab-org/prometheus-client-mmap
|
|
163
211
|
licenses:
|
164
212
|
- Apache-2.0
|
165
213
|
metadata: {}
|
166
|
-
post_install_message:
|
214
|
+
post_install_message:
|
167
215
|
rdoc_options: []
|
168
216
|
require_paths:
|
169
217
|
- lib
|
@@ -176,10 +224,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
224
|
requirements:
|
177
225
|
- - ">="
|
178
226
|
- !ruby/object:Gem::Version
|
179
|
-
version:
|
227
|
+
version: 3.3.22
|
180
228
|
requirements: []
|
181
|
-
rubygems_version: 3.
|
182
|
-
signing_key:
|
229
|
+
rubygems_version: 3.3.26
|
230
|
+
signing_key:
|
183
231
|
specification_version: 4
|
184
232
|
summary: A suite of instrumentation metric primitivesthat can be exposed through a
|
185
233
|
web services interface.
|