yabeda 0.11.0 → 0.13.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 262fe8c41ef493e3792e67b3e569f3820f8fc8de11a5795807d8d81efe8e0d9f
4
- data.tar.gz: d86b4a968f1894ce65af4976873135957a122672cd58453023d38792b60c4db7
3
+ metadata.gz: 8d2581bd55cdd41639a1c6f01d456c5e09e1ad7636253e92720d35242fde6fab
4
+ data.tar.gz: 02f88db1ee3d892e387129c8775ab1b31dbafe2ec97ea8a67c34ff6abf67dc1d
5
5
  SHA512:
6
- metadata.gz: 22c41d84fb0efbb8ca1802e02c1c4e6636fc8a2ae05c22775d4390ddc5ddfd0926b97464d6b2702e6b82a1b8709d66bf391bcb7aa6ed05df9a640a0143817889
7
- data.tar.gz: ad5e58fc8b678c0764b6d8f3677c56a08d087dcbc9407b3a6864fa0e85226a773dce2efaa365d8bed0d0c25db300829811688819a407dee86bcefbea439e2232
6
+ metadata.gz: 57c4e7b716b077e37b7191cf4bfcc4f7090943eab1922439d485e02bc925408f21db656e239545bd7836413fc219282e71553b4cbd88e02b80f272dc236bacfb
7
+ data.tar.gz: 63707a843e531b01e685e17f7772dcf718ab730d401396d936ade23a5f8e0a7699ddbf7799caca797afcb4ef0fb5c07cacfd362ff98f46949846f166de636b97
@@ -0,0 +1,37 @@
1
+ name: Lint Ruby
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - '**'
7
+ tags-ignore:
8
+ - 'v*'
9
+ paths:
10
+ - "gemfiles/*"
11
+ - "Gemfile"
12
+ - "**/*.rb"
13
+ - "**/*.gemspec"
14
+ - ".github/workflows/lint.yml"
15
+ pull_request:
16
+ paths:
17
+ - "gemfiles/*"
18
+ - "Gemfile"
19
+ - "**/*.rb"
20
+ - "**/*.gemspec"
21
+ - ".github/workflows/lint.yml"
22
+
23
+ jobs:
24
+ rubocop:
25
+ # Skip running tests for local pull requests (use push event instead), run only for foreign ones
26
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login != github.event.pull_request.base.repo.owner.login
27
+ name: RuboCop
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+ - uses: ruby/setup-ruby@v1
32
+ with:
33
+ ruby-version: "3.3"
34
+ bundler-cache: true
35
+ - name: Lint Ruby code with RuboCop
36
+ run: |
37
+ bundle exec rubocop
@@ -1,4 +1,4 @@
1
- name: Build and release gem to RubyGems
1
+ name: Build and release gem
2
2
 
3
3
  on:
4
4
  push:
@@ -8,13 +8,17 @@ on:
8
8
  jobs:
9
9
  release:
10
10
  runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: write
13
+ id-token: write
14
+ packages: write
11
15
  steps:
12
- - uses: actions/checkout@v2
16
+ - uses: actions/checkout@v4
13
17
  with:
14
18
  fetch-depth: 0 # Fetch current tag as annotated. See https://github.com/actions/checkout/issues/290
15
19
  - uses: ruby/setup-ruby@v1
16
20
  with:
17
- ruby-version: 2.7
21
+ ruby-version: "3.3"
18
22
  - name: "Extract data from tag: version, message, body"
19
23
  id: tag
20
24
  run: |
@@ -75,8 +79,8 @@ jobs:
75
79
  GEM_HOST_API_KEY: Bearer ${{ secrets.GITHUB_TOKEN }}
76
80
  run: |
77
81
  gem push yabeda-${{ steps.tag.outputs.version }}.gem --host https://rubygems.pkg.github.com/${{ github.repository_owner }}
82
+ - name: Configure RubyGems Credentials
83
+ uses: rubygems/configure-rubygems-credentials@main
78
84
  - name: Publish to RubyGems
79
- env:
80
- GEM_HOST_API_KEY: "${{ secrets.RUBYGEMS_API_KEY }}"
81
85
  run: |
82
86
  gem push yabeda-${{ steps.tag.outputs.version }}.gem
@@ -11,38 +11,23 @@ on:
11
11
  jobs:
12
12
  test:
13
13
  name: "Ruby ${{ matrix.ruby }}"
14
+ # Skip running tests for local pull requests (use push event instead), run only for foreign ones
15
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login != github.event.pull_request.base.repo.owner.login
14
16
  runs-on: ubuntu-latest
15
17
  strategy:
16
18
  fail-fast: false
17
19
  matrix:
18
20
  include:
21
+ - ruby: "3.3"
22
+ - ruby: "3.2"
23
+ - ruby: "3.1"
19
24
  - ruby: "3.0"
20
25
  - ruby: "2.7"
21
- - ruby: "2.6"
22
- - ruby: "2.5"
23
- - ruby: "2.4"
24
- - ruby: "2.3"
25
- container:
26
- image: ruby:${{ matrix.ruby }}
27
- env:
28
- CI: true
29
26
  steps:
30
- - uses: actions/checkout@v2
31
- - uses: actions/cache@v2
27
+ - uses: actions/checkout@v4
28
+ - uses: ruby/setup-ruby@v1
32
29
  with:
33
- path: vendor/bundle
34
- key: bundle-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}-${{ hashFiles('**/Gemfile') }}
35
- restore-keys: |
36
- bundle-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}-${{ hashFiles('**/Gemfile') }}
37
- bundle-${{ matrix.ruby }}-
38
- - name: Upgrade Bundler to 2.0 (for older Rubies)
39
- run: gem install bundler -v '~> 2.0'
40
- - name: Bundle install
41
- run: |
42
- bundle config path vendor/bundle
43
- bundle install
44
- bundle update
45
- - name: Run Rubocop
46
- run: bundle exec rubocop
30
+ ruby-version: ${{ matrix.ruby }}
31
+ bundler-cache: true
47
32
  - name: Run RSpec
48
33
  run: bundle exec rspec
data/.rubocop.yml CHANGED
@@ -10,6 +10,9 @@ Metrics/BlockLength:
10
10
  - "Gemfile"
11
11
  - "spec/**/*"
12
12
 
13
+ Metrics/AbcSize:
14
+ Max: 25
15
+
13
16
  Layout/LineLength:
