yodeler 0.1.1 → 0.1.2
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/.codeclimate.yml +1 -1
- data/Guardfile +2 -2
- data/README.md +11 -2
- data/Rakefile +3 -3
- data/bin/console +3 -3
- data/lib/yodeler/adapter_not_registered_error.rb +1 -1
- data/lib/yodeler/adapters/http_adapter.rb +4 -2
- data/lib/yodeler/adapters/void_adapter.rb +1 -2
- data/lib/yodeler/client.rb +44 -22
- data/lib/yodeler/endpoint.rb +1 -3
- data/lib/yodeler/metric.rb +47 -29
- data/lib/yodeler/version.rb +1 -1
- data/lib/yodeler.rb +12 -16
- data/yodeler.gemspec +14 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d67f1c41f3f2b01e9fb7f25a24f0f1fa937f1cdc
|
4
|
+
data.tar.gz: 91448d8ada39aec9c5210c350ebdab9ae62a4279
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2f5d3f51fc14366b6fd9b68db14f1591d388aa5c6628de2f6412f47448f355b60c850497bd347ad60a2baaefe127fa76e15259e9d73219f9ce75b803d61959d
|
7
|
+
data.tar.gz: 885e84f73efec668d70b20377c56770b53ff496f9bc045bf43fe5078453b25e45a02fae26c5bf866fe99bafc6b6886dadb431c613a02d8dadb72b4051c0d86c7
|
data/.codeclimate.yml
CHANGED
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -13,7 +13,7 @@ Spoutin' off noise to whoever is listening.
|
|
13
13
|
Add this line to your application's Gemfile:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
gem 'yodeler', '~>0.1.
|
16
|
+
gem 'yodeler', '~>0.1.2'
|
17
17
|
```
|
18
18
|
|
19
19
|
And then execute:
|
@@ -40,6 +40,11 @@ Yodeler.configure do |client|
|
|
40
40
|
# http.use_ssl = false
|
41
41
|
# http.default_params = {}
|
42
42
|
end
|
43
|
+
|
44
|
+
# if no timestamp_format is set, defaults to UTC ISO8601
|
45
|
+
client.timestamp_format = :iso8601
|
46
|
+
#client.timestamp_format = :epoch
|
47
|
+
#client.timestamp_format = -> { Time.now.whatever.you_feel_like! }
|
43
48
|
end
|
44
49
|
```
|
45
50
|
|
@@ -102,7 +107,7 @@ Yodeler.configure do |client|
|
|
102
107
|
}
|
103
108
|
|
104
109
|
# Overwrite the default http dispatcher or overwrite an individual metric dispatcher
|
105
|
-
# http.handle(:gauge){|url, metric, default_params| ... something cool ... }
|
110
|
+
# http.handle(:gauge){ |url, metric, default_params| ... something cool ... }
|
106
111
|
http.handle(:default) do |url, metric, default_params|
|
107
112
|
# This is the default handler definition, but you could change it
|
108
113
|
HTTP.post(url, json: default_params.merge(metric.to_hash))
|
@@ -195,3 +200,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/coryod
|
|
195
200
|
* [ ] Custom adapter documentation
|
196
201
|
* [ ] Client#format_options -> Metric.format_options
|
197
202
|
* [ ] Client#default_endpoint_name accept array of names
|
203
|
+
* [ ] Dispatch to any object or proc, if adapter not registered
|
204
|
+
* client.endpoint(:dashboard).use(:something_that_responds_to_dispatch)
|
205
|
+
* client.endpoint(:dashboard).use{ |metric| MyWorker.perform_later(metric) }
|
206
|
+
* [ ] more yard docs
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'yodeler'
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require "yodeler"
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require 'irb'
|
14
14
|
IRB.start
|
@@ -8,7 +8,7 @@ module Yodeler::Adapters
|
|
8
8
|
attr_accessor :use_ssl
|
9
9
|
attr_accessor :default_params
|
10
10
|
|
11
|
-
def initialize(host=nil, port:nil, path:nil, use_ssl:false, params:{})
|
11
|
+
def initialize(host = nil, port:nil, path:nil, use_ssl:false, params:{})
|
12
12
|
@host = host
|
13
13
|
@port = port
|
14
14
|
@path = path
|
@@ -26,7 +26,8 @@ module Yodeler::Adapters
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def dispatch(metric)
|
29
|
-
|
29
|
+
dispatcher = @handlers[metric.type] || @handlers[:default]
|
30
|
+
dispatcher.call(url, metric, default_params)
|
30
31
|
end
|
31
32
|
|
32
33
|
def url
|
@@ -34,6 +35,7 @@ module Yodeler::Adapters
|
|
34
35
|
end
|
35
36
|
|
36
37
|
private
|
38
|
+
|
37
39
|
def host_with_port
|
38
40
|
if port
|
39
41
|
"#{host}:#{port}"
|
data/lib/yodeler/client.rb
CHANGED
@@ -5,23 +5,40 @@ module Yodeler
|
|
5
5
|
attr_accessor :default_endpoint_name
|
6
6
|
attr_accessor :default_prefix
|
7
7
|
attr_accessor :default_sample_rate
|
8
|
+
attr_accessor :timestamp_format
|
8
9
|
attr_reader :endpoints
|
9
10
|
|
11
|
+
TIMESTAMP_FORMATS = {
|
12
|
+
iso8601: -> { Time.now.utc.iso8601 },
|
13
|
+
epoch: -> { Time.now.to_i }
|
14
|
+
}
|
15
|
+
|
10
16
|
def initialize
|
11
17
|
@endpoints = {}
|
12
18
|
@default_sample_rate = 1.0
|
13
19
|
@default_prefix = nil
|
14
|
-
@hostname
|
20
|
+
@hostname = Socket.gethostname
|
21
|
+
@timestamp_format = :iso8601
|
22
|
+
end
|
23
|
+
|
24
|
+
def timestamp_generator
|
25
|
+
if timestamp_format.is_a?(Symbol) && TIMESTAMP_FORMATS[timestamp_format]
|
26
|
+
TIMESTAMP_FORMATS[timestamp_format].call
|
27
|
+
elsif timestamp_format.is_a?(Proc)
|
28
|
+
timestamp_format.call
|
29
|
+
else
|
30
|
+
raise ArgumentError, "Time format not recognized: #{timestamp_format}. \nOptions are #{TIMESTAMP_FORMATS.join(', ')} or a lamba"
|
31
|
+
end
|
15
32
|
end
|
16
33
|
|
17
34
|
# Register a new endpoint
|
18
35
|
#
|
19
36
|
# @param [Symbol|String] name of endpoint, must be unique
|
20
37
|
# @return [Yodeler::Endpoint]
|
21
|
-
def endpoint(name
|
22
|
-
|
38
|
+
def endpoint(name = :default, &block)
|
39
|
+
fail DuplicateEndpointNameError.new(name: name) if @endpoints[name]
|
23
40
|
@default_endpoint_name ||= name
|
24
|
-
@endpoints[name] = Endpoint.new(name
|
41
|
+
@endpoints[name] = Endpoint.new(name, &block)
|
25
42
|
end
|
26
43
|
|
27
44
|
# Get the default endpoint
|
@@ -40,8 +57,8 @@ module Yodeler
|
|
40
57
|
# @param [Symbol] name registered adapter name
|
41
58
|
# @param [Type] &block configuration for adapter
|
42
59
|
# @return [~Yodeler::Adapters::Base] the adapter
|
43
|
-
def adapter(name
|
44
|
-
endpoint
|
60
|
+
def adapter(name, &block)
|
61
|
+
endpoint if @endpoints.empty?
|
45
62
|
default_endpoint.use(name, &block)
|
46
63
|
end
|
47
64
|
|
@@ -55,7 +72,7 @@ module Yodeler
|
|
55
72
|
# @param [~Fixnum] value of the metric
|
56
73
|
# @param [Hash] opts={} Examples {#format_options}
|
57
74
|
# @return [Yodeler::Metric, nil] the dispatched metric, nil if not sampled
|
58
|
-
def gauge(name, value, opts={})
|
75
|
+
def gauge(name, value, opts = {})
|
59
76
|
dispatch(:gauge, name, value, opts)
|
60
77
|
end
|
61
78
|
|
@@ -70,8 +87,8 @@ module Yodeler
|
|
70
87
|
# @param [~Fixnum] value=1 of the metric
|
71
88
|
# @param [Hash] opts={} Examples {#format_options}
|
72
89
|
# @return [Yodeler::Metric, nil] the dispatched metric, nil if not sampled
|
73
|
-
def increment(name, value=1, opts={})
|
74
|
-
if value.
|
90
|
+
def increment(name, value = 1, opts = {})
|
91
|
+
if value.is_a?(Hash)
|
75
92
|
opts = value
|
76
93
|
value = 1
|
77
94
|
end
|
@@ -92,56 +109,60 @@ module Yodeler
|
|
92
109
|
# @return [Yodeler::Metric, nil, Object]
|
93
110
|
# the dispatched metric, nil if not sampled
|
94
111
|
# if a block is given the result of the block is returned
|
95
|
-
def timing(name, value=nil, opts={})
|
96
|
-
if value.
|
112
|
+
def timing(name, value = nil, opts = {})
|
113
|
+
if value.is_a?(Hash)
|
97
114
|
opts = value
|
98
115
|
value = nil
|
99
116
|
end
|
100
117
|
|
101
|
-
|
102
|
-
|
118
|
+
retval = nil
|
103
119
|
if block_given?
|
104
|
-
start = Time.now
|
105
|
-
|
106
|
-
value = Time.now - start
|
120
|
+
start = Time.now.to_i
|
121
|
+
retval = yield
|
122
|
+
value = Time.now.to_i - start
|
107
123
|
end
|
108
124
|
|
109
125
|
metric = dispatch(:timing, name, value, opts)
|
110
|
-
|
126
|
+
retval || metric
|
111
127
|
end
|
112
128
|
|
113
129
|
# Publish an event
|
114
130
|
#
|
115
131
|
# @example
|
116
132
|
# client.publish('item.sold', purchase.to_json)
|
117
|
-
# client.publish('user.sign_up', {name: user.name, avatar: user.
|
133
|
+
# client.publish('user.sign_up', {name: user.name, avatar: user.image})
|
118
134
|
#
|
119
135
|
# @param [~String] name of the metric
|
120
136
|
# @param [~Hash] value of the metric
|
121
137
|
# @param [Hash] opts={} Examples {#format_options}
|
122
138
|
# @return [Yodeler::Metric, nil] the dispatched metric, nil if not sampled
|
123
|
-
def publish(name, payload, opts={})
|
139
|
+
def publish(name, payload, opts = {})
|
124
140
|
dispatch(:event, name, payload, opts)
|
125
141
|
end
|
126
142
|
|
127
143
|
# Formats/Defaults metric options
|
128
144
|
#
|
129
145
|
# @param [Hash] opts metric options
|
130
|
-
# @option opts [Array<String,Symbol>, String, Symbol] :tags ([])
|
146
|
+
# @option opts [Array<String,Symbol>, String, Symbol] :tags ([])
|
147
|
+
# array of tags to apply to metric/event
|
131
148
|
# @option opts [Float] :sample_rate (1.0) The sample rate to use
|
132
|
-
# @option opts [Array<Symbol>, Symbol] :to
|
149
|
+
# @option opts [Array<Symbol>, Symbol] :to
|
150
|
+
# array of endpoint names to send the metric to.
|
151
|
+
# If not set will send to {Yodeler::Client#default_endpoint_name}
|
133
152
|
# @return [Hash] formatted, defaulted options
|
134
153
|
def format_options(opts)
|
135
154
|
endpoint_names = opts.delete(:to) || [default_endpoint_name]
|
136
155
|
tags = opts.delete(:tags)
|
137
156
|
prefix = opts.delete(:prefix) || default_prefix
|
157
|
+
timestamp = opts.delete(:timestamp) || timestamp_generator
|
138
158
|
|
139
159
|
{
|
140
160
|
prefix: prefix,
|
141
161
|
to: [endpoint_names].flatten.compact,
|
142
162
|
sample_rate: opts.delete(:sample_rate) || default_sample_rate,
|
143
163
|
tags: [tags].flatten.compact,
|
144
|
-
hostname: @hostname
|
164
|
+
hostname: @hostname,
|
165
|
+
timestamp: timestamp
|
145
166
|
}
|
146
167
|
end
|
147
168
|
|
@@ -150,6 +171,7 @@ module Yodeler
|
|
150
171
|
def dispatch(type, name, value, opts)
|
151
172
|
opts = format_options(opts)
|
152
173
|
destinations = opts.delete(:to)
|
174
|
+
|
153
175
|
metric = Metric.new(type, name, value, opts)
|
154
176
|
|
155
177
|
return nil unless metric.sample?
|
data/lib/yodeler/endpoint.rb
CHANGED
data/lib/yodeler/metric.rb
CHANGED
@@ -1,36 +1,54 @@
|
|
1
|
-
|
2
|
-
attr_reader :type, :value
|
3
|
-
attr_reader :sample_rate, :tags, :prefix
|
4
|
-
attr_reader :options
|
5
|
-
|
6
|
-
def initialize(type, name, value, opts={})
|
7
|
-
@type = type
|
8
|
-
@name = name
|
9
|
-
@value = value
|
10
|
-
@prefix = opts.delete(:prefix)
|
11
|
-
@sample_rate = opts.delete(:sample_rate)
|
12
|
-
@options = opts
|
13
|
-
end
|
1
|
+
require 'securerandom'
|
14
2
|
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
module Yodeler
|
4
|
+
class Metric
|
5
|
+
attr_reader :type, :value
|
6
|
+
attr_reader :sample_rate, :tags, :prefix
|
7
|
+
attr_reader :uuid
|
8
|
+
attr_reader :options
|
18
9
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
10
|
+
TYPES = [:event, :increment, :gauge, :timing]
|
11
|
+
|
12
|
+
def initialize(type, name, value, opts = {})
|
13
|
+
@uuid = SecureRandom.uuid
|
14
|
+
@type = type
|
15
|
+
@name = name
|
16
|
+
@value = value
|
17
|
+
@prefix = opts.delete(:prefix)
|
18
|
+
@sample_rate = opts.delete(:sample_rate)
|
19
|
+
@timestamp = opts.delete(:timestamp)
|
20
|
+
@tags = opts.delete(:tags)
|
21
|
+
@hostname = opts.delete(:hostname)
|
22
|
+
end
|
23
|
+
|
24
|
+
def name
|
25
|
+
@prefix ? [@prefix, @name].join('.') : @name
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Boolean] Should this metric be sampled
|
29
|
+
def sample?
|
30
|
+
@_sample ||= !(rand > @sample_rate)
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_hash
|
34
|
+
hash = {
|
35
|
+
uuid: uuid,
|
36
|
+
name: name,
|
37
|
+
type: @type,
|
38
|
+
value: @value
|
39
|
+
}
|
23
40
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
type: @type,
|
28
|
-
value: @value,
|
29
|
-
}
|
41
|
+
hash[:timestamp] = @timestamp if @timestamp
|
42
|
+
hash[:tags] = @tags if @tags && @tags.any?
|
43
|
+
hash[:hostname] = @hostname if @hostname
|
30
44
|
|
31
|
-
|
32
|
-
|
45
|
+
hash
|
46
|
+
end
|
33
47
|
|
34
|
-
|
48
|
+
TYPES.each do |type_meth|
|
49
|
+
define_method("#{type_meth}?") do
|
50
|
+
type_meth.to_sym == type
|
51
|
+
end
|
52
|
+
end
|
35
53
|
end
|
36
54
|
end
|
data/lib/yodeler/version.rb
CHANGED
data/lib/yodeler.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
require
|
1
|
+
require 'yaml'
|
2
2
|
require 'forwardable'
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
4
|
+
require 'yodeler/version'
|
5
|
+
require 'yodeler/endpoint'
|
6
|
+
require 'yodeler/client'
|
7
|
+
require 'yodeler/metric'
|
8
8
|
|
9
|
-
require
|
10
|
-
require
|
9
|
+
require 'yodeler/duplicate_endpoint_name_error'
|
10
|
+
require 'yodeler/adapter_not_registered_error'
|
11
11
|
|
12
12
|
module Yodeler
|
13
13
|
class << self
|
@@ -21,7 +21,7 @@ module Yodeler
|
|
21
21
|
@registered_adapters = {}
|
22
22
|
end
|
23
23
|
|
24
|
-
def register_adapter(name,klass)
|
24
|
+
def register_adapter(name, klass)
|
25
25
|
@registered_adapters[name] = klass
|
26
26
|
end
|
27
27
|
|
@@ -29,9 +29,7 @@ module Yodeler
|
|
29
29
|
# @private
|
30
30
|
def registered_adapters(name)
|
31
31
|
klass = @registered_adapters[name]
|
32
|
-
|
33
|
-
raise AdapterNotRegisteredError.new(name: name)
|
34
|
-
end
|
32
|
+
fail AdapterNotRegisteredError.new(name: name) unless klass
|
35
33
|
@registered_adapters[name]
|
36
34
|
end
|
37
35
|
|
@@ -40,9 +38,7 @@ module Yodeler
|
|
40
38
|
setup!
|
41
39
|
end
|
42
40
|
|
43
|
-
|
44
|
-
@client
|
45
|
-
end
|
41
|
+
attr_reader :client
|
46
42
|
|
47
43
|
def configure
|
48
44
|
@client = Yodeler::Client.new
|
@@ -53,5 +49,5 @@ module Yodeler
|
|
53
49
|
end
|
54
50
|
|
55
51
|
Yodeler.setup!
|
56
|
-
require
|
57
|
-
require
|
52
|
+
require 'yodeler/adapters/memory_adapter'
|
53
|
+
require 'yodeler/adapters/http_adapter'
|
data/yodeler.gemspec
CHANGED
@@ -4,26 +4,26 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'yodeler/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'yodeler'
|
8
8
|
spec.version = Yodeler::VERSION
|
9
9
|
spec.authors = ["Cory O'Daniel"]
|
10
|
-
spec.email = [
|
11
|
-
spec.description =
|
10
|
+
spec.email = ['github@coryodaniel.com']
|
11
|
+
spec.description = 'A generic instrumentation library thats supports reporting to multiple endpoints via pluggable backend adapters.'
|
12
12
|
spec.summary = "A generic instrumentation library thats supports reporting to multiple endpoints via pluggable backend adapters. Spoutin' off noise to whoever is listening."
|
13
|
-
spec.homepage =
|
13
|
+
spec.homepage = 'http://github.com/coryodaniel/yodeler'
|
14
14
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
-
spec.bindir =
|
16
|
+
spec.bindir = 'exe'
|
17
17
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
-
spec.require_paths = [
|
18
|
+
spec.require_paths = ['lib']
|
19
19
|
|
20
|
-
spec.add_dependency
|
20
|
+
spec.add_dependency 'http'
|
21
21
|
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
23
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
spec.add_development_dependency 'rspec'
|
25
|
+
spec.add_development_dependency 'webmock'
|
26
|
+
spec.add_development_dependency 'rspec-mocks'
|
27
|
+
spec.add_development_dependency 'guard-rspec'
|
28
|
+
spec.add_development_dependency 'codeclimate-test-reporter'
|
29
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yodeler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cory O'Daniel
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http
|