hallmonitor 4.2.0 → 5.0.0

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: 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