hallmonitor 4.2.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4d6589305a3290c2bf628e2a55f5ca6d13d4616b
4
- data.tar.gz: 1e616bf4cb119aae142a64c4f70a6b043d5bf8a4
3
+ metadata.gz: 54c0631a67fb95ae8201691fdd5e5e12c09936f1
4
+ data.tar.gz: d0dddea0967b40bfeea62612157649eeef033711
5
5
  SHA512:
6
- metadata.gz: 3233ea964e32edbe665230f4f32e434b4988acacce629b12ae763d2313d7d5ef3a549e1f37af6685c3f4c8cf93f1870c33e7963925f70b11284869591f0518b2
7
- data.tar.gz: 565ec6ba834afa8b0e81296a38df618c09ba759682d928b0ae69ec11301e6e8c7b3bd02f2800391b3c5be460f57288bc9eae3ecfd11920d9b0c2a15c3f01f515
6
+ metadata.gz: 0e314315927b4dbaa450022ac88e054ff6e1e230a5f81db0930cab21e54c7e28d20d3521d17cce6671897f1837f8ad7a400409038f7e0a2e8e34e4da4e721045
7
+ data.tar.gz: 193b9d428e2cca3a95618f5a8b77853fefd8194673f2bf83ef8937326c05c0c47ad667c5328372a99845c4ae862b4f6acf948a77ec1e64b8de9e3721ceff5349
data/README.md CHANGED
@@ -2,21 +2,32 @@
2
2
 
3
3
  Hallmonitor is a simple event monitoring framework for Ruby. It allows programs to define and emit events. These events can then be sent on to various back ends to be counted, monitored, etc.
4
4
 