14
17
  Max: 120
15
18
 
@@ -29,6 +32,12 @@ RSpec/DescribeClass:
29
32
  RSpec/NestedGroups:
30
33
  Max: 4
31
34
 
35
+ RSpec/MultipleMemoizedHelpers:
36
+ Enabled: false
37
+
38
+ RSpec/ExampleLength:
39
+ Max: 10
40
+
32
41
  Bundler/OrderedGems:
33
42
  Enabled: false
34
43
 
data/CHANGELOG.md CHANGED
@@ -7,6 +7,53 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## 0.13.0 - 2024-10-02
11
+
12
+ ### Added
13
+
14
+ - Ability to limit some metrics to specific adapters. [#37](https://github.com/yabeda-rb/yabeda/pull/37) by [@Keallar] and [@Envek]
15
+
16
+ ```ruby
17
+ Yabeda.configure do
18
+ group :cloud do
19
+ adapter :newrelic, :datadog
20
+
21
+ counter :foo
22
+ end
23
+
24
+ counter :bar, adapter: :prometheus
25
+ end
26
+ ```
27
+
28
+ - Multiple expectations in RSpec matchers. [@Envek]
29
+
30
+ ```ruby
31
+ expect { whatever }.to increment_yabeda_counter(:my_counter).with(
32
+ { tag: "foo" } => 1,
33
+ { tag: "bar" } => (be >= 42),
34
+ )
35
+ ```
36
+
37
+ ### Changed
38
+
39
+ - Don't require to provide tags for counters and histograms, use empty tags (`{}`) by default. See discussion at [#26](https://github.com/yabeda-rb/yabeda/issues/26). [@Envek]
40
+
41
+ ```ruby
42
+ Yabeda.foo.increment
43
+ # same as
44
+ Yabeda.foo.increment({}, by: 1)
45
+ ```
46
+
47
+ ### Fixed
48
+
49
+ - Railtie loading to prevent calling methods that have not yet been defined. [#38](https://github.com/yabeda-rb/yabeda/pull/38) by [@bibendi].
50
+
51
+ ## 0.12.0 - 2023-07-28
52
+
53
+ ### Added
54
+
55
+ - Summary metric type (mostly for Prometheus adapter).
56
+
10
57
  ## 0.11.0 - 2021-09-25
11
58
 
12
59
  ### Added
@@ -31,7 +78,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
31
78
 
32
79
  ### Changed
33
80
 
34
- - Adapters now should use method `Yabeda.collect!` instead of manual calling of every collector block.
81
+ - Adapters now should use method `Yabeda.collect!` instead of manual calling of every collector block.
35
82
 
36
83
  ## 0.9.0 - 2021-05-07
37
84
 
@@ -134,3 +181,5 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
134
181
  [@dsalahutdinov]: https://github.com/dsalahutdinov "Dmitry Salahutdinov"
135
182
  [@asusikov]: https://github.com/asusikov "Alexander Susikov"
136
183
  [@liaden]: https://github.com/liaden "Joel Johnson"
184
+ [@bibendi]: https://github.com/bibendi "Misha Merkushin"
185
+ [@Keallar]: https://github.com/Keallar "Eugene Lysanskiy"
data/Gemfile CHANGED
@@ -8,9 +8,14 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
8
8
  gemspec
9
9
 
10
10
  group :development, :test do
11
+ gem "rake", "~> 12.0"
12
+ gem "rspec", "~> 3.0"
13
+ gem "yard"
14
+ gem "yard-dry-initializer"
15
+
11
16
  gem "pry"
12
17
  gem "pry-byebug", platform: :mri
13
18
 
14
- gem "rubocop", "~> 0.80.0"
15
- gem "rubocop-rspec"
19
+ gem "rubocop", "~> 1.0", require: false
20
+ gem "rubocop-rspec", require: false
16
21
  end
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # ![Yabeda](./yabeda-logo.png)
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/yabeda.svg)](https://rubygems.org/gems/yabeda)
4
-
5
- **This software is Work in Progress: features will appear and disappear, API will be changed, your feedback is always welcome!**
4
+ [![Tests status](https://github.com/yabeda-rb/yabeda/actions/workflows/test.yml/badge.svg)](https://github.com/yabeda-rb/yabeda/actions/workflows/test.yml)
6
5
 
7
6
  Extendable solution for easy setup of monitoring in your Ruby apps.
8
7
 
@@ -18,6 +17,11 @@ Most of the time you don't need to add this gem to your Gemfile directly (unless
18
17
 
19
18
  ```ruby
20
19
  gem 'yabeda'
20
+
21
+ # Add some plugins to quickly start collecting some essential metrics:
22
+ # gem 'yabeda-rails'
23
+ # gem 'yabeda-sidekiq'
24
+
21
25
  # Then add monitoring system adapter, e.g.:
22
26
  # gem 'yabeda-prometheus'
23
27
  ```
@@ -39,6 +43,7 @@ And then execute:
39
43
  comment "How long whistles are being active"
40
44
  unit :seconds
41
45
  end
46
+ summary :bells_ringing_duration, unit: :seconds, comment: "How long bells are ringing"
42
47
  end
43
48
  end
44
49
  ```
@@ -124,6 +129,8 @@ And then execute:
124
129
  These are developed and maintained by other awesome folks:
125
130
 
126
131
  - [Statsd](https://github.com/asusikov/yabeda-statsd)
132
+ - [AWS CloudWatch](https://github.com/retsef/yabeda-cloudwatch)
133
+ - [Honeybadger Insights](https://github.com/honeybadger-io/yabeda-honeybadger_insights)
127
134
  - _…and more! You can write your own adapter and open a pull request to add it into this list._
128
135
 
129
136
  ## Available plugins to collect metrics
@@ -131,6 +138,7 @@ These are developed and maintained by other awesome folks:
131
138
  ### Maintained by Yabeda
132
139
 
133
140
  - [yabeda-rails] — basic request metrics for [Ruby on Rails](https://rubyonrails.org/) applications.
141
+ - [yabeda-activerecord] — query performance and connection pool stats for apps using ActiveRecord to query databases.
134
142
  - [yabeda-sidekiq] — comprehensive set of metrics for monitoring [Sidekiq](https://sidekiq.org/) jobs execution and queues.
135
143
  - [yabeda-faktory] — metrics for monitoring jobs execution by Ruby workers of [Faktory](https://contribsys.com/faktory/).
136
144
  - [yabeda-graphql] — metrics to query and field-level monitoring for apps using [GraphQL-Ruby](https://graphql-ruby.org/).
@@ -146,6 +154,10 @@ These are developed and maintained by other awesome folks:
146
154
  - [yabeda-grape](https://github.com/efigence/yabeda-grape) — metrics for [Grape](https://github.com/ruby-grape/grape) framework.
147
155
  - [yabeda-gruf](https://github.com/Placewise/yabeda-gruf) — metrics for [gRPC Ruby Framework](https://github.com/bigcommerce/gruf)
148
156
  - [yabeda-gc](https://github.com/ianks/yabeda-gc) — metrics for Ruby garbage collection.
157
+ - [yabeda-activejob](https://github.com/Fullscript/yabeda-activejob) — backend-agnostic metrics for background jobs.
158
+ - [yabeda-shoryuken](https://github.com/retsef/yabeda-shoryuken) — metrics for [Shoryuken](https://github.com/ruby-shoryuken/shoryuken) jobs execution message queues.
159
+ - [yabeda-rack-ratelimit](https://github.com/basecamp/yabeda-rack-ratelimit) — metrics for [Rack::Ratelimit](https://github.com/jeremy/rack-ratelimit)
160
+ - [yabeda-hanami](https://github.com/mlibrary/yabeda-hanami) — metrics for [Hanami](https://hanamirb.org/) The web, with simplicity.
149
161
  - _…and more! You can write your own adapter and open a pull request to add it into this list._
150
162
 
151
163
  ## Configuration
@@ -172,7 +184,7 @@ Add the following to your `rails_helper.rb` (or `spec_helper.rb`):
172
184
  require "yabeda/rspec"
173
185
  ```
174
186
 
175
- Now you can use `increment_yabeda_counter`, `update_yabeda_gauge`, and `measure_yabeda_histogram` matchers:
187
+ Now you can use `increment_yabeda_counter`, `update_yabeda_gauge`, `measure_yabeda_histogram`, and `observe_yabeda_summary` matchers:
176
188
 
177
189
  ```ruby
178
190
  it "increments counters" do
@@ -192,7 +204,7 @@ end
192
204
 
193
205
  Note that tags you specified doesn't need to be exact, but can be a subset of tags used on metric update. In this example updates with following sets of tags `{ method: "command", command: "subscribe", status: "SUCCESS" }` and `{ method: "command", command: "subscribe", status: "FAILURE" }` will make test example to pass.
194
206
 
195
- And check for values with `by` for counters, `to` for gauges, and `with` for gauges and histograms (and you [can use other matchers here](https://relishapp.com/rspec/rspec-expectations/v/3-10/docs/composing-matchers)):
207
+ And check for values with `by` for counters, `to` for gauges, and `with` for histograms and summaries (and you [can use other matchers here](https://relishapp.com/rspec/rspec-expectations/v/3-10/docs/composing-matchers)):
196
208
 
197
209
  ```ruby
198
210
  expect { subject }.to \
@@ -200,6 +212,41 @@ expect { subject }.to \
200
212
  with(be_between(0.005, 0.05))
201
213
  ```
202
214
 
215
+ You also can specify multiple tags and their expected values in `with`:
216
+
217
+ ```ruby
218
+ expect { whatever }.to increment_yabeda_counter(:my_counter).with(
219
+ { tag: "foo" } => 1,
220
+ { tag: "bar" } => (be >= 42),
221
+ )
222
+ ```
223
+
224
+ ## Advanced usage
225
+
226
+ ### Limiting metrics and groups to specific adapters
227
+
228
+ You can limit, which metrics and groups should be available for specific adapter:
229
+
230
+ ```ruby
231
+ Yabeda.configure do
232
+ group :internal do
233
+ adapter :prometheus
234
+
235
+ counter :foo
236
+ gauge :bar
237
+ end
238
+
239
+ group :cloud do
240
+ adapter :newrelic
241
+
242
+ counter :baz
243
+ end
244
+
245
+ counter :qux, adapter: :prometheus
246
+ end
247
+ ```
248
+
249
+
203
250
  ## Roadmap (aka TODO or Help wanted)
204
251
 
205
252
  - Ability to change metric settings for individual adapters
@@ -212,16 +259,6 @@ expect { subject }.to \
212
259
  end
213
260
  ```
214
261
 
215
- - Ability to route some metrics only for given adapter:
216
-
217
- ```rb
218
- adapter :prometheus do
219
- include_group :sidekiq
220
- end
221
- ```
222
-
223
-
224
-
225
262
  ## Development
226
263
 
227
264
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -267,6 +304,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/yabeda
267
304
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
268
305
 
269
306
  [yabeda-rails]: https://github.com/yabeda-rb/yabeda-rails/ "Yabeda plugin for collecting and exporting basic metrics for Rails applications"
307
+ [yabeda-activerecord]: https://github.com/yabeda-rb/yabeda-activerecord/ "Yabeda plugin to collect query performance metrics and connection pool statistics"
270
308
  [yabeda-sidekiq]: https://github.com/yabeda-rb/yabeda-sidekiq/ "Yabeda plugin for complete monitoring of Sidekiq metrics"
271
309
  [yabeda-faktory]: https://github.com/yabeda-rb/yabeda-faktory/ "Yabeda plugin for complete monitoring of Faktory Ruby Workers"
272
310
  [yabeda-graphql]: https://github.com/yabeda-rb/yabeda-graphql/ "Measure and understand how good your GraphQL-Ruby application works"
@@ -8,6 +8,7 @@ module Yabeda
8
8
  when Counter then register_counter!(metric)
9
9
  when Gauge then register_gauge!(metric)
10
10
  when Histogram then register_histogram!(metric)
11
+ when Summary then register_summary!(metric)
11
12
  else raise "#{metric.class} is unknown metric type"
12
13
  end
13
14
  end
@@ -36,6 +37,14 @@ module Yabeda
36
37
  raise NotImplementedError, "#{self.class} doesn't support measuring histograms"
37
38
  end
38
39
 
40
+ def register_summary!(_metric)
41
+ raise NotImplementedError, "#{self.class} doesn't support summaries as metric type!"
42
+ end
43
+
44
+ def perform_summary_observe!(_metric, _tags, _value)
45
+ raise NotImplementedError, "#{self.class} doesn't support observing summaries"
46
+ end
47
+
39
48
  # Hook to enable debug mode in adapters when it is enabled in Yabeda itself
40
49
  def debug!; end
41
50
  end
@@ -3,10 +3,10 @@
3
3
  module Yabeda
4
4
  # Growing-only counter
5
5
  class Counter < Metric
6
- def increment(tags, by: 1)
6
+ def increment(tags = {}, by: 1)
7
7
  all_tags = ::Yabeda::Tags.build(tags, group)
8
8
  values[all_tags] += by
9
- ::Yabeda.adapters.each do |_, adapter|
9
+ adapters.each_value do |adapter|
10
10
  adapter.perform_counter_increment!(self, all_tags, by)
11
11
  end
12
12
  values[all_tags]
@@ -4,6 +4,7 @@ require "yabeda/metric"
4
4
  require "yabeda/counter"
5
5
  require "yabeda/gauge"
6
6
  require "yabeda/histogram"
7
+ require "yabeda/summary"
7
8
  require "yabeda/group"
8
9
  require "yabeda/global_group"
9
10
  require "yabeda/dsl/metric_builder"
@@ -55,6 +56,12 @@ module Yabeda
55
56
  register_metric(metric)
56
57
  end
57
58
 
59
+ # Register a summary
60
+ def summary(*args, **kwargs, &block)
61
+ metric = MetricBuilder.new(Summary).build(args, kwargs, @group, &block)
62
+ register_metric(metric)
63
+ end
64
+
58
65
  # Add default tag for all metric
59
66
  #
60
67
  # @param name [Symbol] Name of default tag
@@ -85,6 +92,16 @@ module Yabeda
85
92
  Thread.current[:yabeda_temporary_tags] ||= {}
86
93
  end
87
94
 
95
+ # Limit all group metrics to specific adapters only
96
+ #
97
+ # @param adapter_names [Array<Symbol>] Names of adapters to use
98
+ def adapter(*adapter_names, group: @group)
99
+ raise ConfigurationError, "Adapter limitation can't be defined outside of group" unless group
100
+
101
+ Yabeda.groups[group] ||= Yabeda::Group.new(group)
102
+ Yabeda.groups[group].adapter(*adapter_names)
103
+ end
104
+
88
105
  private
89
106
 
90
107
  def register_metric(metric)
@@ -92,7 +109,7 @@ module Yabeda
92
109
  ::Yabeda.define_singleton_method(name) { metric }
93
110
  ::Yabeda.metrics[name] = metric
94
111
  register_group_for(metric) if metric.group
95
- ::Yabeda.adapters.each_value { |adapter| adapter.register!(metric) } if ::Yabeda.configured?
112
+ metric.adapters.each_value { |adapter| adapter.register!(metric) } if ::Yabeda.configured?
96
113
  metric
97
114
  end
98
115
 
data/lib/yabeda/gauge.rb CHANGED
@@ -6,17 +6,17 @@ module Yabeda
6
6
  def set(tags, value)
7
7
  all_tags = ::Yabeda::Tags.build(tags, group)
8
8
  values[all_tags] = value
9
- ::Yabeda.adapters.each do |_, adapter|
9
+ adapters.each_value do |adapter|
10
10
  adapter.perform_gauge_set!(self, all_tags, value)
11
11
  end
12
12
  value
13
13
  end
14
14
 
15
- def increment(tags, by: 1)
15
+ def increment(tags = {}, by: 1)
16
16
  set(tags, get(tags).to_i + by)
17
17
  end
18
18
 
19
- def decrement(tags, by: 1)
19
+ def decrement(tags = {}, by: 1)
20
20
  set(tags, get(tags).to_i - by)
21
21
  end
22
22
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "forwardable"
4
- require_relative "./group"
4
+ require_relative "group"
5
5
 
6
6
  module Yabeda
7
7
  # Represents implicit global group
data/lib/yabeda/group.rb CHANGED
@@ -19,6 +19,13 @@ module Yabeda
19
19
  @default_tags[key] = value
20
20
  end
21
21
 
22
+ def adapter(*adapter_names)
23
+ return @adapter if adapter_names.empty?
24
+
25
+ @adapter ||= Concurrent::Array.new
26
+ @adapter.push(*adapter_names)
27
+ end
28
+
22
29
  def register_metric(metric)
23
30
  define_singleton_method(metric.name) { metric }
24
31
  end
@@ -7,7 +7,7 @@ module Yabeda
7
7
  option :buckets
8
8
 
9
9
  # rubocop: disable Metrics/MethodLength
10
- def measure(tags, value = nil)
10
+ def measure(tags = {}, value = nil)
11
11
  if value.nil? ^ block_given?
12
12
  raise ArgumentError, "You must provide either numeric value or block for Yabeda::Histogram#measure!"
13
13
  end
@@ -20,7 +20,7 @@ module Yabeda
20
20
 
21
21
  all_tags = ::Yabeda::Tags.build(tags, group)
22
22
  values[all_tags] = value
23
- ::Yabeda.adapters.each do |_, adapter|
23
+ adapters.each_value do |adapter|
24
24
  adapter.perform_histogram_measure!(self, all_tags, value)
25
25
  end
26
26
  value
data/lib/yabeda/metric.rb CHANGED
@@ -14,6 +14,9 @@ module Yabeda
14
14
  option :per, optional: true, comment: "Per which unit is measured `unit`. E.g. `call` as in seconds per call"
15
15
  option :group, optional: true, comment: "Category name for grouping metrics"
16
16
  option :aggregation, optional: true, comment: "How adapters should aggregate values from different processes"
17
+ # rubocop:disable Layout/LineLength
18
+ option :adapter, optional: true, comment: "Monitoring system adapter to register metric in and report metric values to (other adapters won't be used)"
19
+ # rubocop:enable Layout/LineLength
17
20
 
18
21
  # Returns the value for the given label set
19
22
  def get(labels = {})
@@ -25,7 +28,7 @@ module Yabeda
25
28
  end
26
29
 
27
30
  # Returns allowed tags for metric (with account for global and group-level +default_tags+)
28
- # @return Array<Symbol>
31
+ # @return [Array<Symbol>]
29
32
  def tags
30
33
  (Yabeda.groups[group].default_tags.keys + Array(super)).uniq
31
34
  end
@@ -33,5 +36,31 @@ module Yabeda
33
36
  def inspect
34
37
  "#<#{self.class.name}: #{[@group, @name].compact.join('.')}>"
35
38
  end
39
+
40
+ # Returns the metric adapters
41
+ # @return [Hash<Symbol, Yabeda::BaseAdapter>]
42
+ def adapters
43
+ return ::Yabeda.adapters unless adapter
44
+
45
+ @adapters ||= begin
46
+ adapter_names = Array(adapter)
47
+ unknown_adapters = adapter_names - ::Yabeda.adapters.keys
48
+
49
+ if unknown_adapters.any?
50
+ raise ConfigurationError,
51
+ "invalid adapter option #{adapter.inspect} in metric #{inspect}"
52
+ end
53
+
54
+ ::Yabeda.adapters.slice(*adapter_names)
55
+ end
56
+ end
57
+
58
+ # Redefined option reader to get group-level adapter if not set on metric level
59
+ # @api private
60
+ def adapter
61
+ return ::Yabeda.groups[group]&.adapter if @adapter == Dry::Initializer::UNDEFINED
62
+
63
+ super
64
+ end
36
65
  end
37
66
  end
@@ -8,20 +8,30 @@ module Yabeda
8
8
  # Example:
9
9
  # expect { anything }.to do_whatever_with_yabeda_metric(Yabeda.something)
10
10
  class BaseMatcher < ::RSpec::Matchers::BuiltIn::BaseMatcher
11
- attr_reader :tags, :metric
11
+ attr_reader :tags, :metric, :expectations
12
12
 
13
13
  # Specify a scope of labels (tags). Subset of tags can be specified.
14
14
  def with_tags(tags)
15
+ raise ArgumentError, "Can't use `with_tags` with expectations hash provided" if !@tags && @expectations&.any?
16
+
15
17
  @tags = tags
18
+ @expectations = { tags => nil }
19
+ self
20
+ end
21
+
22
+ def with(expectations)
23
+ @expectations = expectations || {}
16
24
  self
17
25
  end
18
26
 
19
- def initialize(expected)
20
- @expected = @metric = resolve_metric(expected)
27
+ def initialize(metric)
28
+ super
29
+ @expected = @metric = resolve_metric(metric)
30
+ @expectations = {}
21
31
  rescue KeyError
22
32
  raise ArgumentError, <<~MSG
23
33
  Pass metric name or metric instance to matcher (e.g. `increment_yabeda_counter(Yabeda.metric_name)` or \
24
- increment_yabeda_counter('metric_name')). Got #{expected.inspect} instead
34
+ increment_yabeda_counter('metric_name')). Got #{metric.inspect} instead
25
35
  MSG
26
36
  end
27
37
 
@@ -55,9 +65,11 @@ module Yabeda
55
65
  # Filter metric changes by tags.
56
66
  # If tags specified, treat them as subset of real tags (to avoid bothering with default tags in tests)
57
67
  def filter_matching_changes(changes)
58
- return changes if tags.nil?
68
+ return changes.map { |tags, change| [tags, [nil, change]] }.to_h unless expectations&.any?
59
69
 
60
- changes.select { |t, _v| t >= tags }
70
+ expectations.map do |tags, expected|
71
+ [tags, [expected, changes.find { |t, _v| t >= tags }&.[](1)]]
72
+ end.to_h
61
73
  end
62
74
  end
63
75
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./base_matcher"
3
+ require_relative "base_matcher"
4
4
 
5
5
  module Yabeda
6
6
  module RSpec
@@ -15,6 +15,7 @@ module Yabeda
15
15
  class IncrementYabedaCounter < BaseMatcher
16
16
  def by(increment)
17
17
  @expected_increment = increment
18
+ @expectations = { tags => increment } if tags
18
19
  self
19
20
  end
20
21
 
@@ -32,8 +33,12 @@ module Yabeda
32
33
 
33
34
  increments = filter_matching_changes(Yabeda::TestAdapter.instance.counters.fetch(metric))
34
35
 
35
- increments.values.any? do |actual_increment|
36
- expected_increment.nil? || values_match?(expected_increment, actual_increment)
36
+ return false if increments.empty?
37
+
38
+ increments.values.all? do |expected_increment, actual_increment|
39
+ next !actual_increment.nil? if expected_increment.nil?
40
+
41
+ values_match?(expected_increment, actual_increment)
37
42
  end
38
43
  end
39
44
 
@@ -49,21 +54,27 @@ module Yabeda
49
54
 
50
55
  increments = filter_matching_changes(Yabeda::TestAdapter.instance.counters.fetch(metric))
51
56
 
52
- increments.none?
57
+ increments.none? { |_tags, (_expected, actual)| !actual.nil? }
53
58
  end
54
59
 
55
60
  def failure_message
56
61
  "expected #{expected_formatted} " \
57
- "to be incremented #{"by #{description_of(expected_increment)} " unless expected_increment.nil?}" \
58
- "#{("with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags)}" \
59
- "but #{actual_increments_message}"
62
+ "to be incremented #{"by #{description_of(expected_increment)} " unless expected_increment.nil?}" \
63
+ "#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
64
+ "#{if !tags && expectations
65
+ "with following expectations: #{::RSpec::Support::ObjectFormatter.format(expectations)} "
66
+ end}" \
67
+ "but #{actual_increments_message}"
60
68
  end
