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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa2389240d853b1e917ca4741cd9d8ca0c9bde03
4
- data.tar.gz: 43aae361bf5632fea1641a3914f2b5390759cffe
3
+ metadata.gz: d67f1c41f3f2b01e9fb7f25a24f0f1fa937f1cdc
4
+ data.tar.gz: 91448d8ada39aec9c5210c350ebdab9ae62a4279
5
5
  SHA512:
6
- metadata.gz: a081b0689cd5e2f0f2a3c192a54832459a0935f020aa7392a23ec3e4d9771fdff89280b120e57219e14507c597f38266ce71ae6150f67118ff7459fb42cf33be
7
- data.tar.gz: 7eb2cd49a592a382610031303a10a1eeb4313c2893aa1c5d40e48ce0d7446dd04af2cd119aefaf5d2a5860f21f6252e4fa3401f6ef804f57f4b41ce4c6b9f1a7
6
+ metadata.gz: c2f5d3f51fc14366b6fd9b68db14f1591d388aa5c6628de2f6412f47448f355b60c850497bd347ad60a2baaefe127fa76e15259e9d73219f9ce75b803d61959d
7
+ data.tar.gz: 885e84f73efec668d70b20377c56770b53ff496f9bc045bf43fe5078453b25e45a02fae26c5bf866fe99bafc6b6886dadb431c613a02d8dadb72b4051c0d86c7
data/.codeclimate.yml CHANGED
@@ -3,7 +3,7 @@ engines:
3
3
  brakeman:
4
4
  enabled: false
5
5
  bundler-audit:
6
- enabled: true
6
+ enabled: false
7
7
  duplication:
8
8
  enabled: true
9
9
  config:
data/Guardfile CHANGED
@@ -1,5 +1,5 @@
1
- guard :rspec, cmd: "bundle exec rspec" do
2
- require "guard/rspec/dsl"
1
+ guard :rspec, cmd: 'bundle exec rspec' do
2
+ require 'guard/rspec/dsl'
3
3
  dsl = Guard::RSpec::Dsl.new(self)
4
4
 
5
5
  # Feel free to open issues for suggestions and improvements
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.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
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "yodeler"
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 "irb"
13
+ require 'irb'
14
14
  IRB.start
@@ -5,7 +5,7 @@ module Yodeler
5
5
  @name = name
6
6
  msg = [
7
7
  "No Yodeler Adapter registed for: ':#{name}'",
8
- "Register an adapter with:",
8
+ 'Register an adapter with:',
9
9
  "Yodeler.register_adapter(:#{name}, CustomAdapterClass)"
10
10
  ].join("\n")
11
11
  super(msg)
@@ -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
- (@handlers[metric.type] || @handlers[:default]).call(url, metric, default_params)
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}"
@@ -1,8 +1,7 @@
1
1
  module Yodeler::Adapters
2
2
  class VoidAdapter
3
-
4
3
  def dispatch(*)
5
- #noop
4
+ # noop
6
5
  end
7
6
 
8
7
  Yodeler.register_adapter(:void, self)
@@ -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 = Socket.gethostname
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=:default, &block)
22
- raise DuplicateEndpointNameError.new(name: name) if @endpoints[name]
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,&block)
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 ,&block)
44
- endpoint() if @endpoints.empty?
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.kind_of?(Hash)
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.kind_of?(Hash)
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
- _retval = nil
102
-
118
+ retval = nil
103
119
  if block_given?
104
- start = Time.now
105
- _retval = yield
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
- _retval || metric
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.image_url})
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 ([]) array of tags to apply to metric/event
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 array of endpoint names to send the metric to. If not set will send to {Yodeler::Client#default_endpoint_name}
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?
@@ -28,8 +28,6 @@ module Yodeler
28
28
  @adapter
29
29
  end
30
30
 
31
- def adapter
32
- @adapter
33
- end
31
+ attr_reader :adapter
34
32
  end
35
33
  end
@@ -1,36 +1,54 @@
1
- class Yodeler::Metric
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
- def name
16
- @prefix ? [@prefix, @name].join('.') : @name
17
- end
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
- # @return [Boolean] Should this metric be sampled
20
- def sample?
21
- @_sample ||= !(rand()> @sample_rate)
22
- end
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
- def to_hash
25
- hash = {
26
- name: name,
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
- hash[:tags] = options[:tags] if options[:tags] && options[:tags].any?
32
- hash[:hostname] = options[:hostname] if options[:hostname]
45
+ hash
46
+ end
33
47
 
34
- hash
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
@@ -1,3 +1,3 @@
1
1
  module Yodeler
2
- VERSION = "0.1.1"
2
+ VERSION = '0.1.2'
3
3
  end
data/lib/yodeler.rb CHANGED
@@ -1,13 +1,13 @@
1
- require "yaml"
1
+ require 'yaml'
2
2
  require 'forwardable'
3
3
 
4
- require "yodeler/version"
5
- require "yodeler/endpoint"
6
- require "yodeler/client"
7
- require "yodeler/metric"
4
+ require 'yodeler/version'
5
+ require 'yodeler/endpoint'
6
+ require 'yodeler/client'
7
+ require 'yodeler/metric'
8
8
 
9
- require "yodeler/duplicate_endpoint_name_error"
10
- require "yodeler/adapter_not_registered_error"
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
- if !klass
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
- def client
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 "yodeler/adapters/memory_adapter"
57
- require "yodeler/adapters/http_adapter"
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 = "yodeler"
7
+ spec.name = 'yodeler'
8
8
  spec.version = Yodeler::VERSION
9
9
  spec.authors = ["Cory O'Daniel"]
10
- spec.email = ["github@coryodaniel.com"]
11
- spec.description = "A generic instrumentation library thats supports reporting to multiple endpoints via pluggable backend adapters."
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 = "http://github.com/coryodaniel/yodeler"
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 = "exe"
16
+ spec.bindir = 'exe'
17
17
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
19
19
 
20
- spec.add_dependency "http"
20
+ spec.add_dependency 'http'
21
21
 
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"
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.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-12 00:00:00.000000000 Z
11
+ date: 2016-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http