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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +5 -0
  3. data/ext/fast_mmaped_file_rs/Cargo.toml +40 -0
  4. data/ext/fast_mmaped_file_rs/README.md +52 -0
  5. data/ext/fast_mmaped_file_rs/build.rs +7 -0
  6. data/ext/fast_mmaped_file_rs/extconf.rb +28 -0
  7. data/ext/fast_mmaped_file_rs/src/error.rs +174 -0
  8. data/ext/fast_mmaped_file_rs/src/exemplars.rs +25 -0
  9. data/ext/fast_mmaped_file_rs/src/file_entry.rs +1252 -0
  10. data/ext/fast_mmaped_file_rs/src/file_info.rs +240 -0
  11. data/ext/fast_mmaped_file_rs/src/lib.rs +89 -0
  12. data/ext/fast_mmaped_file_rs/src/macros.rs +14 -0
  13. data/ext/fast_mmaped_file_rs/src/map.rs +519 -0
  14. data/ext/fast_mmaped_file_rs/src/metrics.proto +153 -0
  15. data/ext/fast_mmaped_file_rs/src/mmap/inner.rs +775 -0
  16. data/ext/fast_mmaped_file_rs/src/mmap.rs +977 -0
  17. data/ext/fast_mmaped_file_rs/src/raw_entry.rs +547 -0
  18. data/ext/fast_mmaped_file_rs/src/testhelper.rs +222 -0
  19. data/ext/fast_mmaped_file_rs/src/util.rs +140 -0
  20. data/lib/.DS_Store +0 -0
  21. data/lib/2.7/fast_mmaped_file_rs.so +0 -0
  22. data/lib/3.0/fast_mmaped_file_rs.so +0 -0
  23. data/lib/3.1/fast_mmaped_file_rs.so +0 -0
  24. data/lib/3.2/fast_mmaped_file_rs.so +0 -0
  25. data/lib/3.3/fast_mmaped_file_rs.so +0 -0
  26. data/lib/prometheus/.DS_Store +0 -0
  27. data/lib/prometheus/client/configuration.rb +24 -0
  28. data/lib/prometheus/client/counter.rb +27 -0
  29. data/lib/prometheus/client/formats/protobuf.rb +93 -0
  30. data/lib/prometheus/client/formats/text.rb +85 -0
  31. data/lib/prometheus/client/gauge.rb +40 -0
  32. data/lib/prometheus/client/helper/entry_parser.rb +132 -0
  33. data/lib/prometheus/client/helper/file_locker.rb +50 -0
  34. data/lib/prometheus/client/helper/json_parser.rb +23 -0
  35. data/lib/prometheus/client/helper/metrics_processing.rb +45 -0
  36. data/lib/prometheus/client/helper/metrics_representation.rb +51 -0
  37. data/lib/prometheus/client/helper/mmaped_file.rb +64 -0
  38. data/lib/prometheus/client/helper/plain_file.rb +29 -0
  39. data/lib/prometheus/client/histogram.rb +80 -0
  40. data/lib/prometheus/client/label_set_validator.rb +85 -0
  41. data/lib/prometheus/client/metric.rb +80 -0
  42. data/lib/prometheus/client/mmaped_dict.rb +83 -0
  43. data/lib/prometheus/client/mmaped_value.rb +164 -0
  44. data/lib/prometheus/client/page_size.rb +17 -0
  45. data/lib/prometheus/client/push.rb +203 -0
  46. data/lib/prometheus/client/rack/collector.rb +88 -0
  47. data/lib/prometheus/client/rack/exporter.rb +102 -0
  48. data/lib/prometheus/client/registry.rb +65 -0
  49. data/lib/prometheus/client/simple_value.rb +31 -0
  50. data/lib/prometheus/client/summary.rb +69 -0
  51. data/lib/prometheus/client/support/puma.rb +44 -0
  52. data/lib/prometheus/client/support/unicorn.rb +35 -0
  53. data/lib/prometheus/client/uses_value_type.rb +20 -0
  54. data/lib/prometheus/client/version.rb +5 -0
  55. data/lib/prometheus/client.rb +58 -0
  56. data/lib/prometheus.rb +3 -0
  57. 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,5 @@
1
+ # vinted-prometheus-client-mmap
2
+
3
+ ### ! This gem is part of the Engineering Hackathon, not to be used in production
4
+
5
+ Forked prometheus-client-mmap gem
@@ -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,7 @@
1
+ fn main() -> Result<(), Box<dyn std::error::Error>> {
2
+ let _ = rb_sys_env::activate()?;
3
+ prost_build::compile_protos(&["src/metrics.proto"], &["src/"])
4
+ .expect("failed compile protobufs");
5
+
6
+ Ok(())
7
+ }
@@ -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.