vinted-prometheus-client-mmap 1.5.0-x86_64-linux
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 +7 -0
- data/README.md +5 -0
- data/ext/fast_mmaped_file_rs/Cargo.toml +40 -0
- data/ext/fast_mmaped_file_rs/README.md +52 -0
- data/ext/fast_mmaped_file_rs/build.rs +7 -0
- data/ext/fast_mmaped_file_rs/extconf.rb +28 -0
- data/ext/fast_mmaped_file_rs/src/error.rs +174 -0
- data/ext/fast_mmaped_file_rs/src/exemplars.rs +25 -0
- data/ext/fast_mmaped_file_rs/src/file_entry.rs +1252 -0
- data/ext/fast_mmaped_file_rs/src/file_info.rs +240 -0
- data/ext/fast_mmaped_file_rs/src/lib.rs +89 -0
- data/ext/fast_mmaped_file_rs/src/macros.rs +14 -0
- data/ext/fast_mmaped_file_rs/src/map.rs +519 -0
- data/ext/fast_mmaped_file_rs/src/metrics.proto +153 -0
- data/ext/fast_mmaped_file_rs/src/mmap/inner.rs +775 -0
- data/ext/fast_mmaped_file_rs/src/mmap.rs +977 -0
- data/ext/fast_mmaped_file_rs/src/raw_entry.rs +547 -0
- data/ext/fast_mmaped_file_rs/src/testhelper.rs +222 -0
- data/ext/fast_mmaped_file_rs/src/util.rs +140 -0
- data/lib/.DS_Store +0 -0
- data/lib/2.7/fast_mmaped_file_rs.so +0 -0
- data/lib/3.0/fast_mmaped_file_rs.so +0 -0
- data/lib/3.1/fast_mmaped_file_rs.so +0 -0
- data/lib/3.2/fast_mmaped_file_rs.so +0 -0
- data/lib/3.3/fast_mmaped_file_rs.so +0 -0
- data/lib/prometheus/.DS_Store +0 -0
- data/lib/prometheus/client/configuration.rb +24 -0
- data/lib/prometheus/client/counter.rb +27 -0
- data/lib/prometheus/client/formats/protobuf.rb +93 -0
- data/lib/prometheus/client/formats/text.rb +85 -0
- data/lib/prometheus/client/gauge.rb +40 -0
- data/lib/prometheus/client/helper/entry_parser.rb +132 -0
- data/lib/prometheus/client/helper/file_locker.rb +50 -0
- data/lib/prometheus/client/helper/json_parser.rb +23 -0
- data/lib/prometheus/client/helper/metrics_processing.rb +45 -0
- data/lib/prometheus/client/helper/metrics_representation.rb +51 -0
- data/lib/prometheus/client/helper/mmaped_file.rb +64 -0
- data/lib/prometheus/client/helper/plain_file.rb +29 -0
- data/lib/prometheus/client/histogram.rb +80 -0
- data/lib/prometheus/client/label_set_validator.rb +85 -0
- data/lib/prometheus/client/metric.rb +80 -0
- data/lib/prometheus/client/mmaped_dict.rb +83 -0
- data/lib/prometheus/client/mmaped_value.rb +164 -0
- data/lib/prometheus/client/page_size.rb +17 -0
- data/lib/prometheus/client/push.rb +203 -0
- data/lib/prometheus/client/rack/collector.rb +88 -0
- data/lib/prometheus/client/rack/exporter.rb +102 -0
- data/lib/prometheus/client/registry.rb +65 -0
- data/lib/prometheus/client/simple_value.rb +31 -0
- data/lib/prometheus/client/summary.rb +69 -0
- data/lib/prometheus/client/support/puma.rb +44 -0
- data/lib/prometheus/client/support/unicorn.rb +35 -0
- data/lib/prometheus/client/uses_value_type.rb +20 -0
- data/lib/prometheus/client/version.rb +5 -0
- data/lib/prometheus/client.rb +58 -0
- data/lib/prometheus.rb +3 -0
- metadata +210 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e813eec5d2233337d34cd3f19c79e68a9b38b63e45607b3dd0929fbcf84e353f
|
4
|
+
data.tar.gz: 979ebaef61c83ecf0e6eeb85c85581e3869c269e7868d3194d6d6faab2c83bf4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1df8af4b3368826fde07874b89b14648a66f193a5c5a945bcda4fc6e9588500ddf800866ce2af04c573474b2c8aa5b1ee275674ba45dabc82539345b42f4ff10
|
7
|
+
data.tar.gz: 51c47ecccd1d1f0afb6c4543837c43657f203dc8b391b3ff4ed57a947499a6a7e98375be644eb5cd1033f2fc901f38cc4b663944ffb2a76c2ad8cbcd856bc27d
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
[package]
|
2
|
+
name = "fast_mmaped_file_rs"
|
3
|
+
version = "0.1.0"
|
4
|
+
edition = "2021"
|
5
|
+
|
6
|
+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
7
|
+
|
8
|
+
[dependencies]
|
9
|
+
prost = "0.12"
|
10
|
+
prost-types = "0.12"
|
11
|
+
hashbrown = "0.14"
|
12
|
+
varint-rs = "2.2.0"
|
13
|
+
itertools = "0.11.0"
|
14
|
+
libc = "0.2"
|
15
|
+
magnus = { version = "0.6", features = ["rb-sys"] }
|
16
|
+
memmap2 = "0.9"
|
17
|
+
# v0.26 cannot be built on CentOS 7 https://github.com/nix-rust/nix/issues/1972
|
18
|
+
nix = { version = "0.25", features = ["mman"] } # mman used for MsFlags
|
19
|
+
rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
|
20
|
+
serde = { version = "1.0", features = ["derive"] }
|
21
|
+
serde_json = { version = "1.0", features = ["raw_value"] }
|
22
|
+
smallvec = { version = "1.10", features = ["serde"] }
|
23
|
+
thiserror = "1.0"
|
24
|
+
|
25
|
+
[dev-dependencies]
|
26
|
+
bstr = "1.9"
|
27
|
+
indoc = "2.0"
|
28
|
+
# We need the `embed` feature to run tests, but this triggers failures when building as a Gem.
|
29
|
+
magnus = { version = "0.6", features = ["rb-sys","embed"] }
|
30
|
+
rand = "0.8"
|
31
|
+
sha2 = "0.10"
|
32
|
+
tempfile = "3.9"
|
33
|
+
|
34
|
+
[build-dependencies]
|
35
|
+
rb-sys-env = "0.1"
|
36
|
+
prost-build = "0.12"
|
37
|
+
|
38
|
+
[lib]
|
39
|
+
# Integration tests won't work if crate is only `cdylib`.
|
40
|
+
crate-type = ["cdylib","lib"]
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Testing
|
2
|
+
|
3
|
+
## Running Tests
|
4
|
+
|
5
|
+
Use [cargo nextest](https://nexte.st/) to execute the Rust unit tests.
|
6
|
+
|
7
|
+
```sh
|
8
|
+
$ cargo nextest run
|
9
|
+
```
|
10
|
+
|
11
|
+
## Why not use 'cargo test'?
|
12
|
+
|
13
|
+
We need to embed Ruby into the test binary to access Ruby types. This requires
|
14
|
+
us to run `magnus::embed::init()` no more than once before calling Ruby.
|
15
|
+
See [the magnus docs](https://docs.rs/magnus/latest/magnus/embed/fn.init.html)
|
16
|
+
for more details.
|
17
|
+
|
18
|
+
If we try to create separate `#[test]` functions that call `init()` these will
|
19
|
+
conflict, as Cargo runs tests in parallel using a single process with separate
|
20
|
+
threads. Running `cargo test` will result in errors like:
|
21
|
+
|
22
|
+
```
|
23
|
+
---- file_info::test::with_ruby stdout ----
|
24
|
+
thread 'file_info::test::with_ruby' panicked at 'Ruby already initialized'
|
25
|
+
```
|
26
|
+
|
27
|
+
The simplest workaround for this is to avoid using `cargo test` to run unit
|
28
|
+
tests. [nextest](https://nexte.st/) is an alternate test harness that runs each
|
29
|
+
test as its own process, enabling each test to intitialize Ruby without
|
30
|
+
conflict.
|
31
|
+
|
32
|
+
## 'symbol not found' errors when running tests
|
33
|
+
|
34
|
+
If you see errors like the following when running tests:
|
35
|
+
|
36
|
+
```
|
37
|
+
Caused by:
|
38
|
+
for `fast_mmaped_file_rs`, command `/Users/myuser/prometheus-client-mmap/ext/fast_mmaped_file_rs/target/debug/deps/fast_mmaped_file_rs-c81ccc96a6484e04 --list --format terse` exited with signal 6 (SIGABRT)
|
39
|
+
--- stdout:
|
40
|
+
|
41
|
+
--- stderr:
|
42
|
+
dyld[17861]: symbol not found in flat namespace '_rb_cArray'
|
43
|
+
```
|
44
|
+
|
45
|
+
Clearing the build cache will resolve the problem.
|
46
|
+
|
47
|
+
```sh
|
48
|
+
$ cargo clean
|
49
|
+
```
|
50
|
+
|
51
|
+
This is probably due to separate features being used with `magnus` in
|
52
|
+
development builds.
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
require "rb_sys/mkmf"
|
3
|
+
|
4
|
+
if find_executable('rustc')
|
5
|
+
create_rust_makefile("fast_mmaped_file_rs") do |r|
|
6
|
+
r.auto_install_rust_toolchain = false
|
7
|
+
|
8
|
+
if enable_config('fail-on-warning')
|
9
|
+
r.extra_rustflags = ["-Dwarnings"]
|
10
|
+
end
|
11
|
+
|
12
|
+
if enable_config('debug')
|
13
|
+
r.profile = :dev
|
14
|
+
end
|
15
|
+
|
16
|
+
if enable_config('address-sanitizer')
|
17
|
+
r.extra_rustflags = ["-Zsanitizer=address"]
|
18
|
+
end
|
19
|
+
|
20
|
+
# `rb_sys/mkmf` passes all arguments after `--` directly to `cargo rustc`.
|
21
|
+
# We use this awful hack to keep compatibility with existing flags used by
|
22
|
+
# the C implementation.
|
23
|
+
trimmed_argv = ARGV.take_while { |arg| arg != "--" }
|
24
|
+
ARGV = trimmed_argv
|
25
|
+
end
|
26
|
+
else
|
27
|
+
raise 'rustc not found. prometheus-client-mmap now requires Rust.'
|
28
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
use magnus::{exception, Ruby};
|
2
|
+
use std::any;
|
3
|
+
use std::fmt::Display;
|
4
|
+
use std::io;
|
5
|
+
use std::path::Path;
|
6
|
+
use thiserror::Error;
|
7
|
+
|
8
|
+
use crate::util;
|
9
|
+
use crate::PROM_EPARSING_ERROR;
|
10
|
+
|
11
|
+
/// A lightweight representation of Ruby ExceptionClasses.
|
12
|
+
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
13
|
+
pub enum RubyError {
|
14
|
+
Arg,
|
15
|
+
Encoding,
|
16
|
+
Frozen,
|
17
|
+
Index,
|
18
|
+
Io,
|
19
|
+
NoMem,
|
20
|
+
PromParsing,
|
21
|
+
Runtime,
|
22
|
+
Type,
|
23
|
+
}
|
24
|
+
|
25
|
+
impl From<RubyError> for magnus::ExceptionClass {
|
26
|
+
fn from(err: RubyError) -> magnus::ExceptionClass {
|
27
|
+
match err {
|
28
|
+
RubyError::Arg => exception::arg_error(),
|
29
|
+
RubyError::Encoding => exception::encoding_error(),
|
30
|
+
RubyError::Frozen => exception::frozen_error(),
|
31
|
+
RubyError::Index => exception::index_error(),
|
32
|
+
RubyError::Io => exception::io_error(),
|
33
|
+
RubyError::NoMem => exception::no_mem_error(),
|
34
|
+
RubyError::Runtime => exception::runtime_error(),
|
35
|
+
RubyError::PromParsing => {
|
36
|
+
// UNWRAP: this will panic if called outside of a Ruby thread.
|
37
|
+
let ruby = Ruby::get().unwrap();
|
38
|
+
ruby.get_inner(&PROM_EPARSING_ERROR)
|
39
|
+
}
|
40
|
+
RubyError::Type => exception::type_error(),
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
/// Errors returned internally within the crate. Methods called directly by Ruby return
|
46
|
+
/// `magnus::error::Error` as do functions that interact heavily with Ruby. This can be
|
47
|
+
/// converted into a `magnus::error::Error` at the boundary between Rust and Ruby.
|
48
|
+
#[derive(PartialEq, Eq, Error, Debug)]
|
49
|
+
pub enum MmapError {
|
50
|
+
/// A read or write was made while another thread had mutable access to the mmap.
|
51
|
+
#[error("read/write operation attempted while mmap was being written to")]
|
52
|
+
ConcurrentAccess,
|
53
|
+
/// An error message used to exactly match the messages returned by the C
|
54
|
+
/// implementation.
|
55
|
+
#[error("{0}")]
|
56
|
+
Legacy(String, RubyError),
|
57
|
+
/// A String had invalid UTF-8 sequences.
|
58
|
+
#[error("{0}")]
|
59
|
+
Encoding(String),
|
60
|
+
/// A failed attempt to cast an integer from one type to another.
|
61
|
+
#[error("failed to cast {object_name} {value} from {from} to {to}")]
|
62
|
+
FailedCast {
|
63
|
+
from: &'static str,
|
64
|
+
to: &'static str,
|
65
|
+
value: String,
|
66
|
+
object_name: String,
|
67
|
+
},
|
68
|
+
/// The mmap was frozen when a mutable operation was attempted.
|
69
|
+
#[error("mmap")]
|
70
|
+
Frozen,
|
71
|
+
/// An io operation failed.
|
72
|
+
#[error("failed to {operation} path '{path}': {err}")]
|
73
|
+
Io {
|
74
|
+
operation: String,
|
75
|
+
path: String,
|
76
|
+
err: String,
|
77
|
+
},
|
78
|
+
#[error("string length gt {}", i32::MAX)]
|
79
|
+
KeyLength,
|
80
|
+
/// Failed to allocate memory.
|
81
|
+
#[error("Couldn't allocate for {0} memory")]
|
82
|
+
OutOfMemory(usize),
|
83
|
+
/// A memory operation fell outside of the containers bounds.
|
84
|
+
#[error("offset {index} out of bounds of len {len}")]
|
85
|
+
OutOfBounds { index: String, len: String },
|
86
|
+
/// A numeric operation overflowed.
|
87
|
+
#[error("overflow when {op} {value} and {added} of type {ty}")]
|
88
|
+
Overflow {
|
89
|
+
value: String,
|
90
|
+
added: String,
|
91
|
+
op: String,
|
92
|
+
ty: &'static str,
|
93
|
+
},
|
94
|
+
/// A miscellaneous error.
|
95
|
+
#[error("{0}")]
|
96
|
+
Other(String),
|
97
|
+
/// A failure when parsing a `.db` file containing Prometheus metrics.
|
98
|
+
#[error("{0}")]
|
99
|
+
PromParsing(String),
|
100
|
+
/// No mmap open.
|
101
|
+
#[error("unmapped file")]
|
102
|
+
UnmappedFile,
|
103
|
+
/// A custom error message with `strerror(3)` appended.
|
104
|
+
#[error("{0}")]
|
105
|
+
WithErrno(String),
|
106
|
+
}
|
107
|
+
|
108
|
+
impl MmapError {
|
109
|
+
pub fn legacy<T: Into<String>>(msg: T, ruby_err: RubyError) -> Self {
|
110
|
+
MmapError::Legacy(msg.into(), ruby_err)
|
111
|
+
}
|
112
|
+
|
113
|
+
pub fn failed_cast<T: Display, U>(value: T, object_name: &str) -> Self {
|
114
|
+
MmapError::FailedCast {
|
115
|
+
from: any::type_name::<T>(),
|
116
|
+
to: any::type_name::<U>(),
|
117
|
+
value: value.to_string(),
|
118
|
+
object_name: object_name.to_string(),
|
119
|
+
}
|
120
|
+
}
|
121
|
+
pub fn io(operation: &str, path: &Path, err: io::Error) -> Self {
|
122
|
+
MmapError::Io {
|
123
|
+
operation: operation.to_string(),
|
124
|
+
path: path.display().to_string(),
|
125
|
+
err: err.to_string(),
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
pub fn overflowed<T: Display>(value: T, added: T, op: &str) -> Self {
|
130
|
+
MmapError::Overflow {
|
131
|
+
value: value.to_string(),
|
132
|
+
added: added.to_string(),
|
133
|
+
op: op.to_string(),
|
134
|
+
ty: any::type_name::<T>(),
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
pub fn out_of_bounds<T: Display>(index: T, len: T) -> Self {
|
139
|
+
MmapError::OutOfBounds {
|
140
|
+
index: index.to_string(),
|
141
|
+
len: len.to_string(),
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
pub fn with_errno<T: Into<String>>(msg: T) -> Self {
|
146
|
+
let strerror = util::strerror(util::errno());
|
147
|
+
MmapError::WithErrno(format!("{}: ({strerror})", msg.into()))
|
148
|
+
}
|
149
|
+
|
150
|
+
pub fn ruby_err(&self) -> RubyError {
|
151
|
+
match self {
|
152
|
+
MmapError::ConcurrentAccess => RubyError::Arg,
|
153
|
+
MmapError::Legacy(_, e) => *e,
|
154
|
+
MmapError::Encoding(_) => RubyError::Encoding,
|
155
|
+
MmapError::Io { .. } => RubyError::Io,
|
156
|
+
MmapError::FailedCast { .. } => RubyError::Arg,
|
157
|
+
MmapError::Frozen => RubyError::Frozen,
|
158
|
+
MmapError::KeyLength => RubyError::Arg,
|
159
|
+
MmapError::Overflow { .. } => RubyError::Arg,
|
160
|
+
MmapError::OutOfBounds { .. } => RubyError::Index,
|
161
|
+
MmapError::OutOfMemory { .. } => RubyError::NoMem,
|
162
|
+
MmapError::Other(_) => RubyError::Arg,
|
163
|
+
MmapError::PromParsing(_) => RubyError::PromParsing,
|
164
|
+
MmapError::UnmappedFile => RubyError::Io,
|
165
|
+
MmapError::WithErrno(_) => RubyError::Io,
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
impl From<MmapError> for magnus::error::Error {
|
171
|
+
fn from(err: MmapError) -> magnus::error::Error {
|
172
|
+
magnus::error::Error::new(err.ruby_err().into(), err.to_string())
|
173
|
+
}
|
174
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#[derive(Clone, Debug, Serialize, Deserialize)]
|
2
|
+
pub struct Exemplar {
|
3
|
+
// Labels (set of label names/values). Only 1 for now.
|
4
|
+
// Value -> f64.
|
5
|
+
// Timestamp -> uint64.
|
6
|
+
// We have to cap the maximum size of strings.
|
7
|
+
// From the spec:
|
8
|
+
// The combined length of the label names and values of an Exemplar's LabelSet MUST NOT exceed 128 UTF-8 character code points.
|
9
|
+
// 4 bytes max per code point.
|
10
|
+
// So, we need to allocate 128*4 = 512 bytes for the label names and values.
|
11
|
+
pub label_name: String,
|
12
|
+
|
13
|
+
pub label_value: String,
|
14
|
+
pub value: f64,
|
15
|
+
pub timestamp: u128,
|
16
|
+
}
|
17
|
+
|
18
|
+
use serde::{Deserialize, Serialize};
|
19
|
+
|
20
|
+
use crate::size_of;
|
21
|
+
|
22
|
+
pub const EXEMPLAR_ENTRY_MAX_SIZE_BYTES:usize = 512 + size_of::<f64>() + size_of::<u64>();
|
23
|
+
|
24
|
+
// Key -> use the old one.
|
25
|
+
// Value -> allocate EXEMPLAR_ENTRY_MAX_SIZE_BYTES. If it exceeds this, we need to return an error. Use JSON.
|