61
69
 
62
70
  def failure_message_when_negated
63
71
  "expected #{expected_formatted} " \
64
- "not to be incremented " \
65
- "#{("with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags)}" \
66
- "but #{actual_increments_message}"
72
+ "not to be incremented " \
73
+ "#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
74
+ "#{if !tags && expectations
75
+ "with following expectations: #{::RSpec::Support::ObjectFormatter.format(expectations)} "
76
+ end}" \
77
+ "but #{actual_increments_message}"
67
78
  end
68
79
 
69
80
  def actual_increments_message
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./base_matcher"
3
+ require_relative "base_matcher"
4
4
 
5
5
  module Yabeda
6
6
  module RSpec
@@ -14,6 +14,8 @@ module Yabeda
14
14
  # Custom matcher class with implementation for +measure_yabeda_histogram+
15
15
  class MeasureYabedaHistogram < BaseMatcher
16
16
  def with(value)
17
+ return super if value.is_a?(Hash)
18
+
17
19
  @expected_value = value
18
20
  self
19
21
  end
@@ -32,7 +34,13 @@ module Yabeda
32
34
 
33
35
  measures = filter_matching_changes(Yabeda::TestAdapter.instance.histograms.fetch(metric))
34
36
 
35
- measures.values.any? { |measure| expected_value.nil? || values_match?(expected_value, measure) }
37
+ return false if measures.empty?
38
+
39
+ measures.values.all? do |expected_measure, actual_measure|
40
+ next !actual_measure.nil? if expected_measure.nil?
41
+
42
+ values_match?(expected_measure, actual_measure)
43
+ end
36
44
  end
