fast-prometheus 0.3.1 → 0.3.2
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/CHANGELOG.md +14 -0
- data/README.md +3 -3
- data/lib/fast/prometheus/formats/protobuf.rb +20 -21
- data/lib/fast/prometheus/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 25cba069a74bd1f00499ff8d2c3a3feb84e9646b1447de704d2dff860dc5cea4
|
|
4
|
+
data.tar.gz: 533131b2461c719cb5525695a5abdc26b474bc6ce9fe35ba338855a698e887a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c0a779b8563993d01400a7587852f2ec65c65621facd1bd3e9c44d39404e44eff0656a137a12f6a8da1b60b902d6bfe897b35ab82627064c8238f005171d0623
|
|
7
|
+
data.tar.gz: 8b9c2ce522dc9360c40f1779b7e4240370e5a7dbe4e6b333f9c39583bf2ba5a43805aa4b523763322ca62716b23c619047291beff28cb5b33abe88ad7874f96c
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.2] - 2026-09-19
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- `Formats::Protobuf.render` writes each family and each series straight
|
|
15
|
+
into the output behind a length prefix reserved first and filled in after
|
|
16
|
+
(`Fast::Protowire::Wire.reserve_length` / `close_length` /
|
|
17
|
+
`append_length_delimited_from`), instead of encoding the family header
|
|
18
|
+
to a String and copying every series out of a scratch buffer. Same
|
|
19
|
+
bytes; at 36,000 series x 12 labels a render went from 0.151 s and 29
|
|
20
|
+
objects to 0.144 s and 24, a protobuf scrape over HTTP from 0.162 s to
|
|
21
|
+
0.151 s (0.200 s to 0.192 s with gzip). Benchmarks page and README
|
|
22
|
+
updated.
|
|
23
|
+
|
|
10
24
|
## [0.3.1] - 2026-09-19
|
|
11
25
|
|
|
12
26
|
### Changed
|
data/README.md
CHANGED
|
@@ -94,13 +94,13 @@ Single process, locked, thread-safe by default (`benchmark-ips` and allocation
|
|
|
94
94
|
comparisons against `prometheus-client` and `google-protobuf`; see
|
|
95
95
|
[the benchmarks page](docs/explanation/benchmarks.md) for the full runs and conditions):
|
|
96
96
|
|
|
97
|
-
- A protobuf scrape of 36,000 series renders in **
|
|
97
|
+
- A protobuf scrape of 36,000 series renders in **24 objects**, where the
|
|
98
98
|
`google-protobuf` encoder needed 3.5 million Ruby objects and 504k native arenas, and
|
|
99
99
|
in a hundredth of the GC time; taking the snapshot it reads is 1 ms and one Hash per metric
|
|
100
100
|
- The text renderer allocates **66x fewer objects** than prometheus-client's formatter
|
|
101
101
|
for the same body, and renders it 3.2x faster at 36,000 series
|
|
102
|
-
- Bound counter and gauge writes allocate nothing and are **1.
|
|
103
|
-
prometheus-client's; histogram observe is **3.
|
|
102
|
+
- Bound counter and gauge writes allocate nothing and are **1.45x** faster than
|
|
103
|
+
prometheus-client's; histogram observe is **3.1x** faster and summary observe **3.3x**
|
|
104
104
|
- Native histogram observe runs at **1.32M i/s** with no prometheus-client equivalent
|
|
105
105
|
|
|
106
106
|
## Development
|
|
@@ -12,10 +12,10 @@ module Fast
|
|
|
12
12
|
# Each family's header is a declared Proto::MetricFamily; the series
|
|
13
13
|
# under it are written straight to the wire with Fast::Protowire::Wire,
|
|
14
14
|
# no LabelPair/Metric/Counter objects, because a scrape's series count
|
|
15
|
-
# is the one thing here that is large.
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
15
|
+
# is the one thing here that is large. Each series' bytes are written
|
|
16
|
+
# straight into the output behind a length prefix filled in after them,
|
|
17
|
+
# so rendering allocates nothing per series and copies nothing. Native
|
|
18
|
+
# histograms, few and irregular,
|
|
19
19
|
# still go through Proto::Histogram. Bytes are identical to what the
|
|
20
20
|
# declared classes (and google-protobuf) produce; the tests check.
|
|
21
21
|
module Protobuf
|
|
@@ -64,32 +64,31 @@ module Fast
|
|
|
64
64
|
DOUBLE_SIZE = 9
|
|
65
65
|
private_constant :DOUBLE_SIZE
|
|
66
66
|
|
|
67
|
-
# One varint-length-prefixed MetricFamily frame per metric
|
|
67
|
+
# One varint-length-prefixed MetricFamily frame per metric, each
|
|
68
|
+
# written straight into the output behind a length prefix reserved
|
|
69
|
+
# first and filled in after (see Fast::Protowire::Wire).
|
|
68
70
|
def self.render(snapshot)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Fast::Protowire::Wire.
|
|
73
|
-
buffer << family
|
|
71
|
+
snapshot.metrics.each_with_object(String.new) do |ms, out|
|
|
72
|
+
start = Fast::Protowire::Wire.reserve_length(out)
|
|
73
|
+
append_metric_family(out, ms)
|
|
74
|
+
Fast::Protowire::Wire.close_length(out, start)
|
|
74
75
|
end
|
|
75
76
|
end
|
|
76
77
|
|
|
77
78
|
# A family's bytes are its header (name, help, type) followed by one
|
|
78
|
-
# metric entry per series,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
# metric entry per series, in place. A family's series are alike, so
|
|
80
|
+
# the entry prefix width carries from one to the next.
|
|
81
|
+
private_class_method def self.append_metric_family(out, metric_snapshot)
|
|
82
|
+
Proto::MetricFamily.new(name: metric_snapshot.name.name, help: metric_snapshot.docstring,
|
|
83
|
+
type: TYPE_MAP.fetch(metric_snapshot.type)).encode(out)
|
|
82
84
|
type = metric_snapshot.type
|
|
83
85
|
names = metric_snapshot.label_names
|
|
84
|
-
|
|
86
|
+
width = 1
|
|
85
87
|
metric_snapshot.series.each_pair do |values, value|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
Fast::Protowire::Wire.append_varint(buffer, scratch.bytesize)
|
|
90
|
-
buffer << scratch
|
|
88
|
+
width = Fast::Protowire::Wire.append_length_delimited_from(out, FAMILY_METRIC, width) do |buffer|
|
|
89
|
+
append_metric(buffer, names, values, value, type)
|
|
90
|
+
end
|
|
91
91
|
end
|
|
92
|
-
buffer
|
|
93
92
|
end
|
|
94
93
|
|
|
95
94
|
# Metric: labels (1) then the one value field for the type, in
|