Skip to content

Commit

Permalink
Add method adapters to metrics and filtering adapters
Browse files Browse the repository at this point in the history
  • Loading branch information
Keallar committed Sep 23, 2024
1 parent 4c6d9b5 commit 3ada934
Show file tree
Hide file tree
Showing 16 changed files with 172 additions and 21 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/.bundle/
/.yardoc
/.idea/
/_yardoc/
/coverage/
/doc/
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Added

- Ability to change metrics setting for individual adapter

## 0.13.0 - 2024-08-12

### Added

- Multiple expectations in RSpec matchers:

```ruby
Expand Down
3 changes: 2 additions & 1 deletion lib/yabeda.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def groups
end
end

# @return [Hash<String, Yabeda::BaseAdapter>] All loaded adapters
# @return [Hash<Symbol, Yabeda::BaseAdapter>] All loaded adapters
def adapters
@adapters ||= Concurrent::Hash.new
end
Expand Down Expand Up @@ -72,6 +72,7 @@ def register_adapter(name, instance)
next if metric.adapter && metric.adapter != name

instance.register!(metric)
metric.restrict_adapter! if metric.adapter == name
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/yabeda/counter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Counter < Metric
def increment(tags, by: 1)
all_tags = ::Yabeda::Tags.build(tags, group)
values[all_tags] += by
::Yabeda.adapters.each do |_, adapter|
adapters.each_value do |adapter|
adapter.perform_counter_increment!(self, all_tags, by)
end
values[all_tags]
Expand Down
5 changes: 1 addition & 4 deletions lib/yabeda/dsl/class_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,7 @@ def register_group_for(metric)
def register_metric_for_adapters(metric)
return ::Yabeda.adapters.each_value { |adapter| adapter.register!(metric) } if metric.adapter.nil?

adapter = ::Yabeda.adapters[metric.adapter]
raise ConfigurationError, "invalid adapter option in metric #{metric.inspect}" if adapter.nil?

adapter.register!(metric)
metric.restrict_adapter!
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/yabeda/gauge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Gauge < Metric
def set(tags, value)
all_tags = ::Yabeda::Tags.build(tags, group)
values[all_tags] = value
::Yabeda.adapters.each do |_, adapter|
adapters.each_value do |adapter|
adapter.perform_gauge_set!(self, all_tags, value)
end
value
Expand Down
2 changes: 1 addition & 1 deletion lib/yabeda/histogram.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def measure(tags, value = nil)

all_tags = ::Yabeda::Tags.build(tags, group)
values[all_tags] = value
::Yabeda.adapters.each_value do |adapter|
adapters.each_value do |adapter|
adapter.perform_histogram_measure!(self, all_tags, value)
end
value
Expand Down
23 changes: 21 additions & 2 deletions lib/yabeda/metric.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ class Metric
option :per, optional: true, comment: "Per which unit is measured `unit`. E.g. `call` as in seconds per call"
option :group, optional: true, comment: "Category name for grouping metrics"
option :aggregation, optional: true, comment: "How adapters should aggregate values from different processes"
option :adapter, optional: true, comment: "Which adapter apply the indicator settings."
# rubocop:disable Layout/LineLength
option :adapter, optional: true, comment: "Monitoring system adapter to register metric in and report metric values to (other adapters won't be used)"
# rubocop:enable Layout/LineLength

# Returns the value for the given label set
def get(labels = {})
Expand All @@ -26,13 +28,30 @@ def values
end

# Returns allowed tags for metric (with account for global and group-level +default_tags+)
# @return Array<Symbol>
# @return [Array<Symbol>]
def tags
(Yabeda.groups[group].default_tags.keys + Array(super)).uniq
end

def inspect
"#<#{self.class.name}: #{[@group, @name].compact.join('.')}>"
end

# Returns the metric adapters
# @return [Hash<Symbol, Yabeda::BaseAdapter>]
def adapters
@adapters ||= ::Yabeda.adapters
end

# @return [Hash<Symbol, Yabeda::BaseAdapter> | null]
def restrict_adapter!
return if adapter.nil?

adapter_slice = ::Yabeda.adapters.slice(adapter)
raise ConfigurationError, "invalid adapter option in metric #{inspect}" if adapter_slice.empty?

adapter_slice[adapter].register!(self)
@adapters = adapter_slice
end
end
end
2 changes: 1 addition & 1 deletion lib/yabeda/summary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def observe(tags, value = nil)

all_tags = ::Yabeda::Tags.build(tags, group)
values[all_tags] = value
::Yabeda.adapters.each do |_, adapter|
adapters.each_value do |adapter|
adapter.perform_summary_observe!(self, all_tags, value)
end
value
Expand Down
22 changes: 22 additions & 0 deletions spec/yabeda/counter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,26 @@
increment_counter
expect(adapter).to have_received(:perform_counter_increment!).with(counter, built_tags, metric_value)
end

context "with adapter option" do
let(:counter) { Yabeda.counter_with_adapter }
let(:another_adapter) { instance_double(Yabeda::BaseAdapter, perform_counter_increment!: true, register!: true) }

before do
Yabeda.register_adapter(:another_adapter, another_adapter)
Yabeda.configure do
counter :counter_with_adapter, adapter: :test_adapter
end
Yabeda.configure! unless Yabeda.already_configured?
end

it "execute perform_counter_increment! method of adapter with name :test_adapter" do
increment_counter

aggregate_failures do
expect(adapter).to have_received(:perform_counter_increment!).with(counter, built_tags, metric_value)
expect(another_adapter).not_to have_received(:perform_counter_increment!)
end
end
end
end
11 changes: 9 additions & 2 deletions spec/yabeda/dsl/class_methods_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
let(:block) { proc { histogram :test_histogram, buckets: [42] } }

before do
Yabeda.register_adapter(:another_adapter, Yabeda::TestAdapter.instance)
Yabeda.configure! unless Yabeda.configured?
end

Expand All @@ -173,9 +174,15 @@
end

context "when got metric with adapter option" do
let(:block) { proc { histogram :invalid_test, buckets: [42], adapter: :invalid } }
let(:block) { proc { histogram :invalid_test, buckets: [42], adapter: :another_adapter } }

it { expect { configure }.to raise_error(Yabeda::ConfigurationError, /invalid adapter option in metric/) }
it { expect { configure }.not_to raise_error }

context "when option is invalid" do
let(:block) { proc { histogram :invalid_test, buckets: [42], adapter: :invalid } }

it { expect { configure }.to raise_error(Yabeda::ConfigurationError, /invalid adapter option in metric/) }
end
end
end
end
22 changes: 22 additions & 0 deletions spec/yabeda/gauge_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,26 @@
end
end
end

context "with adapter option" do
let(:gauge) { Yabeda.gauge_with_adapter }
let(:another_adapter) { instance_double(Yabeda::BaseAdapter, perform_gauge_set!: true, register!: true) }

before do
Yabeda.register_adapter(:another_adapter, another_adapter)
Yabeda.configure do
gauge :gauge_with_adapter, adapter: :test_adapter
end
Yabeda.configure! unless Yabeda.already_configured?
end

it "execute perform_counter_increment! method of adapter with name :test_adapter" do
set_gauge

aggregate_failures do
expect(adapter).to have_received(:perform_gauge_set!).with(gauge, built_tags, metric_value)
expect(another_adapter).not_to have_received(:perform_gauge_set!)
end
end
end
end
22 changes: 22 additions & 0 deletions spec/yabeda/histogram_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,26 @@
expect { measure_histogram }.to raise_error(ArgumentError)
end
end

context "with adapter option" do
let(:histogram) { Yabeda.histogram_with_adapter }
let(:another_adapter) { instance_double(Yabeda::BaseAdapter, perform_histogram_measure!: true, register!: true) }

before do
Yabeda.register_adapter(:another_adapter, another_adapter)
Yabeda.configure do
histogram :histogram_with_adapter, adapter: :test_adapter, buckets: [1, 10, 100]
end
Yabeda.configure! unless Yabeda.already_configured?
end

it "execute perform_counter_increment! method of adapter with name :test_adapter" do
measure_histogram

aggregate_failures do
expect(adapter).to have_received(:perform_histogram_measure!).with(histogram, built_tags, metric_value)
expect(another_adapter).not_to have_received(:perform_histogram_measure!)
end
end
end
end
18 changes: 18 additions & 0 deletions spec/yabeda/metric_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,22 @@
it { is_expected.to match_array(%i[foo bar baz]) }
end
end

describe "#restrict_adapter!" do
subject(:restrict_adapter!) { metric.restrict_adapter! }

let(:adapter) { instance_double(Yabeda::BaseAdapter, register!: true) }

before do
Yabeda.register_adapter(:test_adapter, adapter)
end

it { is_expected.to be_nil }

context "when adapter option is configured" do
let(:options) { { tags: %i[foo bar], adapter: :test_adapter } }

it { is_expected.to eq(Yabeda.adapters.slice(:test_adapter)) }
end
end
end
22 changes: 22 additions & 0 deletions spec/yabeda/summary_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,26 @@
expect { observe_summary }.to raise_error(ArgumentError)
end
end

context "with adapter option" do
let(:summary) { Yabeda.summary_with_adapter }
let(:another_adapter) { instance_double(Yabeda::BaseAdapter, perform_summary_observe!: true, register!: true) }

before do
Yabeda.register_adapter(:another_adapter, another_adapter)
Yabeda.configure do
summary :summary_with_adapter, adapter: :test_adapter
end
Yabeda.configure! unless Yabeda.already_configured?
end

it "execute perform_counter_increment! method of adapter with name :test_adapter" do
observe_summary

aggregate_failures do
expect(adapter).to have_received(:perform_summary_observe!).with(summary, built_tags, metric_value)
expect(another_adapter).not_to have_received(:perform_summary_observe!)
end
end
end
end
30 changes: 23 additions & 7 deletions spec/yabeda_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,22 @@
end

context "when set valid adapter option in metric" do
let(:adapter) { instance_double(Yabeda::BaseAdapter, register!: true) }
let(:adapter) { instance_double(Yabeda::BaseAdapter, register!: true, debug!: true) }

before do
Yabeda.configure { counter(:test_counter, adapter: :test_adapter) }
Yabeda.register_adapter(:test_adapter, adapter)
described_class.configure { counter(:test_counter, adapter: :test_adapter) }
described_class.register_adapter(:test_adapter, adapter)
end

it { expect { configure! }.to change(described_class, :configured?).to(true) }
end

context "when set invalid adapter option in metric" do
let(:adapter) { instance_double(Yabeda::BaseAdapter) }
let(:adapter) { instance_double(Yabeda::BaseAdapter, register!: true, debug!: true) }

before do
Yabeda.configure { counter(:test_counter, adapter: :invalid) }
Yabeda.register_adapter(:test_adapter, adapter)
described_class.configure { counter(:test_counter, adapter: :invalid) }
described_class.register_adapter(:test_adapter, adapter)
end

it { expect { configure! }.to raise_error(Yabeda::ConfigurationError, /invalid adapter option in metric/) }
Expand Down Expand Up @@ -126,7 +126,7 @@

before do
described_class.configure { histogram :test, buckets: [42] }
described_class.configure! unless Yabeda.configured?
described_class.configure! unless described_class.configured?
end

it "register metric for adapter" do
Expand All @@ -147,5 +147,21 @@
expect(adapter).not_to have_received(:register!)
end
end

context "when added another adapter" do
let(:another_adapter_name) { :another_test_adapter }
let(:another_adapter) { instance_double(Yabeda::BaseAdapter, register!: true) }

before do
described_class.register_adapter(another_adapter_name, another_adapter)
end

it "changes available adapters in registered metric" do
aggregate_failures do
expect { register_adapter }.to change(described_class.test.adapters, :size).by(1)
expect(another_adapter).to have_received(:register!)
end
end
end
end
end

0 comments on commit 3ada934

Please sign in to comment.