37
45
 
38
46
  def match_when_negated(metric, block)
@@ -47,21 +55,27 @@ module Yabeda
47
55
 
48
56
  measures = filter_matching_changes(Yabeda::TestAdapter.instance.histograms.fetch(metric))
49
57
 
50
- measures.none?
58
+ measures.none? { |_tags, (_expected, actual)| !actual.nil? }
51
59
  end
52
60
 
53
61
  def failure_message
54
62
  "expected #{expected_formatted} " \
55
- "to be changed #{"to #{expected} " unless expected_value.nil?}" \
56
- "#{("with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags)}" \
57
- "but #{actual_changes_message}"
63
+ "to be changed #{"to #{expected} " unless expected_value.nil?}" \
64
+ "#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
65
+ "#{if !tags && expectations
66
+ "with following expectations: #{::RSpec::Support::ObjectFormatter.format(expectations)} "
67
+ end}" \
68
+ "but #{actual_changes_message}"
58
69
  end
59
70
 
60
71
  def failure_message_when_negated
61
72
  "expected #{expected_formatted} " \
62
- "not to be incremented " \
63
- "#{("with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags)}" \
64
- "but #{actual_changes_message}"
73
+ "not to be incremented " \
74
+ "#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
75
+ "#{if !tags && expectations
76
+ "with following expectations: #{::RSpec::Support::ObjectFormatter.format(expectations)} "
77
+ end}" \
78
+ "but #{actual_changes_message}"
65
79
  end
