yabeda 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/yabeda.svg)](https://rubygems.org/gems/yabeda) [![Build Status](https://travis-ci.org/yabeda-rb/yabeda.svg?branch=master)](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
|