yabeda 0.1.2 → 0.1.3
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/CHANGELOG.md +29 -0
- data/README.md +18 -15
- data/lib/yabeda.rb +5 -0
- data/lib/yabeda/dsl.rb +2 -55
- data/lib/yabeda/dsl/class_methods.rb +81 -0
- data/lib/yabeda/dsl/metric_builder.rb +29 -0
- data/lib/yabeda/dsl/option_builder.rb +49 -0
- data/lib/yabeda/group.rb +16 -0
- data/lib/yabeda/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3a3991d4dbb2b060ba55ad682d20eb14012c8fb674cebc335e36ae5c0ab8067
|
4
|
+
data.tar.gz: 56190b3fae34f414ba1afa58ec0ffc05ca36ee7c5f5209148b64a7a7a9936197
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: def5c6a2dfaf0bff0b17aadb9af664fc5b36427c1b52eff208afc7a43f275691a32d3c2cea2c19c2abd5643339a788f78b7f30f9294a8c882897abd57d060bee
|
7
|
+
data.tar.gz: 3548e381cf4b1b2fefe93d0211887e040022d02f4fbfc3a23f6404407bdb82e5b5a951a446d461a333978e5892054921593c4ea4a43de956ecefecf121408c0f
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
6
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
|
9
|
+
## 0.1.3 - 2018-12-18
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Block-based DSL for defining groups and metrics. @DmitryTsepelev
|
14
|
+
|
15
|
+
## 0.1.2 - 2018-10-25
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
|
19
|
+
- Removed accidental dependency from Rails. @dsalahutdinov
|
20
|
+
|
21
|
+
## 0.1.1 - 2018-10-17
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
|
25
|
+
- Renamed evil-metrics gem to yabeda. @Envek
|
26
|
+
|
27
|
+
## 0.1.0 - 2018-10-03
|
28
|
+
|
29
|
+
- Initial release of evil-metrics gem. @Envek
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/yabeda) [](https://travis-ci.org/yabeda-rb/yabeda)
|
4
4
|
|
5
|
-
**This software is Work in Progress: features will appear and disappear, API will be changed, your feedback is always welcome!**
|
5
|
+
**This software is Work in Progress: features will appear and disappear, API will be changed, your feedback is always welcome!**
|
6
6
|
|
7
7
|
Extendable solution for easy setup of monitoring in your Ruby apps.
|
8
8
|
|
@@ -32,35 +32,38 @@ And then execute:
|
|
32
32
|
|
33
33
|
```ruby
|
34
34
|
Yabeda.configure do
|
35
|
-
group :your_app
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
group :your_app do
|
36
|
+
counter :bells_rang_count, comment: "Total number of bells being rang"
|
37
|
+
gauge :whistles_active, comment: "Number of whistles ready to whistle"
|
38
|
+
histogram :whistle_runtime do
|
39
|
+
comment "How long whistles are being active"
|
40
|
+
unit :seconds
|
41
|
+
end
|
42
|
+
end
|
40
43
|
end
|
41
44
|
```
|
42
|
-
|
45
|
+
|
43
46
|
2. Access metric in your app and use it!
|
44
|
-
|
47
|
+
|
45
48
|
```ruby
|
46
49
|
def ring_the_bell(id)
|
47
50
|
bell = Bell.find(id)
|
48
51
|
bell.ring!
|
49
|
-
Yabeda.
|
52
|
+
Yabeda.your_app.bells_rang_count.increment({bell_size: bell.size}, by: 1)
|
50
53
|
end
|
51
54
|
|
52
55
|
def whistle!
|
53
|
-
Yabeda.
|
56
|
+
Yabeda.your_app.whistle_runtime.measure do
|
54
57
|
# Run your code
|
55
58
|
end
|
56
59
|
end
|
57
60
|
```
|
58
|
-
|
61
|
+
|
59
62
|
3. Setup collecting of metrics that do not tied to specific events in you application. E.g.: reporting your app's current state
|
60
63
|
```ruby
|
61
64
|
Yabeda.configure do
|
62
65
|
# This block will be executed periodically few times in a minute
|
63
|
-
# (by timer or external request depending on adapter you're using)
|
66
|
+
# (by timer or external request depending on adapter you're using)
|
64
67
|
# Keep it fast and simple!
|
65
68
|
collect do
|
66
69
|
your_app_whistles_active.set({}, Whistle.where(state: :active).count
|
@@ -74,7 +77,7 @@ And then execute:
|
|
74
77
|
## Roadmap (aka TODO or Help wanted)
|
75
78
|
|
76
79
|
- Ability to change metric settings for individual adapters
|
77
|
-
|
80
|
+
|
78
81
|
```rb
|
79
82
|
histogram :foo, comment: "say what?" do
|
80
83
|
adapter :prometheus do
|
@@ -82,9 +85,9 @@ And then execute:
|
|
82
85
|
end
|
83
86
|
end
|
84
87
|
```
|
85
|
-
|
88
|
+
|
86
89
|
- Ability to route some metrics only for given adapter:
|
87
|
-
|
90
|
+
|
88
91
|
```rb
|
89
92
|
adapter :prometheus do
|
90
93
|
include_group :sidekiq
|
data/lib/yabeda.rb
CHANGED
@@ -15,6 +15,11 @@ module Yabeda
|
|
15
15
|
@metrics ||= Concurrent::Hash.new
|
16
16
|
end
|
17
17
|
|
18
|
+
# @return [Hash<String, Yabeda::Group>] All registered metrics
|
19
|
+
def groups
|
20
|
+
@groups ||= Concurrent::Hash.new
|
21
|
+
end
|
22
|
+
|
18
23
|
# @return [Hash<String, Yabeda::BaseAdapter>] All loaded adapters
|
19
24
|
def adapters
|
20
25
|
@adapters ||= Concurrent::Hash.new
|
data/lib/yabeda/dsl.rb
CHANGED
@@ -1,65 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "yabeda/
|
4
|
-
require "yabeda/counter"
|
5
|
-
require "yabeda/gauge"
|
6
|
-
require "yabeda/histogram"
|
3
|
+
require "yabeda/dsl/class_methods"
|
7
4
|
|
8
5
|
module Yabeda
|
9
6
|
# DSL for ease of work with Yabeda
|
10
7
|
module DSL
|
11
8
|
def self.included(base)
|
12
|
-
base.extend ClassMethods
|
9
|
+
base.extend DSL::ClassMethods
|
13
10
|
end
|
14
|
-
|
15
|
-
# rubocop: disable Style/Documentation
|
16
|
-
module ClassMethods
|
17
|
-
# Block for grouping and simplifying configuration of related metrics
|
18
|
-
def configure(&block)
|
19
|
-
class_exec(&block)
|
20
|
-
@group = nil
|
21
|
-
end
|
22
|
-
|
23
|
-
# Define the actions that should be performed
|
24
|
-
def collect(&block)
|
25
|
-
::Yabeda.collectors.push(block)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Specify metric category or group for all consecutive metrics in this
|
29
|
-
# +configure+ block.
|
30
|
-
# On most adapters it is only adds prefix to the metric name but on some
|
31
|
-
# (like NewRelic) it is treated individually and have special meaning.
|
32
|
-
def group(group_name)
|
33
|
-
@group = group_name
|
34
|
-
end
|
35
|
-
|
36
|
-
# Register a growing-only counter
|
37
|
-
def counter(*args, **kwargs)
|
38
|
-
register(Counter.new(*args, **kwargs, group: @group))
|
39
|
-
end
|
40
|
-
|
41
|
-
# Register a gauge
|
42
|
-
def gauge(*args, **kwargs)
|
43
|
-
register(Gauge.new(*args, **kwargs, group: @group))
|
44
|
-
end
|
45
|
-
|
46
|
-
# Register an histogram
|
47
|
-
def histogram(*args, **kwargs)
|
48
|
-
register(Histogram.new(*args, **kwargs, group: @group))
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def register(metric)
|
54
|
-
name = [metric.group, metric.name].compact.join("_")
|
55
|
-
::Yabeda.define_singleton_method(name) { metric }
|
56
|
-
::Yabeda.metrics[name] = metric
|
57
|
-
::Yabeda.adapters.each do |_, adapter|
|
58
|
-
adapter.register!(metric)
|
59
|
-
end
|
60
|
-
metric
|
61
|
-
end
|
62
|
-
end
|
63
|
-
# rubocop: enable Style/Documentation
|
64
11
|
end
|
65
12
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yabeda/metric"
|
4
|
+
require "yabeda/counter"
|
5
|
+
require "yabeda/gauge"
|
6
|
+
require "yabeda/histogram"
|
7
|
+
require "yabeda/group"
|
8
|
+
require "yabeda/dsl/metric_builder"
|
9
|
+
|
10
|
+
module Yabeda
|
11
|
+
# DSL for ease of work with Yabeda
|
12
|
+
module DSL
|
13
|
+
# rubocop: disable Style/Documentation
|
14
|
+
module ClassMethods
|
15
|
+
# Block for grouping and simplifying configuration of related metrics
|
16
|
+
def configure(&block)
|
17
|
+
class_exec(&block)
|
18
|
+
@group = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
# Define the actions that should be performed
|
22
|
+
def collect(&block)
|
23
|
+
::Yabeda.collectors.push(block)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Specify metric category or group for all consecutive metrics in this
|
27
|
+
# +configure+ block.
|
28
|
+
# On most adapters it is only adds prefix to the metric name but on some
|
29
|
+
# (like NewRelic) it is treated individually and has a special meaning.
|
30
|
+
def group(group_name)
|
31
|
+
@group = group_name
|
32
|
+
return unless block_given?
|
33
|
+
|
34
|
+
yield
|
35
|
+
@group = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
# Register a growing-only counter
|
39
|
+
def counter(*args, **kwargs, &block)
|
40
|
+
metric = MetricBuilder.new(Counter).build(args, kwargs, @group, &block)
|
41
|
+
register_metric(metric)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Register a gauge
|
45
|
+
def gauge(*args, **kwargs, &block)
|
46
|
+
metric = MetricBuilder.new(Gauge).build(args, kwargs, @group, &block)
|
47
|
+
register_metric(metric)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Register a histogram
|
51
|
+
def histogram(*args, **kwargs, &block)
|
52
|
+
metric = MetricBuilder.new(Histogram).build(args, kwargs, @group, &block)
|
53
|
+
register_metric(metric)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def register_metric(metric)
|
59
|
+
name = [metric.group, metric.name].compact.join("_")
|
60
|
+
::Yabeda.define_singleton_method(name) { metric }
|
61
|
+
::Yabeda.metrics[name] = metric
|
62
|
+
::Yabeda.adapters.each_value { |adapter| adapter.register!(metric) }
|
63
|
+
register_group_for(metric) if metric.group
|
64
|
+
metric
|
65
|
+
end
|
66
|
+
|
67
|
+
def register_group_for(metric)
|
68
|
+
group = ::Yabeda.groups[metric.group]
|
69
|
+
|
70
|
+
if group.nil?
|
71
|
+
group = Group.new(metric.group)
|
72
|
+
::Yabeda.groups[metric.group] = group
|
73
|
+
::Yabeda.define_singleton_method(metric.group) { group }
|
74
|
+
end
|
75
|
+
|
76
|
+
group.register_metric(metric)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
# rubocop: enable Style/Documentation
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yabeda/dsl/option_builder"
|
4
|
+
|
5
|
+
module Yabeda
|
6
|
+
class ConfigurationError < StandardError; end
|
7
|
+
|
8
|
+
module DSL
|
9
|
+
# Handles DSL for working with individual metrics
|
10
|
+
class MetricBuilder
|
11
|
+
extend Dry::Initializer
|
12
|
+
|
13
|
+
param :metric_klass
|
14
|
+
|
15
|
+
def build(args, kwargs, group, &block)
|
16
|
+
options = OptionBuilder.new(metric_klass, kwargs).options_from(&block)
|
17
|
+
initialize_metric(args, options, group)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def initialize_metric(params, options, group)
|
23
|
+
metric_klass.new(*params, **options, group: group)
|
24
|
+
rescue KeyError => error
|
25
|
+
raise ConfigurationError, "#{error.message} for #{metric_klass.name}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Yabeda
|
4
|
+
module DSL
|
5
|
+
# Collects options for metric initializer
|
6
|
+
class OptionBuilder
|
7
|
+
extend Dry::Initializer
|
8
|
+
|
9
|
+
param :metric_klass
|
10
|
+
param :options
|
11
|
+
|
12
|
+
def options_from(&block)
|
13
|
+
instance_eval(&block) if block
|
14
|
+
|
15
|
+
return options if unknown_options.empty?
|
16
|
+
|
17
|
+
raise ConfigurationError,
|
18
|
+
"option '#{unknown_options.first}' is not available for #{metric_klass.name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def method_missing(method_name, method_args, &_block)
|
22
|
+
if kwarg?(method_name)
|
23
|
+
options[method_name] = method_args
|
24
|
+
else
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def respond_to_missing?(method_name, _args)
|
30
|
+
kwarg?(method_name) || super
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def kwarg?(method_name)
|
36
|
+
option_names.include?(method_name.to_sym)
|
37
|
+
end
|
38
|
+
|
39
|
+
def option_names
|
40
|
+
definitions = metric_klass.dry_initializer.definitions.values
|
41
|
+
definitions.select(&:option).map { |definition| definition.source.to_sym }
|
42
|
+
end
|
43
|
+
|
44
|
+
def unknown_options
|
45
|
+
options.keys - option_names
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/yabeda/group.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-initializer"
|
4
|
+
|
5
|
+
module Yabeda
|
6
|
+
# Represents a set of metrics grouped under the same name
|
7
|
+
class Group
|
8
|
+
extend Dry::Initializer
|
9
|
+
|
10
|
+
param :name
|
11
|
+
|
12
|
+
def register_metric(metric)
|
13
|
+
define_singleton_method(metric.name) { metric }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/yabeda/version.rb
CHANGED
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.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey Novikov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -123,6 +123,7 @@ files:
|
|
123
123
|
- ".rubocop.yml"
|
124
124
|
- ".travis.yml"
|
125
125
|
- ".yardopts"
|
126
|
+
- CHANGELOG.md
|
126
127
|
- Gemfile
|
127
128
|
- LICENSE.txt
|
128
129
|
- README.md
|
@@ -133,7 +134,11 @@ files:
|
|
133
134
|
- lib/yabeda/base_adapter.rb
|
134
135
|
- lib/yabeda/counter.rb
|
135
136
|
- lib/yabeda/dsl.rb
|
137
|
+
- lib/yabeda/dsl/class_methods.rb
|
138
|
+
- lib/yabeda/dsl/metric_builder.rb
|
139
|
+
- lib/yabeda/dsl/option_builder.rb
|
136
140
|
- lib/yabeda/gauge.rb
|
141
|
+
- lib/yabeda/group.rb
|
137
142
|
- lib/yabeda/histogram.rb
|
138
143
|
- lib/yabeda/metric.rb
|
139
144
|
- lib/yabeda/version.rb
|