66
80
 
67
81
  def actual_changes_message
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_matcher"
4
+
5
+ module Yabeda
6
+ module RSpec
7
+ # Checks whether Yabeda summary was observed during test run or not
8
+ # @param metric [Yabeda::Summary,String,Symbol] metric instance or name
9
+ # @return [Yabeda::RSpec::ObserveYabedaSummary]
10
+ def observe_yabeda_summary(metric)
11
+ ObserveYabedaSummary.new(metric)
12
+ end
13
+
14
+ # Custom matcher class with implementation for +observe_yabeda_summary+
15
+ class ObserveYabedaSummary < BaseMatcher
16
+ def with(value)
17
+ return super if value.is_a?(Hash)
18
+
19
+ @expected_value = value
20
+ self
21
+ end
22
+
23
+ attr_reader :expected_value
24
+
25
+ def initialize(*)
26
+ super
27
+ return if metric.is_a? Yabeda::Summary
28
+
29
+ raise ArgumentError, "Pass summary instance/name to `observe_yabeda_summary`. Got #{metric.inspect} instead"
30
+ end
31
+
32
+ def match(metric, block)
33
+ block.call
34
+
35
+ observations = filter_matching_changes(Yabeda::TestAdapter.instance.summaries.fetch(metric))
36
+
37
+ return false if observations.empty?
38
+
39
+ observations.values.all? do |expected_observation, actual_observation|
40
+ next !actual_observation.nil? if expected_observation.nil?
41
+
42
+ values_match?(expected_observation, actual_observation)
43
+ end
44
+ end
45
+
46
+ def match_when_negated(metric, block)
47
+ unless expected_value.nil?
48
+ raise NotImplementedError, <<~MSG
49
+ `expect {}.not_to observe_yabeda_summary` doesn't support specifying values with `.with`
50
+ as it can lead to false positives.
51
+ MSG
52
+ end
53
+
54
+ block.call
55
+
56
+ observations = filter_matching_changes(Yabeda::TestAdapter.instance.summaries.fetch(metric))
57
+
58
+ observations.none? { |_tags, (_expected, actual)| !actual.nil? }
59
+ end
60
+
61
+ def failure_message
62
+ "expected #{expected_formatted} " \
63
+ "to be observed #{"with #{expected} " unless expected_value.nil?}" \
64
+ "#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
65
+ "#{if !tags && expectations
66
+ "with following expectations: #{::RSpec::Support::ObjectFormatter.format(expectations)} "
67
+ end}" \
68
+ "but #{actual_changes_message}"
69
+ end
70
+
71
+ def failure_message_when_negated
72
+ "expected #{expected_formatted} " \
73
+ "not to be observed " \
74
+ "#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
75
+ "#{if !tags && expectations
76
+ "with following expectations: #{::RSpec::Support::ObjectFormatter.format(expectations)} "
77
+ end}" \
78
+ "but #{actual_changes_message}"
79
+ end
80
+
81
+ def actual_changes_message
82
+ observations = Yabeda::TestAdapter.instance.summaries.fetch(metric)
83
+ if observations.empty?
84
+ "no observations of this summary have been made"
85
+ elsif tags && observations.key?(tags)
86
+ formatted_tags = ::RSpec::Support::ObjectFormatter.format(tags)
87
+ "has been observed with #{observations.fetch(tags)} with tags #{formatted_tags}"
88
+ else
89
+ "following observations have been made: #{::RSpec::Support::ObjectFormatter.format(observations)}"
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./base_matcher"
3
+ require_relative "base_matcher"
4
4
 
