Skip to content

Commit

Permalink
Merge pull request prometheus#66 from Envek/add-thread-safe-inc-dec-t…
Browse files Browse the repository at this point in the history
…o-gauge

Add thread safe increment and decrement operations to gauges
  • Loading branch information
grobie authored Jul 27, 2017
2 parents 7d69b00 + cefaee4 commit fcc77b9
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@ gauge.get({ room: 'kitchen' })
# => 21.534
```

Also you can use gauge as the bi-directional counter:

```ruby
gauge = Prometheus::Client::Gauge.new(:concurrent_requests_total, '...')

gauge.increment({ service: 'foo' })
# => 1.0

gauge.decrement({ service: 'foo' })
# => 0.0
```

### Histogram

A histogram samples observations (usually things like request durations or
Expand Down
20 changes: 20 additions & 0 deletions lib/prometheus/client/gauge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,26 @@ def set(labels, value)

@values[label_set_for(labels)] = value.to_f
end

# Increments Gauge value by 1 or adds the given value to the Gauge.
# (The value can be negative, resulting in a decrease of the Gauge.)
def increment(labels = {}, by = 1)
label_set = label_set_for(labels)
synchronize do
@values[label_set] ||= 0
@values[label_set] += by
end
end

# Decrements Gauge value by 1 or subtracts the given value from the Gauge.
# (The value can be negative, resulting in a increase of the Gauge.)
def decrement(labels = {}, by = 1)
label_set = label_set_for(labels)
synchronize do
@values[label_set] ||= 0
@values[label_set] -= by
end
end
end
end
end
80 changes: 80 additions & 0 deletions spec/prometheus/client/gauge_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,84 @@
end
end
end

describe '#increment' do
before do
gauge.set(RSpec.current_example.metadata[:labels] || {}, 0)
end

it 'increments the gauge' do
expect do
gauge.increment
end.to change { gauge.get }.by(1.0)
end

it 'increments the gauge for a given label set', labels: { test: 'one' } do
expect do
expect do
gauge.increment(test: 'one')
end.to change { gauge.get(test: 'one') }.by(1.0)
end.to_not change { gauge.get(test: 'another') }
end

it 'increments the gauge by a given value' do
expect do
gauge.increment({}, 5)
end.to change { gauge.get }.by(5.0)
end

it 'returns the new gauge value' do
expect(gauge.increment).to eql(1.0)
end

it 'is thread safe' do
expect do
Array.new(10) do
Thread.new do
10.times { gauge.increment }
end
end.each(&:join)
end.to change { gauge.get }.by(100.0)
end
end

describe '#decrement' do
before do
gauge.set(RSpec.current_example.metadata[:labels] || {}, 0)
end

it 'increments the gauge' do
expect do
gauge.decrement
end.to change { gauge.get }.by(-1.0)
end

it 'decrements the gauge for a given label set', labels: { test: 'one' } do
expect do
expect do
gauge.decrement(test: 'one')
end.to change { gauge.get(test: 'one') }.by(-1.0)
end.to_not change { gauge.get(test: 'another') }
end

it 'decrements the gauge by a given value' do
expect do
gauge.decrement({}, 5)
end.to change { gauge.get }.by(-5.0)
end

it 'returns the new gauge value' do
expect(gauge.decrement).to eql(-1.0)
end

it 'is thread safe' do
expect do
Array.new(10) do
Thread.new do
10.times { gauge.decrement }
end
end.each(&:join)
end.to change { gauge.get }.by(-100.0)
end
end
end

0 comments on commit fcc77b9

Please sign in to comment.