yabeda 0.11.0 → 0.12.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 +4 -4
- data/.github/workflows/lint.yml +32 -0
- data/.github/workflows/test.yml +2 -8
- data/.rubocop.yml +6 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +6 -1
- data/README.md +15 -4
- data/lib/yabeda/base_adapter.rb +9 -0
- data/lib/yabeda/dsl/class_methods.rb +7 -0
- data/lib/yabeda/global_group.rb +1 -1
- data/lib/yabeda/rspec/base_matcher.rb +1 -0
- data/lib/yabeda/rspec/increment_yabeda_counter.rb +7 -7
- data/lib/yabeda/rspec/measure_yabeda_histogram.rb +7 -7
- data/lib/yabeda/rspec/observe_yabeda_summary.rb +80 -0
- data/lib/yabeda/rspec/update_yabeda_gauge.rb +7 -7
- data/lib/yabeda/rspec.rb +6 -5
- data/lib/yabeda/summary.rb +28 -0
- data/lib/yabeda/test_adapter.rb +15 -3
- data/lib/yabeda/testing.rb +1 -1
- data/lib/yabeda/version.rb +1 -1
- data/lib/yabeda.rb +2 -4
- data/yabeda.gemspec +1 -5
- metadata +6 -73
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52ac87de3f6f2edd66e88d967b2e2e7231a87a27189e9d0a129cbafc6041813f
|
4
|
+
data.tar.gz: 2096a9ea457d7aa10efdcb54bc29a6a6e520e15974bba1efafc53df2921b5116
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a75f40eb17ab3d35feef5449bfe07e369487c61609eca03da0f7eec17d1d7e32ad5b51b4a5079d3247b994df8e9730d681d501b7fa7b71d17a9b7d1ede06993
|
7
|
+
data.tar.gz: bcf1c14781cb17a3621ed4f03a3431b2399ee9e4ec80bfa044455903d2d4e9ab25563b94a01207435b05e1898e681dda91c6f36d437e574c33060f0f7c1014ef
|
@@ -0,0 +1,32 @@
|
|
1
|
+
name: Lint Ruby
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
paths:
|
8
|
+
- "gemfiles/*"
|
9
|
+
- "Gemfile"
|
10
|
+
- "**/*.rb"
|
11
|
+
- "**/*.gemspec"
|
12
|
+
- ".github/workflows/lint.yml"
|
13
|
+
pull_request:
|
14
|
+
paths:
|
15
|
+
- "gemfiles/*"
|
16
|
+
- "Gemfile"
|
17
|
+
- "**/*.rb"
|
18
|
+
- "**/*.gemspec"
|
19
|
+
- ".github/workflows/lint.yml"
|
20
|
+
|
21
|
+
jobs:
|
22
|
+
rubocop:
|
23
|
+
runs-on: ubuntu-latest
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v3
|
26
|
+
- uses: ruby/setup-ruby@v1
|
27
|
+
with:
|
28
|
+
ruby-version: 3.2
|
29
|
+
bundler-cache: true
|
30
|
+
- name: Lint Ruby code with RuboCop
|
31
|
+
run: |
|
32
|
+
bundle exec rubocop
|
data/.github/workflows/test.yml
CHANGED
@@ -16,12 +16,10 @@ jobs:
|
|
16
16
|
fail-fast: false
|
17
17
|
matrix:
|
18
18
|
include:
|
19
|
+
- ruby: "3.2"
|
20
|
+
- ruby: "3.1"
|
19
21
|
- ruby: "3.0"
|
20
22
|
- ruby: "2.7"
|
21
|
-
- ruby: "2.6"
|
22
|
-
- ruby: "2.5"
|
23
|
-
- ruby: "2.4"
|
24
|
-
- ruby: "2.3"
|
25
23
|
container:
|
26
24
|
image: ruby:${{ matrix.ruby }}
|
27
25
|
env:
|
@@ -35,14 +33,10 @@ jobs:
|
|
35
33
|
restore-keys: |
|
36
34
|
bundle-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}-${{ hashFiles('**/Gemfile') }}
|
37
35
|
bundle-${{ matrix.ruby }}-
|
38
|
-
- name: Upgrade Bundler to 2.0 (for older Rubies)
|
39
|
-
run: gem install bundler -v '~> 2.0'
|
40
36
|
- name: Bundle install
|
41
37
|
run: |
|
42
38
|
bundle config path vendor/bundle
|
43
39
|
bundle install
|
44
40
|
bundle update
|
45
|
-
- name: Run Rubocop
|
46
|
-
run: bundle exec rubocop
|
47
41
|
- name: Run RSpec
|
48
42
|
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,9 @@ RSpec/DescribeClass:
|
|
29
32
|
RSpec/NestedGroups:
|
30
33
|
Max: 4
|
31
34
|
|
35
|
+
RSpec/MultipleMemoizedHelpers:
|
36
|
+
Enabled: false
|
37
|
+
|
32
38
|
Bundler/OrderedGems:
|
33
39
|
Enabled: false
|
34
40
|
|
data/CHANGELOG.md
CHANGED
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", "~>
|
19
|
+
gem "rubocop", "~> 1.0"
|
15
20
|
gem "rubocop-rspec"
|
16
21
|
end
|
data/README.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# 
|
2
2
|
|
3
3
|
[](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
|
+
[](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,7 @@ 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)
|
127
133
|
- _…and more! You can write your own adapter and open a pull request to add it into this list._
|
128
134
|
|
129
135
|
## Available plugins to collect metrics
|
@@ -131,6 +137,7 @@ These are developed and maintained by other awesome folks:
|
|
131
137
|
### Maintained by Yabeda
|
132
138
|
|
133
139
|
- [yabeda-rails] — basic request metrics for [Ruby on Rails](https://rubyonrails.org/) applications.
|
140
|
+
- [yabeda-activerecord] — query performance and connection pool stats for apps using ActiveRecord to query databases.
|
134
141
|
- [yabeda-sidekiq] — comprehensive set of metrics for monitoring [Sidekiq](https://sidekiq.org/) jobs execution and queues.
|
135
142
|
- [yabeda-faktory] — metrics for monitoring jobs execution by Ruby workers of [Faktory](https://contribsys.com/faktory/).
|
136
143
|
- [yabeda-graphql] — metrics to query and field-level monitoring for apps using [GraphQL-Ruby](https://graphql-ruby.org/).
|
@@ -146,6 +153,9 @@ These are developed and maintained by other awesome folks:
|
|
146
153
|
- [yabeda-grape](https://github.com/efigence/yabeda-grape) — metrics for [Grape](https://github.com/ruby-grape/grape) framework.
|
147
154
|
- [yabeda-gruf](https://github.com/Placewise/yabeda-gruf) — metrics for [gRPC Ruby Framework](https://github.com/bigcommerce/gruf)
|
148
155
|
- [yabeda-gc](https://github.com/ianks/yabeda-gc) — metrics for Ruby garbage collection.
|
156
|
+
- [yabeda-activejob](https://github.com/Fullscript/yabeda-activejob) — backend-agnostic metrics for background jobs.
|
157
|
+
- [yabeda-shoryuken](https://github.com/retsef/yabeda-shoryuken) — metrics for [Shoryuken](https://github.com/ruby-shoryuken/shoryuken) jobs execution message queues.
|
158
|
+
- [yabeda-rack-ratelimit](https://github.com/basecamp/yabeda-rack-ratelimit) — metrics for [Rack::Ratelimit](https://github.com/jeremy/rack-ratelimit)
|
149
159
|
- _…and more! You can write your own adapter and open a pull request to add it into this list._
|
150
160
|
|
151
161
|
## Configuration
|
@@ -172,7 +182,7 @@ Add the following to your `rails_helper.rb` (or `spec_helper.rb`):
|
|
172
182
|
require "yabeda/rspec"
|
173
183
|
```
|
174
184
|
|
175
|
-
Now you can use `increment_yabeda_counter`, `update_yabeda_gauge`, and `
|
185
|
+
Now you can use `increment_yabeda_counter`, `update_yabeda_gauge`, `measure_yabeda_histogram`, and `observe_yabeda_summary` matchers:
|
176
186
|
|
177
187
|
```ruby
|
178
188
|
it "increments counters" do
|
@@ -192,7 +202,7 @@ end
|
|
192
202
|
|
193
203
|
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
204
|
|
195
|
-
And check for values with `by` for counters, `to` for gauges, and `with` for
|
205
|
+
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
206
|
|
197
207
|
```ruby
|
198
208
|
expect { subject }.to \
|
@@ -267,6 +277,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/yabeda
|
|
267
277
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
268
278
|
|
269
279
|
[yabeda-rails]: https://github.com/yabeda-rb/yabeda-rails/ "Yabeda plugin for collecting and exporting basic metrics for Rails applications"
|
280
|
+
[yabeda-activerecord]: https://github.com/yabeda-rb/yabeda-activerecord/ "Yabeda plugin to collect query performance metrics and connection pool statistics"
|
270
281
|
[yabeda-sidekiq]: https://github.com/yabeda-rb/yabeda-sidekiq/ "Yabeda plugin for complete monitoring of Sidekiq metrics"
|
271
282
|
[yabeda-faktory]: https://github.com/yabeda-rb/yabeda-faktory/ "Yabeda plugin for complete monitoring of Faktory Ruby Workers"
|
272
283
|
[yabeda-graphql]: https://github.com/yabeda-rb/yabeda-graphql/ "Measure and understand how good your GraphQL-Ruby application works"
|
data/lib/yabeda/base_adapter.rb
CHANGED
@@ -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
|
@@ -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
|
data/lib/yabeda/global_group.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "base_matcher"
|
4
4
|
|
5
5
|
module Yabeda
|
6
6
|
module RSpec
|
@@ -54,16 +54,16 @@ module Yabeda
|
|
54
54
|
|
55
55
|
def failure_message
|
56
56
|
"expected #{expected_formatted} " \
|
57
|
-
|
58
|
-
|
59
|
-
|
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}"
|
60
60
|
end
|
61
61
|
|
62
62
|
def failure_message_when_negated
|
63
63
|
"expected #{expected_formatted} " \
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
"not to be incremented " \
|
65
|
+
"#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
|
66
|
+
"but #{actual_increments_message}"
|
67
67
|
end
|
68
68
|
|
69
69
|
def actual_increments_message
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "base_matcher"
|
4
4
|
|
5
5
|
module Yabeda
|
6
6
|
module RSpec
|
@@ -52,16 +52,16 @@ module Yabeda
|
|
52
52
|
|
53
53
|
def failure_message
|
54
54
|
"expected #{expected_formatted} " \
|
55
|
-
|
56
|
-
|
57
|
-
|
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}"
|
58
58
|
end
|
59
59
|
|
60
60
|
def failure_message_when_negated
|
61
61
|
"expected #{expected_formatted} " \
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
"not to be incremented " \
|
63
|
+
"#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
|
64
|
+
"but #{actual_changes_message}"
|
65
65
|
end
|
66
66
|
|
67
67
|
def actual_changes_message
|
@@ -0,0 +1,80 @@
|
|
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
|
+
@expected_value = value
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :expected_value
|
22
|
+
|
23
|
+
def initialize(*)
|
24
|
+
super
|
25
|
+
return if metric.is_a? Yabeda::Summary
|
26
|
+
|
27
|
+
raise ArgumentError, "Pass summary instance/name to `observe_yabeda_summary`. Got #{metric.inspect} instead"
|
28
|
+
end
|
29
|
+
|
30
|
+
def match(metric, block)
|
31
|
+
block.call
|
32
|
+
|
33
|
+
observations = filter_matching_changes(Yabeda::TestAdapter.instance.summaries.fetch(metric))
|
34
|
+
|
35
|
+
observations.values.any? { |observation| expected_value.nil? || values_match?(expected_value, observation) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def match_when_negated(metric, block)
|
39
|
+
unless expected_value.nil?
|
40
|
+
raise NotImplementedError, <<~MSG
|
41
|
+
`expect {}.not_to observe_yabeda_summary` doesn't support specifying values with `.with`
|
42
|
+
as it can lead to false positives.
|
43
|
+
MSG
|
44
|
+
end
|
45
|
+
|
46
|
+
block.call
|
47
|
+
|
48
|
+
observations = filter_matching_changes(Yabeda::TestAdapter.instance.summaries.fetch(metric))
|
49
|
+
|
50
|
+
observations.none?
|
51
|
+
end
|
52
|
+
|
53
|
+
def failure_message
|
54
|
+
"expected #{expected_formatted} " \
|
55
|
+
"to be observed #{"with #{expected} " unless expected_value.nil?}" \
|
56
|
+
"#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
|
57
|
+
"but #{actual_changes_message}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def failure_message_when_negated
|
61
|
+
"expected #{expected_formatted} " \
|
62
|
+
"not to be observed " \
|
63
|
+
"#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
|
64
|
+
"but #{actual_changes_message}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def actual_changes_message
|
68
|
+
observations = Yabeda::TestAdapter.instance.summaries.fetch(metric)
|
69
|
+
if observations.empty?
|
70
|
+
"no observations of this summary have been made"
|
71
|
+
elsif tags && observations.key?(tags)
|
72
|
+
formatted_tags = ::RSpec::Support::ObjectFormatter.format(tags)
|
73
|
+
"has been observed with #{observations.fetch(tags)} with tags #{formatted_tags}"
|
74
|
+
else
|
75
|
+
"following observations have been made: #{::RSpec::Support::ObjectFormatter.format(observations)}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "base_matcher"
|
4
4
|
|
5
5
|
module Yabeda
|
6
6
|
module RSpec
|
@@ -52,16 +52,16 @@ module Yabeda
|
|
52
52
|
|
53
53
|
def failure_message
|
54
54
|
"expected #{expected_formatted} " \
|
55
|
-
|
56
|
-
|
57
|
-
|
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}"
|
58
58
|
end
|
59
59
|
|
60
60
|
def failure_message_when_negated
|
61
61
|
"expected #{expected_formatted} " \
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
"not to be changed " \
|
63
|
+
"#{"with tags #{::RSpec::Support::ObjectFormatter.format(tags)} " if tags}" \
|
64
|
+
"but #{actual_changes_message}"
|
65
65
|
end
|
66
66
|
|
67
67
|
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 "
|
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 "
|
12
|
-
require_relative "
|
13
|
-
require_relative "
|
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
|
-
|
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
|
+
::Yabeda.adapters.each 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
|
data/lib/yabeda/test_adapter.rb
CHANGED
@@ -2,24 +2,28 @@
|
|
2
2
|
|
3
3
|
require "singleton"
|
4
4
|
|
5
|
-
require_relative "
|
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
|
data/lib/yabeda/testing.rb
CHANGED
data/lib/yabeda/version.rb
CHANGED
data/lib/yabeda.rb
CHANGED
@@ -86,7 +86,7 @@ module Yabeda
|
|
86
86
|
|
87
87
|
# Perform configuration: registration of metrics and collector blocks
|
88
88
|
# @return [void]
|
89
|
-
# rubocop: disable Metrics/MethodLength
|
89
|
+
# rubocop: disable Metrics/MethodLength
|
90
90
|
def configure!
|
91
91
|
raise(AlreadyConfiguredError, @configured_by) if already_configured?
|
92
92
|
|
@@ -129,12 +129,11 @@ module Yabeda
|
|
129
129
|
|
130
130
|
true
|
131
131
|
end
|
132
|
-
# rubocop: enable Metrics/MethodLength
|
132
|
+
# rubocop: enable Metrics/MethodLength
|
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
|
@@ -147,6 +146,5 @@ module Yabeda
|
|
147
146
|
instance_variable_set(:@configured_by, nil)
|
148
147
|
instance_variable_set(:@debug_was_enabled_by, nil)
|
149
148
|
end
|
150
|
-
# rubocop: enable Metrics/AbcSize
|
151
149
|
end
|
152
150
|
end
|
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.
|
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.
|
4
|
+
version: 0.12.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:
|
11
|
+
date: 2023-07-28 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
|
|
@@ -139,6 +69,7 @@ extensions: []
|
|
139
69
|
extra_rdoc_files: []
|
140
70
|
files:
|
141
71
|
- ".github/workflows/build-release.yml"
|
72
|
+
- ".github/workflows/lint.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,7 +122,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
189
122
|
requirements:
|
190
123
|
- - ">="
|
191
124
|
- !ruby/object:Gem::Version
|
192
|
-
version: '
|
125
|
+
version: '2.3'
|
193
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
194
127
|
requirements:
|
195
128
|
- - ">="
|