5
5
  module Yabeda
6
6
  module RSpec
@@ -14,6 +14,8 @@ module Yabeda
14
14
  # Custom matcher class with implementation for +update_yabeda_gauge+
15
15
  class UpdateYabedaGauge < BaseMatcher
16
16
  def with(value)
17
+ return super if value.is_a?(Hash)
18
+
17
19
  @expected_value = value
18
20
  self
19
21
  end
@@ -32,7 +34,13 @@ module Yabeda
32
34
 
33
35
  updates = filter_matching_changes(Yabeda::TestAdapter.instance.gauges.fetch(metric))
34
36
 
35
- updates.values.any? { |update| expected_value.nil? || values_match?(expected_value, update) }
37
+ return false if updates.empty?
38
+
39
+ updates.values.all? do |expected_update, actual_update|
40
+ next !actual_update.nil? if expected_update.nil?
41
+
42
+ expected_update.nil? || values_match?(expected_update, actual_update)
43
+ end
36
44
  end
37
45
 
38
46
  def match_when_negated(metric, block)
@@ -47,21 +55,27 @@ module Yabeda
47
55
 
48
56
  updates = filter_matching_changes(Yabeda::TestAdapter.instance.gauges.fetch(metric))
49
57
 
50
- updates.none?
58
+ updates.none? { |_tags, (_expected, actual)| !actual.nil? }
51
59
  end
