Skip to content

Commit 3652cf7

Browse files
author
Chris Sinjakli
authored
Merge pull request #127 from prometheus/sinjo-unaggregated-gauges
Support :all as an aggregation mode in DirectFileStore
2 parents 6ea675e + e66ab1b commit 3652cf7

File tree

5 files changed

+56
-4
lines changed

5 files changed

+56
-4
lines changed

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,15 @@ class MyComponent
256256
end
257257
```
258258

259+
### Reserved labels
260+
261+
The following labels are reserved by the client library, and attempting to use them in a
262+
metric definition will result in a
263+
`Prometheus::Client::LabelSetValidator::ReservedLabelError` being raised:
264+
265+
- `:job`
266+
- `:instance`
267+
- `:pid`
259268

260269
## Data Stores
261270

@@ -362,7 +371,8 @@ summing the values of each process.
362371

363372
For Gauges, however, this may not be the right thing to do, depending on what they're
364373
measuring. You might want to take the maximum or minimum value observed in any process,
365-
rather than the sum of all of them.
374+
rather than the sum of all of them. You may also want to export each process's individual
375+
value.
366376

367377
In those cases, you should use the `store_settings` parameter when registering the
368378
metric, to specify an `:aggregation` setting.

lib/prometheus/client/data_stores/direct_file_store.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module DataStores
2626

2727
class DirectFileStore
2828
class InvalidStoreSettingsError < StandardError; end
29-
AGGREGATION_MODES = [MAX = :max, MIN = :min, SUM = :sum]
29+
AGGREGATION_MODES = [MAX = :max, MIN = :min, SUM = :sum, ALL = :all]
3030
DEFAULT_METRIC_SETTINGS = { aggregation: SUM }
3131

3232
def initialize(dir:)
@@ -140,6 +140,10 @@ def in_process_sync
140140
end
141141

142142
def store_key(labels)
143+
if @values_aggregation_mode == ALL
144+
labels[:pid] = process_id
145+
end
146+
143147
labels.map{|k,v| "#{CGI::escape(k.to_s)}=#{CGI::escape(v.to_s)}"}.join('&')
144148
end
145149

@@ -168,6 +172,8 @@ def aggregate_values(values)
168172
values.max
169173
elsif @values_aggregation_mode == MIN
170174
values.min
175+
elsif @values_aggregation_mode == ALL
176+
values.first
171177
else
172178
raise InvalidStoreSettingsError,
173179
"Invalid Aggregation Mode: #{ @values_aggregation_mode }"

lib/prometheus/client/label_set_validator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Client
66
# Prometheus specification.
77
class LabelSetValidator
88
# TODO: we might allow setting :instance in the future
9-
BASE_RESERVED_LABELS = [:job, :instance].freeze
9+
BASE_RESERVED_LABELS = [:job, :instance, :pid].freeze
1010

1111
class LabelSetError < StandardError; end
1212
class InvalidLabelSetError < LabelSetError; end

spec/prometheus/client/data_stores/direct_file_store_spec.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,42 @@
150150
end
151151
end
152152

153+
context "with a metric that takes ALL instead of SUM" do
154+
it "reports all the values from different processes" do
155+
allow(Process).to receive(:pid).and_return(12345)
156+
metric_store1 = subject.for_metric(
157+
:metric_name,
158+
metric_type: :gauge,
159+
metric_settings: { aggregation: :all }
160+
)
161+
metric_store1.set(labels: { foo: "bar" }, val: 1)
162+
metric_store1.set(labels: { foo: "baz" }, val: 7)
163+
metric_store1.set(labels: { foo: "yyy" }, val: 3)
164+
165+
allow(Process).to receive(:pid).and_return(23456)
166+
metric_store2 = subject.for_metric(
167+
:metric_name,
168+
metric_type: :gauge,
169+
metric_settings: { aggregation: :all }
170+
)
171+
metric_store2.set(labels: { foo: "bar" }, val: 3)
172+
metric_store2.set(labels: { foo: "baz" }, val: 2)
173+
metric_store2.set(labels: { foo: "zzz" }, val: 1)
174+
175+
expect(metric_store1.all_values).to eq(
176+
{ foo: "bar", pid: "12345" } => 1.0,
177+
{ foo: "bar", pid: "23456" } => 3.0,
178+
{ foo: "baz", pid: "12345" } => 7.0,
179+
{ foo: "baz", pid: "23456" } => 2.0,
180+
{ foo: "yyy", pid: "12345" } => 3.0,
181+
{ foo: "zzz", pid: "23456" } => 1.0,
182+
)
183+
184+
# Both processes should return the same value
185+
expect(metric_store1.all_values).to eq(metric_store2.all_values)
186+
end
187+
end
188+
153189
it "resizes the File if metrics get too big" do
154190
truncate_calls_count = 0
155191
allow_any_instance_of(Prometheus::Client::DataStores::DirectFileStore::FileMappedDict).

spec/prometheus/client/label_set_validator_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
end
3838

3939
it 'raises ReservedLabelError if a label key is reserved' do
40-
[:job, :instance].each do |label|
40+
[:job, :instance, :pid].each do |label|
4141
expect do
4242
validator.validate_symbols!(label => 'value')
4343
end.to raise_exception(described_class::ReservedLabelError)

0 commit comments

Comments
 (0)