Skip to content

Commit d2ebc02

Browse files
author
Chris Sinjakli
committed
Support :all as an aggregation mode in DirectFileStore
We want to support exporting each process's individual value for gauges. To enable this, DirectFileStore needs a new aggregation mode - :all. Signed-off-by: Chris Sinjakli <chris@gocardless.com>
1 parent 982fe2e commit d2ebc02

2 files changed

Lines changed: 54 additions & 4 deletions

File tree

lib/prometheus/client/data_stores/direct_file_store.rb

Lines changed: 18 additions & 4 deletions
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:)
@@ -120,16 +120,30 @@ def all_values
120120
[k.to_sym, vs.first]
121121
end.to_h
122122

123+
if @values_aggregation_mode == ALL
124+
# TODO: Can I do this in a less gross way?
125+
pid = /(\d+)\.bin$/.match(file_path)[1]
126+
label_set[:pid] = pid
127+
end
128+
123129
stores_data[label_set] << v
124130
end
125131
ensure
126132
store.close if store
127133
end
128134
end
129135

130-
# Aggregate all the different values for each label_set
131-
stores_data.each_with_object({}) do |(label_set, values), acc|
132-
acc[label_set] = aggregate_values(values)
136+
if @values_aggregation_mode == ALL
137+
stores_data.each do |label_set, values|
138+
stores_data[label_set] = values.first
139+
end
140+
141+
stores_data
142+
else
143+
# Aggregate all the different values for each label_set
144+
stores_data.each_with_object({}) do |(label_set, values), acc|
145+
acc[label_set] = aggregate_values(values)
146+
end
133147
end
134148
end
135149

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).

0 commit comments

Comments
 (0)