52
60
 
53
61
  def failure_message
54
62
  "expected #{expected_formatted} " \
55
- "to be changed #{"to #{expected_value} " unless expected_value.nil?}" \
56
- "#{("with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags)}" \
57
- "but #{actual_changes_message}"
63
+ "to be changed #{"to #{expected_value} " unless expected_value.nil?}" \
64
+ "#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
65
+ "#{if !tags && expectations
66
+ "with following expectations: #{::RSpec::Support::ObjectFormatter.format(expectations)} "
67
+ end}" \
68
+ "but #{actual_changes_message}"
58
69
  end
59
70
 
60
71
  def failure_message_when_negated
61
72
  "expected #{expected_formatted} " \
62
- "not to be changed " \
63
- "#{("with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags)}" \
64
- "but #{actual_changes_message}"
73
+ "not to be changed " \
74
+ "#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
75
+ "#{if !tags && expectations
76
+ "with following expectations: #{::RSpec::Support::ObjectFormatter.format(expectations)} "
77
+ end}" \
78
+ "but #{actual_changes_message}"
65
79
  end
66
80
 
67
81
  def actual_changes_message
data/lib/yabeda/rspec.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./testing"
3
+ require_relative "testing"
4
4
 
5
5
  module Yabeda
6
6
  # RSpec integration for Yabeda: custom matchers, etc
@@ -8,11 +8,12 @@ module Yabeda
8
8
  end
9
9
  end
10
10
 
11
- require_relative "./rspec/increment_yabeda_counter"
12
- require_relative "./rspec/update_yabeda_gauge"
13
- require_relative "./rspec/measure_yabeda_histogram"
11
+ require_relative "rspec/increment_yabeda_counter"
12
+ require_relative "rspec/update_yabeda_gauge"
13
+ require_relative "rspec/measure_yabeda_histogram"
14
+ require_relative "rspec/observe_yabeda_summary"
14
15
 
15
- ::RSpec.configure do |config|
16
+ RSpec.configure do |config|
16
17
  config.before(:suite) do
17
18
  Yabeda.configure! unless Yabeda.already_configured?
18
19
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yabeda
4
+ # Base class for complex metric for measuring time values that allow to
5
+ # calculate averages, percentiles, and so on.
6
+ class Summary < Metric
7
+ # rubocop: disable Metrics/MethodLength
8
+ def observe(tags = {}, value = nil)
9
+ if value.nil? ^ block_given?
10
+ raise ArgumentError, "You must provide either numeric value or block for Yabeda::Summary#observe!"
11
+ end
12
+
13
+ if block_given?
14
+ starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
15
+ yield
16
+ value = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - starting)
17
+ end
18
+
19
+ all_tags = ::Yabeda::Tags.build(tags, group)
20
+ values[all_tags] = value
21
+ adapters.each_value do |adapter|
22
+ adapter.perform_summary_observe!(self, all_tags, value)
23
+ end
24
+ value
25
+ end
26
+ # rubocop: enable Metrics/MethodLength
27
+ end
28
+ end
@@ -2,24 +2,28 @@
2
2
 
3
3
  require "singleton"
4
4
 
5
- require_relative "./base_adapter"
5
+ require_relative "base_adapter"
6
6
 
7
7
  module Yabeda
8
8
  # Fake monitoring system adapter that collects latest metric values for later inspection
9
9
  class TestAdapter < BaseAdapter
10
10
  include Singleton
11
11
 
12
- attr_reader :counters, :gauges, :histograms
12
+ attr_reader :counters, :gauges, :histograms, :summaries
13
13
 
14
+ # rubocop:disable Metrics/AbcSize
14
15
  def initialize
16
+ super
15
17
  @counters = Hash.new { |ch, ck| ch[ck] = Hash.new { |th, tk| th[tk] = 0 } }
16
18
  @gauges = Hash.new { |gh, gk| gh[gk] = Hash.new { |th, tk| th[tk] = nil } }
17
19
  @histograms = Hash.new { |hh, hk| hh[hk] = Hash.new { |th, tk| th[tk] = nil } }
20
+ @summaries = Hash.new { |sh, sk| sh[sk] = Hash.new { |th, tk| th[tk] = nil } }
18
21
  end
22
+ # rubocop:enable Metrics/AbcSize
19
23
 
20
24
  # Call this method after every test example to quickly get blank state for the next test example
21
25
  def reset!
22
- [@counters, @gauges, @histograms].each do |collection|
26
+ [@counters, @gauges, @histograms, @summaries].each do |collection|
23
27
  collection.each_value(&:clear) # Reset tag-values hash to be empty
24
28
  end
25
29
  end
@@ -36,6 +40,10 @@ module Yabeda
36
40
  @histograms[metric]
37
41
  end
38
42
 
43
+ def register_summary!(metric)
44
+ @summaries[metric]
45
+ end
46
+
39
47
  def perform_counter_increment!(counter, tags, increment)
40
48
  @counters[counter][tags] += increment
41
49
  end
@@ -47,5 +55,9 @@ module Yabeda
47
55
  def perform_histogram_measure!(histogram, tags, value)
48
56
  @histograms[histogram][tags] = value
49
57
  end
58
+
59
+ def perform_summary_observe!(summary, tags, value)
60
+ @summaries[summary][tags] = value
61
+ end
50
62
  end
51
63
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  # Include this file to get things prepared for testing
4
4
 
5
- require_relative "./test_adapter"
5
+ require_relative "test_adapter"
6
6
 
7
7
  Yabeda.register_adapter(:test, Yabeda::TestAdapter.instance)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Yabeda
4
- VERSION = "0.11.0"
4
+ VERSION = "0.13.0"
5
5
  end
data/lib/yabeda.rb CHANGED
@@ -8,7 +8,6 @@ require "yabeda/config"
8
8
  require "yabeda/dsl"
9
9
  require "yabeda/tags"