5
- Hallmonitor includes support for publishing events to a Statsd instance if the `statsd-ruby` gem is installed. See https://github.com/reinh/statsd for details.
6
- It also includes support for outputting events to InfluxDB if the 'influxdb' gem is installed.
5
+ Hallmonitor includes support for the following outputters:
6
+
7
+ - [Statsd](https://github.com/reinh/statsd) - Requires the `statsd` gem to be installed
8
+ - [InfluxDB](https://github.com/influxdata/influxdb-ruby) - Requires the `influxdb` gem to be installed
9
+ - [Datadog](https://github.com/DataDog/dogstatsd-ruby) - Requires the `dogstatsd-ruby` gem to be installed
10
+ - IOOutputter - Simple outputter that outputs to an IO object
11
+ - [NewRelic](https://github.com/newrelic/rpm) - Requires the `newrelic_rpm` gem to be installed
12
+
7
13
 
8
14
  ## Setup
9
15
  Before you can use Hallmonitor you have to do a tiny bit of configuration in the form of adding outputters.
10
16
 
11
17
  ```ruby
12
18
  # Add an outputter to STDOUT
19
+ require 'hallmonitor/outputters/iooutputter.rb'
13
20
  Hallmonitor.add_outputter Hallmonitor::Outputters::IOOutputter.new("STDOUT", STDOUT)
14
21
 
15
22
  # Add an outputter to StatsD
23
+ require 'hallmonitor/outputters/statsd_outputter'
16
24
  Hallmonitor.add_outputter Hallmonitor::Outputters::StatsdOutputter.new("example", "localhost")
17
- ```
18
25
 
19
- The `StatsdOutputter` is only available if you've installed the `statsd-ruby` gem. If it's not available, StatsdOutputter's intitialize method will raise a RuntimeError
26
+ # Add an outputter to Datadog
27
+ require 'hallmonitor/outputters/datadog
28
+ datadog = Datadog::Statsd.new
29
+ Hallmonitor.add_outputter Hallmonitor::Outputters::Datadog.new(datadog)
30
+ ```
20
31
 
21
32
  ## Configuration
22
33
  Right now there's only one configuration option and here's how you can set it:
@@ -90,5 +101,5 @@ event.emit
90
101
 
91
102
  ## Copyright
92
103
 
93
- Copyright (c) 2012-2015 Chris TenHarmsel. See LICENSE.txt for
104
+ Copyright (c) 2012-2018 Chris TenHarmsel. See LICENSE.txt for
94
105
  further details.
@@ -21,5 +21,13 @@ module Hallmonitor
21
21
  self.count = new_value
22
22
  end
23
23
 
24
+ def to_json(*a)
25
+ {
26
+ name: name,
27
+ time: time,
28
+ value: count,
29
+ tags: tags
30
+ }.to_json(*a)
31
+ end
24
32
  end
25
33
  end
@@ -9,16 +9,18 @@ module Hallmonitor
9
9
  # @options [Hash] Optional settings:
10
10
  # metric_name: [String] Metric name to emit, defaults to
11
11
  # "#{underscore(name)}.#{method_sym}"
12
- def timer_for(method_sym, options = {})
13
- metric_name = options[:metric_name] || "#{underscore(name)}.#{method_sym}"
14
- send(:define_method, "#{method_sym}_with_hallmonitor_timer") do |*args|
15
- watch(metric_name) do
16
- send("#{method_sym}_without_hallmonitor_timer".to_sym, *args)
12
+ def timer_for(method_sym, metric_name: nil, tags: {})
13
+ metric_name ||= "#{underscore(name)}.#{method_sym}"
14
+ undecorated_method_sym = "#{method_sym}_without_hallmonitor_timer".to_sym
15
+ decorated_method_sym = "#{method_sym}_with_hallmonitor_timer".to_sym
16
+ send(:define_method, decorated_method_sym) do |*args|
17
+ watch(metric_name, tags: tags) do
18
+ send(undecorated_method_sym, *args)
17
19
  end
18
20
  end
19
21
 
20
- alias_method "#{method_sym}_without_hallmonitor_timer".to_sym, method_sym
21
- alias_method method_sym, "#{method_sym}_with_hallmonitor_timer".to_sym
22
+ alias_method undecorated_method_sym, method_sym
23
+ alias_method method_sym, decorated_method_sym
22
24
  end
23
25
 
24
26
  # Sets up a counter for a method by symbol. Method must have already been
@@ -27,17 +29,20 @@ module Hallmonitor
27
29
  # @options [Hash] Optional settings:
28
30
  # metric_name: [String] Metric name to emit, defaults to
29
31
  # "#{underscore(name)}.#{method_sym}"
30
- def count_for(method_sym, options = {})
31
- metric_name = options[:metric_name] || "#{underscore(name)}.#{method_sym}"
32
- send(:define_method, "#{method_sym}_with_hallmonitor_counter") do |*args|
33
- emit(metric_name)
34
- send("#{method_sym}_without_hallmonitor_counter".to_sym, *args)
32
+ def count_for(method_sym, metric_name: nil, tags: {})
33
+ metric_name ||= "#{underscore(name)}.#{method_sym}"
34
+ undecorated_method_sym = "#{method_sym}_without_hallmonitor_counter".to_sym
35
+ decorated_method_sym = "#{method_sym}_with_hallmonitor_counter".to_sym
36
+ send(:define_method, decorated_method_sym) do |*args|
37
+ emit(metric_name, tags: tags)
38
+ send(undecorated_method_sym, *args)
35
39
  end
36
40
 
37
- alias_method "#{method_sym}_without_hallmonitor_counter".to_sym, method_sym
38
- alias_method method_sym, "#{method_sym}_with_hallmonitor_counter".to_sym
41
+ alias_method undecorated_method_sym, method_sym
42
+ alias_method method_sym, decorated_method_sym
39
43
  end
40
44
 
45
+ # :reek:UtilityFunction
41
46
  def underscore(value)
42
47
  word = value.dup
43
48
  word.gsub!(/::/, '.')
@@ -51,17 +56,19 @@ module Hallmonitor
51
56
 
52
57
  def self.included(base)
53
58
  base.extend(ClassMethods)
59
+ base.extend(self)
54
60
  end
55
61
 
56
- # Emits an event: self if the event param is nil, the passed in event if
57
- # it's an {Event}, or constructs a {Event} from the passed in param.
62
+ # Emits an event: self if the event param is nil, the passed in
63
+ # event if it's an {Event}, or constructs a {Event} from the
64
+ # passed in param.
65
+ #
66
+ # If the parameter is a {Hallmonitor::Event}, it will be emitted
67
+ # as is. Otherwise, a new {Hallmonitor::Event} will be created
68
+ # with the parameter and emitted.
58
69
  #
59
- # If the parameter is a {Hallmonitor::Event}, it will be emitted as is.
60
- # Otherwise, a new {Hallmonitor::Event} will be created with the parameter
61
- # and emitted.
62
70
  # @param event [Mixed] The thing to emit, see method description
63
71
  # @yield [to_emit] The thing that's going to be emitted
64
- # @return nil
65
72
  def emit(event = nil, tags: {})
66
73
  to_emit = self
67
74
  unless event.nil?
@@ -0,0 +1,82 @@
1
+ begin
2
+ require 'datadog/statsd'
3
+ rescue LoadError
4
+ end
5
+
6
+ module Hallmonitor
7
+ module Outputters
8
+ # An outputter for Dogstatsd
9
+ class Datadog < Outputter
10
+ # Simple EventData struct
11
+ EventData = Struct.new(:name, :value, :tags, :type)
12
+
13
+ # Builds a new DogstatsdOutputter.
14
+ # @param dogstatsd [Datadog::Statsd] Dogstatd client instance to use
15
+ # @param tags [Hash] Default tags to apply to all metrics sent to this outputter
16
+ def initialize(dogstatsd, tags: {})
17
+ super('dogstatsd')
18
+ @tags = {}.merge(tags)
19
+ @statsd = dogstatsd
20
+ end
21
+
22
+ # Sends events to datadog statsd instance
23
+ #
24
+ # If the event's value field is a hash, this will send multiple
25
+ # events to statsd with the original name suffixed by the name
26
+ # of the events in the hash
27
+ def process(event)
28
+ event_data = build_event_data(event)
29
+ write(event_data)
30
+ end
31
+
32
+ private
33
+
34
+ # :reek:FeatureEnvy
35
+ def write(event_data)
36
+ event_data.each do |data|
37
+ @statsd.send(data.type, data.name, data.value, tags: data.tags)
38
+ end
39
+ end
40
+
41
+ def build_event_data(event)
42
+ case event
43
+ when Hallmonitor::TimedEvent
44
+ build_timed_data(event)
45
+ when Hallmonitor::GaugeEvent
46
+ build_gauge_data(event)
47
+ else
48
+ build_count_data(event)
49
+ end
50
+ end
51
+
52
+ def build_timed_data(event)
53
+ build_data(event, event.duration, :timing)
54
+ end
55
+
56
+ def build_gauge_data(event)
57
+ build_data(event, event.value, :gauge)
58
+ end
59
+
60
+ def build_count_data(event)
61
+ build_data(event, event.count, :count)
62
+ end
63
+
64
+ # :reek:FeatureEnvy
65
+ def build_data(event, value, type)
66
+ event_name = event.name
67
+ tags = process_tags(event.tags)
68
+ if value.is_a?(Hash)
69
+ value.map do |name, value|
70
+ EventData.new("#{event_name}.#{name}", value, tags, type)
71
+ end
72
+ else
73
+ [EventData.new(event_name, value, tags, type)]
74
+ end
75
+ end
76
+
77
+ def process_tags(tags)
78
+ @tags.merge(tags).map { |key, value| "#{key}:#{value}" }
79
+ end
80
+ end
81
+ end
82
+ end
@@ -36,11 +36,12 @@ module Hallmonitor
36
36
 
37
37
  def to_json(*a)
38
38
  {
39
- name: @name,
40
- time: @time,
39
+ name: name,
40
+ time: time,
41
41
  start: @start,
42
42
  stop: @stop,
43
- duration: duration
43
+ duration: duration,
44
+ tags: tags
44
45
  }.to_json(*a)
45
46
  end
46
47
  end
@@ -1,7 +1,7 @@
1
1
  module Hallmonitor
2
2
  module Version
3
- MAJOR = 4
4
- MINOR = 2
3
+ MAJOR = 5
4
+ MINOR = 0
5
5
  PATCH = 0
6
6
  BUILD = nil
7
7
 
@@ -6,24 +6,28 @@ class Thing
6
6
  def timer_for_test
7
7
  # Nothing
8
8
  end
9
- timer_for :timer_for_test
9
+ timer_for :timer_for_test, metric_name: 'thing.measure', tags: {foo: 'bar'}
10
10
 
11
11
  def count_for_test
12
12
  # Nothing
13
13
  end
14
- count_for :count_for_test
14
+ count_for :count_for_test, metric_name: 'thing.execute', tags: {foo: 'bar'}
15
15
  end
16
16
 
17
- RSpec::Matchers.define :an_event_with_name do |expected_name|
18
- match { |actual| actual.is_a?(Hallmonitor::Event) && actual.name == expected_name }
17
+ RSpec::Matchers.define :an_event do
18
+ match { |actual| actual.is_a?(Hallmonitor::Event)}
19
19
  end
20
20
 
21
- RSpec::Matchers.define :an_event_with_tags do |expected_tags|
22
- match { |actual| actual.is_a?(Hallmonitor::Event) && actual.tags == expected_tags}
21
+ RSpec::Matchers.define :a_timed_event do
22
+ match { |actual| actual.is_a?(Hallmonitor::Event)}
23
23
  end
24
24
 
25
- RSpec::Matchers.define :a_timed_event_with_name do |expected_name|
26
- match { |actual| actual.is_a?(Hallmonitor::TimedEvent) && actual.name == expected_name }
25
+ RSpec::Matchers.define :has_name do |expected_name|
26
+ match { |actual| actual.name == expected_name }
27
+ end
28
+
29
+ RSpec::Matchers.define :has_tags do |expected_tags|
30
+ match { |actual| actual.tags == expected_tags}
27
31
  end
28
32
 
29
33
  RSpec.describe Hallmonitor::Monitored do
@@ -32,7 +36,11 @@ RSpec.describe Hallmonitor::Monitored do
32
36
  describe '#timer_for' do
33
37
  it 'emits a timer with an appropriate name' do
34
38
  expect(Hallmonitor::Dispatcher).to(
35
- receive(:output).with(a_timed_event_with_name('thing.timer_for_test')))
39
+ receive(:output)
40
+ .with(
41
+ a_timed_event.and(has_name('thing.measure')).and(has_tags({foo: 'bar'}))
42
+ )
43
+ )
36
44
  Thing.new.timer_for_test
37
45
  end
38
46
  end
@@ -40,33 +48,33 @@ RSpec.describe Hallmonitor::Monitored do
40
48
  describe '#count_for' do
41
49
  it 'emits an event with an appropriate name' do
42
50
  expect(Hallmonitor::Dispatcher).to(
43
- receive(:output).with(an_event_with_name('thing.count_for_test')))
51
+ receive(:output).with(
52
+ an_event.and(has_name('thing.execute')).and(has_tags({foo: 'bar'}))
53
+ )
54
+ )
44
55
  Thing.new.count_for_test
45
56
  end
46
57
  end
47
58
 
48
- describe '#watch' do
59
+ shared_examples 'for watch' do
49
60
  let(:retval) { 'Hello World' }
50
61
  let(:name) { 'foo' }
51
62
 
52
63
  it 'returns the value the block returns' do
53
- value = subject.watch(name) do
54
- retval
55
- end
64
+ value = subject.watch(name) { retval }
56
65
  expect(value).to eq(retval)
57
66
 
58
- value = subject.watch(name) do
59
- nil
60
- end
67
+ value = subject.watch(name) { nil }
61
68
  expect(value).to_not be
62
69
  end
63
70
 
64
71
  it 'emits a timer event for the block' do
65
72
  expect(Hallmonitor::Dispatcher).to(
66
- receive(:output).with(a_timed_event_with_name(name)))
67
- subject.watch(name) do
68
- 'foo'
69
- end
73
+ receive(:output).with(
74
+ an_event.and(has_name(name))
75
+ )
76
+ )
77
+ subject.watch(name) { 'foo' }
70
78
  end
71
79
 
72
80
  describe 'with tags' do
@@ -75,44 +83,53 @@ RSpec.describe Hallmonitor::Monitored do
75
83
 
76
84
  it 'emits an event with tags' do
77
85
  expect(Hallmonitor::Dispatcher).to(
78
- receive(:output).with(an_event_with_tags(tags)))
79
- subject.watch(name, tags: tags) do
80
- 'foo'
81
- end
86
+ receive(:output).with(
87
+ an_event.and(has_tags(tags))
88
+ )
89
+ )
90
+ subject.watch(name, tags: tags) { 'foo' }
82
91
  end
83
92
  end
84
93
 
85
94
  describe 'when the block raises an error' do
86
95
  it 'emits a timer for the block' do
87
96
  expect(Hallmonitor::Dispatcher).to(
88
- receive(:output).with(a_timed_event_with_name(name)))
97
+ receive(:output).with(
98
+ a_timed_event.and(has_name(name))
99
+ )
100
+ )
89
101
  expect do
90
- subject.watch(name) do
91
- fail 'OOPS!'
92
- end
102
+ subject.watch(name) { fail 'OOPS!' }
93
103
  end.to raise_error('OOPS!')
94
104
  end
95
105
  end
96
106
  end
97
107
 
98
- describe '#emit' do
108
+ shared_examples 'for emit' do
99
109
  describe 'with a string parameter' do
100
110
  let(:name) { 'foo' }
101
111
 
102
112
  it 'emits an event with the passed in name' do
103
113
  expect(Hallmonitor::Dispatcher).to(
104
- receive(:output).with(an_event_with_name(name)))
114
+ receive(:output).with(
115
+ an_event.and(has_name(name))
116
+ )
117
+ )
118
+
105
119
  subject.emit(name)
106
120
  end
107
121
  end
108
122
 
109
123
  describe 'with tags' do
110
124
  let(:name) { 'foo'}
111
- let(:tags) { {'foo': 'bar', 'baz': 6}}
125
+ let(:tags) { {'foo' => 'bar', 'baz' => 6}}
112
126
 
113
127
  it 'emits an event with tags' do
114
128
  expect(Hallmonitor::Dispatcher).to(
115
- receive(:output).with(an_event_with_tags(tags)))
129
+ receive(:output).with(
130
+ an_event.and(has_tags(tags)).and(has_name(name))
131
+ )
132
+ )
116
133
  subject.emit(name, tags: tags)
117
134
  end
118
135
  end
@@ -139,6 +156,27 @@ RSpec.describe Hallmonitor::Monitored do
139
156
  subject.emit(event)
140
157
  end
141
158
  end
159
+ end
142
160
 
161
+ context 'Instance' do
162
+ subject { Thing.new }
163
+ context '#watch' do
164
+ include_examples 'for watch'
165
+ end
166
+
167
+ context '#emit' do
168
+ include_examples 'for emit'
169
+ end
170
+ end
171
+
172
+ context 'Class' do
173
+ subject { Thing }
174
+ context '.watch' do
175
+ include_examples 'for watch'
176
+ end
177
+
178
+ context '.emit' do
179
+ include_examples 'for emit'
180
+ end
143
181
  end
144
182
  end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'hallmonitor/outputters/datadog'
3
+
4
+ module Hallmonitor
5
+ module Outputters
6
+ RSpec.describe Datadog do
7
+ let(:dogstatsd_client) { instance_double(::Datadog::Statsd) }
8
+ let(:outputter) { described_class.new(dogstatsd_client) }
9
+
10
+ it 'can be instantiated' do
11
+ expect { outputter }.to_not raise_error
12
+ end
13
+
14
+ context '#process' do
15
+ let(:event_name) { 'foo.bar.baz' }
16
+ let(:event_tags) { { foo: 'bar' } }
17
+ let(:event_tags_expected) { { tags: ['foo:bar'] } }
18
+
19
+ context 'with a timed event' do
20
+ let(:event) { TimedEvent.new(event_name, duration: 100, tags: event_tags) }
21
+
22
+ it 'sends the event to statsd' do
23
+ expect(dogstatsd_client).to(
24
+ receive(:timing)
25
+ .with(event_name, event.duration, event_tags_expected)
26
+ )
27
+ outputter.process(event)
28
+ end
29
+ end
30
+
31
+ context 'with an event' do
32
+ let(:event) { Event.new(event_name, tags: event_tags) }
33
+
34
+ it 'sends the event to statsd' do
35
+ expect(dogstatsd_client).to(
36
+ receive(:count)
37
+ .with(event_name, event.count, event_tags_expected)
38
+ )
39
+ outputter.process(event)
40
+ end
41
+
42
+ context 'that has multiple values' do
43
+ let(:values) { { foo: 1, bar: 2 } }
44
+ let(:event) do
45
+ Event.new(event_name, count: values, tags: event_tags)
46
+ end
47
+
48
+ it 'sends multiple events to statsd' do
49
+ expect(dogstatsd_client).to(
50
+ receive(:count)
51
+ .with(
52
+ "#{event_name}.foo",
53
+ event.count[:foo],
54
+ event_tags_expected
55
+ )
56
+ )
57
+ expect(dogstatsd_client).to(
58
+ receive(:count)
59
+ .with(
60
+ "#{event_name}.bar",
61
+ event.count[:bar],
62
+ event_tags_expected
63
+ )
64
+ )
65
+ outputter.process(event)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hallmonitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.0
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris TenHarmsel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-23 00:00:00.000000000 Z
11
+ date: 2018-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: statsd-ruby
28
+ name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '1.3'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '1.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: dogstatsd-ruby
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -67,21 +67,21 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.2.2
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec
70
+ name: pry-byebug
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '3.0'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '3.0'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rdoc
84
+ name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,35 +95,35 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: bundler
98
+ name: rdoc
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '1.3'
103
+ version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '1.3'
110
+ version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: pry-byebug
112
+ name: rspec
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: '3.0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
- version: '0'
124
+ version: '3.0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: rake
126
+ name: yard
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
@@ -137,7 +137,7 @@ dependencies:
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: yard
140
+ name: statsd-ruby
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - ">="
@@ -157,15 +157,8 @@ executables: []
157
157
  extensions: []
158
158
  extra_rdoc_files: []
159
159
  files:
160
- - ".document"
161
- - ".gitignore"
162
- - CHANGELOG.md
163
- - Gemfile
164
160
  - LICENSE.txt
165
161
  - README.md
166
- - Rakefile
167
- - bin/example.rb
168
- - hallmonitor.gemspec
169
162
  - lib/hallmonitor.rb
170
163
  - lib/hallmonitor/configuration.rb
171
164
  - lib/hallmonitor/dispatcher.rb
@@ -174,7 +167,7 @@ files:
174
167
  - lib/hallmonitor/middleware.rb
175
168
  - lib/hallmonitor/monitored.rb
176
169
  - lib/hallmonitor/outputter.rb
177
- - lib/hallmonitor/outputters/dogstatsd_outputter.rb
170
+ - lib/hallmonitor/outputters/datadog.rb
178
171
  - lib/hallmonitor/outputters/influxdb.rb
179
172
  - lib/hallmonitor/outputters/iooutputter.rb
180
173
  - lib/hallmonitor/outputters/new_relic.rb
@@ -183,7 +176,7 @@ files:
183
176
  - lib/hallmonitor/version.rb
184
177
  - spec/hallmonitor/dispatcher_spec.rb
185
178
  - spec/hallmonitor/monitored_spec.rb
186
- - spec/hallmonitor/outputters/dogstatsd_outputter_spec.rb
179
+ - spec/hallmonitor/outputters/datadog_spec.rb
187
180
  - spec/hallmonitor/outputters/influxdb_spec.rb
188
181
  - spec/hallmonitor/outputters/statsd_outputter_spec.rb
189
182
  - spec/spec_helper.rb
@@ -207,15 +200,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
200
  version: '0'
208
201
  requirements: []
209
202
  rubyforge_project:
210
- rubygems_version: 2.4.5.1
203
+ rubygems_version: 2.5.2
211
204
  signing_key:
212
205
  specification_version: 4
213
206
  summary: Simple Ruby Event Monitoring
214
207
  test_files:
215
- - spec/hallmonitor/dispatcher_spec.rb
208
+ - spec/spec_helper.rb
216
209
  - spec/hallmonitor/monitored_spec.rb
217
- - spec/hallmonitor/outputters/dogstatsd_outputter_spec.rb
210
+ - spec/hallmonitor/outputters/datadog_spec.rb
218
211
  - spec/hallmonitor/outputters/influxdb_spec.rb
219
212
  - spec/hallmonitor/outputters/statsd_outputter_spec.rb
220
- - spec/spec_helper.rb
221
- has_rdoc:
213
+ - spec/hallmonitor/dispatcher_spec.rb
data/.document DELETED
@@ -1,5 +0,0 @@
1
- lib/**/*.rb
2
- bin/*
3
- -
4
- features/**/*.feature
5
- LICENSE.txt
data/.gitignore DELETED
@@ -1,50 +0,0 @@
1
- # rcov generated
2
- coverage
3
- coverage.data
4
-
5
- # rdoc generated
6
- rdoc
7
-
8
- # yard generated
9
- doc
10
- .yardoc
11
-
12
- # bundler
13
- .bundle
14
-
15
- # jeweler generated
16
- pkg
17
-
18
- # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
19
- #
20
- # * Create a file at ~/.gitignore
21
- # * Include files you want ignored
22
- # * Run: git config --global core.excludesfile ~/.gitignore
23
- #
24
- # After doing this, these files will be ignored in all your git projects,
25
- # saving you from having to 'pollute' every project you touch with them
26
- #
27
- # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
28
- #
29
- # For MacOS:
30
- #
31
- #.DS_Store
32
-
33
- # For TextMate
34
- #*.tmproj
35
- #tmtags
36
-
37
- # For emacs:
38
- #*~
39
- #\#*
40
- #.\#*
41
-
42
- # For vim:
43
- #*.swp
44
-
45
- # For redcar:
46
- #.redcar
47
-
48
- # For rubinius:
49
- #*.rbc
50
- Gemfile.lock
@@ -1,17 +0,0 @@
1
- # Verison 4.2.0
2
- - Added Dogstatsd outputter, thanks to mlahaye
3
-
4
- # Version 4.0.0
5
- - Changed initializer signature for InfluxDB outputter to use
6
- keyword args.
7
- - Added `attr_accessor` for InfluxDB Outputter's transformer
8
-
9
- # Version 3.0.0
10
- - Refactored the Transformer concept in the InfluxDB outputter so that
11
- it is more flexible. This was in response to the InfluxDB client gem
12
- "fixing" a bug where numerical values were previously always sent as
13
- floats, now numbers are marked as "integer" type if they are ruby
14
- Integers which can lead to some field-type conflicts if you update
15
- your InfluxDB gem version and were previously sending integers at
16
- floats. Using the Transformer now allows you to modify the values
17
- that will be sent to InfluxDB immediately before they're sent out.x
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gemspec
data/Rakefile DELETED
@@ -1,16 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'rubygems'
4
- require 'bundler/gem_tasks'
5
-
6
- require 'rspec/core/rake_task'
7
- RSpec::Core::RakeTask.new(:spec)
8
- task :default => :spec
9
-
10
- require 'rdoc/task'
11
- Rake::RDocTask.new do |rdoc|
12
- rdoc.rdoc_dir = 'rdoc'
13
- rdoc.title = "hallmonitor #{Hallmonitor::Version::STRING}"
14
- rdoc.rdoc_files.include('README*')
15
- rdoc.rdoc_files.include('lib/**/*.rb')
16
- end
@@ -1,49 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- lib = File.expand_path('../../lib', __FILE__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
-
6
- require 'hallmonitor'
7
- require 'hallmonitor/outputters/iooutputter'
8
- require 'hallmonitor/outputters/statsd_outputter'
9
- require 'pry'
10
-
11
- Hallmonitor.add_outputter Hallmonitor::Outputters::IOOutputter.new("STDOUT", STDOUT)
12
- Hallmonitor.add_outputter Hallmonitor::Outputters::StatsdOutputter.new("example", "localhost")
13
-
14
- class Foo
15
- include Hallmonitor::Monitored
16
-
17
- def do_something
18
- sleep_time_ms = ((Random.rand * 100).floor) * 2
19
- puts "Sleeping for #{sleep_time_ms} milliseconds"
20
- sleep(sleep_time_ms / 1000.0)
21
- end
22
- timer_for :do_something
23
- count_for :do_something
24
-
25
- def emit_events(count=30)
26
- # Emit 100 events
27
- count.times do
28
- emit("event")
29
- sleep(1)
30
- end
31
- end
32
-
33
- def time_me
34
- watch("timed") do |x|
35
- sleep(5)
36
- end
37
- end
38
- end
39
-
40
- f = Foo.new
41
-
42
- puts 'Calling method with timer_for and count_for...'
43
- f.do_something
44
-
45
- puts 'Emitting some events'
46
- f.emit_events(5)
47
-
48
- puts 'Timing a 5 second block'
49
- f.time_me
@@ -1,31 +0,0 @@
1
- lib = File.expand_path('../lib', __FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'hallmonitor/version'
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "hallmonitor"
7
- s.version = Hallmonitor::Version::STRING
8
-
9
- s.authors = ["Chris TenHarmsel"]
10
- s.summary = "Simple Ruby Event Monitoring"
11
- s.description = "Hallmonitor is a simple event monitoring framework in Ruby"
12
- s.email = ["chris@tenharmsel.com"]
13
- s.homepage = "http://github.com/epchris/hallmonitor"
14
- s.licenses = ["MIT"]
15
-
16
- s.files = `git ls-files`.split($/)
17
- s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
- s.require_paths = ["lib"]
19
-
20
- s.add_runtime_dependency("json", [">= 0"])
21
-
22
- s.add_development_dependency("statsd-ruby", [">= 0"])
23
- s.add_development_dependency("dogstatsd-ruby", [">= 0"])
24
- s.add_development_dependency("influxdb", ["~> 0.2.2"])
25
- s.add_development_dependency("rspec", [">= 3.0"])
26
- s.add_development_dependency("rdoc", [">= 0"])
27
- s.add_development_dependency("bundler", ["~> 1.3"])
28
- s.add_development_dependency("pry-byebug", [">= 0"])
29
- s.add_development_dependency("rake", [">= 0"])
30
- s.add_development_dependency("yard", [">= 0"])
31
- end
@@ -1,85 +0,0 @@
1
- begin
2
- require 'datadog/statsd'
3
- rescue LoadError
4
- end
5
-
6
- module Hallmonitor
7
- module Outputters
8
- # An outputter for Dogstatsd
9
- class DogstatsdOutputter < Outputter
10
- # Builds a new DogstatsdOutputter.
11
- # @param prefix [String] Prefix for all events output by this outputter,
12
- # the prefix will be applied to all event names before sending to statsd
13
- # @param host [String] Datadog Host, defaults to '127.0.0.1'
14
- # @param port [Number] Datadog Port, defaults to 8125
15
- # @raise if Datadog::Statsd is undefined (Gem not present)
16
- def initialize(prefix, host = '127.0.0.1', port = 8125, tags: {})
17
- unless defined?(Datadog::Statsd)
18
- fail 'In order to use DogstatsdOutputter, dogstatsd-ruby gem must be installed'
19
- end
20
-
21
- super(prefix)
22
- @tags = {}.merge(tags)
23
- @statsd = Datadog::Statsd.new(host).tap { |sd| sd.namespace = name }
24
- end
25
-
26
- # Sends events to statsd instance
27
- # If the event's value field is a hash, this will send multiple events
28
- # to statsd with the original name suffixed by the name of the events
29
- # in the hash
30
-
31
- def process_tags(tags)
32
- @tags.merge(tags).map {|key, value| "#{key}:#{value}"}
33
- end
34
-
35
- def process(event)
36
- if event.is_a?(Hallmonitor::TimedEvent)
37
- process_timed_event(event)
38
- elsif event.is_a?(Hallmonitor::GaugeEvent)
39
- process_gauge_event(event)
40
- else
41
- process_event(event)
42
- end
43
- end
44
-
45
- private
46
-
47
- def process_timed_event(event)
48
- event_name = name_for(event)
49
- if event.duration.is_a?(Hash)
50
- event.duration.each do |name, value|
51
- @statsd.timing("#{event_name}.#{name}", value, tags: process_tags(event.tags))
52
- end
53
- else
54
- @statsd.timing(event_name, event.duration, tags: process_tags(event.tags))
55
- end
56
- end
57
-
58
- def process_gauge_event(event)
59
- event_name = name_for(event)
60
- if event.value.is_a?(Hash)
61
- event.value.each do |name, value|
62
- @statsd.gauge("#{event_name}.#{name}", value, tags: process_tags(event.tags))
63
- end
64
- else
65
- @statsd.gauge(event_name, event.value, tags: process_tags(event.tags))
66
- end
67
- end
68
-
69
- def process_event(event)
70
- event_name = name_for(event)
71
- if event.count.is_a?(Hash)
72
- event.count.each do |name, value|
73
- @statsd.count("#{event_name}.#{name}", value, tags: process_tags(event.tags))
74
- end
75
- else
76
- @statsd.count(event_name, event.count, tags: process_tags(event.tags))
77
- end
78
- end
79
-
80
- def name_for(event)
81
- event.name
82
- end
83
- end
84
- end
85
- end
@@ -1,45 +0,0 @@
1
- require 'spec_helper'
2
- require 'hallmonitor/outputters/dogstatsd_outputter'
3
-
4
- module Hallmonitor
5
- module Outputters
6
- RSpec.describe DogstatsdOutputter do
7
- let(:dogstatsd_client) { instance_double(Datadog::Statsd) }
8
- let(:prefix) { 'test' }
9
- let(:outputter) { described_class.new(prefix) }
10
-
11
- before do
12
- allow(dogstatsd_client).to receive(:namespace=)
13
- allow(Datadog::Statsd).to receive(:new).and_return(dogstatsd_client)
14
- end
15
-
16
- it 'can be instantiated' do
17
- expect { outputter }.to_not raise_error
18
- end
19
-
20
- context '#process' do
21
- let(:event_name) { 'foo.bar.baz' }
22
- let(:event_tags) { {foo:"bar"} }
23
- let(:event_tags_expected) {{tags:["foo:bar"]}}
24
- context 'with an event' do
25
- let(:event) { Event.new(name = event_name, tags: event_tags) }
26
-
27
- it 'sends the event to statsd' do
28
- expect(dogstatsd_client).to receive(:count).with(event_name, event.count, event_tags_expected)
29
- outputter.process(event)
30
- end
31
-
32
- context 'that has multiple values' do
33
- let(:values) { { foo: 1, bar: 2 } }
34
- let(:event) { Event.new(event_name, count: values, tags: event_tags) }
35
- it 'sends multiple events to statsd' do
36
- expect(dogstatsd_client).to receive(:count).with("#{event_name}.foo", event.count[:foo], event_tags_expected)
37
- expect(dogstatsd_client).to receive(:count).with("#{event_name}.bar", event.count[:bar], event_tags_expected)
38
- outputter.process(event)
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
45
- end