10
10
  require "yabeda/errors"
11
- require "yabeda/railtie" if defined?(Rails)
12
11
 
13
12
  # Extendable framework for collecting and exporting metrics from Ruby apps
14
13
  module Yabeda
@@ -29,7 +28,7 @@ module Yabeda
29
28
  end
30
29
  end
31
30
 
32
- # @return [Hash<String, Yabeda::BaseAdapter>] All loaded adapters
31
+ # @return [Hash<Symbol, Yabeda::BaseAdapter>] All loaded adapters
33
32
  def adapters
34
33
  @adapters ||= Concurrent::Hash.new
35
34
  end
@@ -68,7 +67,9 @@ module Yabeda
68
67
  def register_adapter(name, instance)
69
68
  adapters[name] = instance
70
69
  # NOTE: Pretty sure there is race condition
71
- metrics.each do |_, metric|
70
+ metrics.each_value do |metric|
71
+ next unless metric.adapters.key?(name)
72
+
72
73
  instance.register!(metric)
73
74
  end
74
75
  end
@@ -86,7 +87,7 @@ module Yabeda
86
87
 
87
88
  # Perform configuration: registration of metrics and collector blocks
88
89
  # @return [void]
89
- # rubocop: disable Metrics/MethodLength, Metrics/AbcSize
90
+ # rubocop: disable Metrics/MethodLength
90
91
  def configure!
91
92
  raise(AlreadyConfiguredError, @configured_by) if already_configured?
92
93
 
@@ -100,8 +101,8 @@ module Yabeda
100
101
 
101
102
  # Register metrics in adapters after evaluating all configuration blocks
102
103
  # to ensure that all global settings (like default tags) will be applied.
103
- adapters.each_value do |adapter|
104
- metrics.each_value do |metric|
104
+ metrics.each_value do |metric|
105
+ metric.adapters.each_value do |adapter|
105
106
  adapter.register!(metric)
106
107
  end
107
108
  end
@@ -129,12 +130,10 @@ module Yabeda
129
130
 
130
131
  true
131
132
  end
132
- # rubocop: enable Metrics/MethodLength, Metrics/AbcSize
133
133
 
134
134
  # Forget all the configuration.
135
135
  # For testing purposes as it doesn't rollback changes in adapters.
136
136
  # @api private
137
- # rubocop: disable Metrics/AbcSize
138
137
  def reset!
139
138
  default_tags.clear
140
139
  adapters.clear
@@ -144,9 +143,12 @@ module Yabeda
144
143
  @metrics = nil
145
144
  collectors.clear
146
145
  configurators.clear
146
+ @config = Config.new
147
147
  instance_variable_set(:@configured_by, nil)
148
148
  instance_variable_set(:@debug_was_enabled_by, nil)
149
149
  end
150
- # rubocop: enable Metrics/AbcSize
150
+ # rubocop: enable Metrics/MethodLength
151
151
  end
152
152
  end
153
+
154
+ require "yabeda/railtie" if defined?(Rails)
data/yabeda.gemspec CHANGED
@@ -29,9 +29,5 @@ Gem::Specification.new do |spec|
29
29
  spec.add_dependency "concurrent-ruby"
30
30
  spec.add_dependency "dry-initializer"
31
31
 
32
- spec.add_development_dependency "bundler", "~> 2.0"
33
- spec.add_development_dependency "rake", "~> 12.0"
34
- spec.add_development_dependency "rspec", "~> 3.0"
35
- spec.add_development_dependency "yard"
36
- spec.add_development_dependency "yard-dry-initializer"
32
+ spec.required_ruby_version = ">= 2.3"
37
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yabeda
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Novikov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-25 00:00:00.000000000 Z
11
+ date: 2024-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anyway_config
@@ -58,76 +58,6 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
- - !ruby/object:Gem::Dependency
62
- name: bundler
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '2.0'
68
- type: :development
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '2.0'
75
- - !ruby/object:Gem::Dependency
76
- name: rake
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '12.0'
82
- type: :development
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '12.0'
89
- - !ruby/object:Gem::Dependency
90
- name: rspec
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: '3.0'
96
- type: :development
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: '3.0'
103
- - !ruby/object:Gem::Dependency
104
- name: yard
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: '0'
117
- - !ruby/object:Gem::Dependency
118
- name: yard-dry-initializer
119
- requirement: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - ">="
122
- - !ruby/object:Gem::Version
123
- version: '0'
124
- type: :development
125
- prerelease: false
126
- version_requirements: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - ">="
129
- - !ruby/object:Gem::Version
130
- version: '0'
131
61
  description: 'Collect statistics about how your application is performing with ease.
132
62
  Export metrics to various monitoring systems.
133
63
 
@@ -138,7 +68,8 @@ executables: []
138
68
  extensions: []
139
69
  extra_rdoc_files: []
140
70
  files:
141
- - ".github/workflows/build-release.yml"
71
+ - ".github/workflows/lint.yml"
72
+ - ".github/workflows/release.yml"
142
73
  - ".github/workflows/test.yml"
143
74
  - ".gitignore"
144
75
  - ".rspec"
@@ -170,7 +101,9 @@ files:
170
101
  - lib/yabeda/rspec/base_matcher.rb
171
102
  - lib/yabeda/rspec/increment_yabeda_counter.rb
172
103
  - lib/yabeda/rspec/measure_yabeda_histogram.rb
104
+ - lib/yabeda/rspec/observe_yabeda_summary.rb
173
105
  - lib/yabeda/rspec/update_yabeda_gauge.rb
106
+ - lib/yabeda/summary.rb
174
107
  - lib/yabeda/tags.rb
175
108
  - lib/yabeda/test_adapter.rb
176
109
  - lib/yabeda/testing.rb
@@ -189,14 +122,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
189
122
  requirements:
190
123
  - - ">="
191
124
  - !ruby/object:Gem::Version
192
- version: '0'
125
+ version: '2.3'
193
126
  required_rubygems_version: !ruby/object:Gem::Requirement
194
127
  requirements:
195
128
  - - ">="
196
129
  - !ruby/object:Gem::Version
197
130
  version: '0'
198
131
  requirements: []
199
- rubygems_version: 3.1.6
132
+ rubygems_version: 3.5.16
200
133
  signing_key:
201
134
  specification_version: 4
202
135
  summary: Extensible framework for collecting metric for your Ruby application