harness 0.3.0 → 0.4.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.
- data/.gitignore +1 -0
- data/README.md +80 -19
- data/harness.gemspec +4 -0
- data/lib/harness.rb +6 -9
- data/lib/harness/adapters/librato_adapter.rb +8 -4
- data/lib/harness/adapters/memory_adapter.rb +10 -2
- data/lib/harness/adapters/null_adapter.rb +2 -2
- data/lib/harness/adapters/stathat_adapter.rb +75 -0
- data/lib/harness/adapters/statsd_adapter.rb +50 -0
- data/lib/harness/gauge.rb +1 -1
- data/lib/harness/queues/delayed_job_queue.rb +7 -0
- data/lib/harness/queues/resque_queue.rb +1 -1
- data/lib/harness/queues/sidekiq_queue.rb +1 -1
- data/lib/harness/queues/{syncronous_queue.rb → synchronous_queue.rb} +7 -2
- data/lib/harness/railtie.rb +12 -12
- data/lib/harness/version.rb +1 -1
- data/test/integration/integrations/active_support_test.rb +1 -0
- data/test/integration/queues/delayed_job_test.rb +59 -0
- data/test/integration/railtie_test.rb +4 -0
- data/test/test_helper.rb +4 -2
- data/test/unit/adapters/librato_adapter_test.rb +2 -2
- data/test/unit/adapters/memory_adapter_test.rb +1 -1
- data/test/unit/adapters/stathat_adapter_test.rb +143 -0
- data/test/unit/adapters/statsd_adapter_test.rb +73 -0
- data/test/unit/gauge_test.rb +10 -0
- data/test/unit/harness_test.rb +9 -9
- metadata +146 -24
- data/test/unit/meter_test.rb +0 -0
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -7,6 +7,8 @@ redis before being sent to the service.
|
|
7
7
|
Currently Supported Services:
|
8
8
|
|
9
9
|
* Librato
|
10
|
+
* Statsd (thanks to fluxlux)
|
11
|
+
* Stathat
|
10
12
|
|
11
13
|
Current Features:
|
12
14
|
|
@@ -45,20 +47,26 @@ end
|
|
45
47
|
|
46
48
|
Add this line to your application's Gemfile:
|
47
49
|
|
48
|
-
|
50
|
+
```
|
51
|
+
gem 'harness'
|
52
|
+
```
|
49
53
|
|
50
54
|
And then execute:
|
51
55
|
|
52
|
-
|
56
|
+
```
|
57
|
+
$ bundle
|
58
|
+
```
|
53
59
|
|
54
60
|
Or install it yourself as:
|
55
61
|
|
56
|
-
|
62
|
+
```
|
63
|
+
$ gem install harness
|
64
|
+
```
|
57
65
|
|
58
66
|
## Usage
|
59
67
|
|
60
68
|
In the metrics world there are two types of things: Gauges and Counters.
|
61
|
-
Gauges are time
|
69
|
+
Gauges are time sensitive and represent something at a specific point in
|
62
70
|
time. Counters keep track of things and should be increasing. Counters
|
63
71
|
can be reset back to zero. You can combine counters and/or gauges to
|
64
72
|
correlate data about your application. Meters monitor counters. They
|
@@ -94,7 +102,14 @@ stored in redis and incremented. This means you can simply pass
|
|
94
102
|
may also pass `:counter => 5` if you'd like to provide your own value.
|
95
103
|
This value is stored in redis so the next time `:counter => true` will
|
96
104
|
work correctly. You can reset all the counters back to zero by calling:
|
97
|
-
`Harness.reset_counters!`.
|
105
|
+
`Harness.reset_counters!`.
|
106
|
+
|
107
|
+
**NOTE**: You should use the bundled rake task to reset counters with
|
108
|
+
a cron job. This will prevent unbounded growth of this metadata. You
|
109
|
+
can call `rake harness:reset_counters` to do this. You should call
|
110
|
+
this rake task at whatever your longest measurable interval is. Here's
|
111
|
+
an example: You log gauges every 12 hours. You should reset the
|
112
|
+
counters every 12 hours. This issue is discussed [here](https://github.com/twinturbo/harness/issues/15).
|
98
113
|
|
99
114
|
```ruby
|
100
115
|
class MyClass
|
@@ -106,14 +121,25 @@ class MyClass
|
|
106
121
|
end
|
107
122
|
```
|
108
123
|
|
109
|
-
The
|
124
|
+
The instruments name will be sent as the name (`important_method.my_class`)
|
110
125
|
for that gauge or counter.
|
111
126
|
|
127
|
+
Note that `ActiveSupport::Notifications.instrument` doesn't require
|
128
|
+
a block. This can be useful when you are taking an instant measurement.
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
class MyClass
|
132
|
+
def important_method(stuff)
|
133
|
+
ActiveSupport::Notifications.instrument "important_method.my_class", :counter => true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
112
138
|
Harness will do all the extra work in sending these metrics to whatever
|
113
139
|
service you're using.
|
114
140
|
|
115
141
|
Once you the counters are you are instrumented, then you can meter them.
|
116
|
-
Meters allow you take
|
142
|
+
Meters allow you take arbitrary readings of counter rates. The results
|
117
143
|
return a gauge so they can be logged as well.
|
118
144
|
|
119
145
|
```ruby
|
@@ -137,13 +163,18 @@ meter.per_hour
|
|
137
163
|
|
138
164
|
## Customizing
|
139
165
|
|
140
|
-
You can
|
166
|
+
You can pass a hash to `:counter` or `:gauge` to initialize the
|
141
167
|
measurement your own way.
|
142
168
|
|
169
|
+
If you pass a value attribute to a gauge, it will be the value
|
170
|
+
sent instead of the duration of the block.
|
171
|
+
|
143
172
|
```ruby
|
144
173
|
class MyClass
|
145
174
|
def important_method(stuff)
|
146
|
-
ActiveSupport::Notifications.instrument "important_method.my_class",
|
175
|
+
ActiveSupport::Notifications.instrument "important_method.my_class",
|
176
|
+
:gauge => { :id => 'custom-id', :name => "My Measurement",
|
177
|
+
:value => my_current_val, :units => 'cogs' } do
|
147
178
|
do_important_stuff
|
148
179
|
end
|
149
180
|
end
|
@@ -152,10 +183,10 @@ end
|
|
152
183
|
|
153
184
|
## One Off Gauges and Counters
|
154
185
|
|
155
|
-
You can instantiate `Harness::Counter` and `Harness::
|
186
|
+
You can instantiate `Harness::Counter` and `Harness::Gauge` wherever you
|
156
187
|
want. Events from `ActiveSupport` are just converted to these classes
|
157
188
|
under the covers anyways. You can use these class if you want to take
|
158
|
-
|
189
|
+
periodic measurements or tracking something that happens outside the
|
159
190
|
application.
|
160
191
|
|
161
192
|
```ruby
|
@@ -174,21 +205,51 @@ counter.time # defaults to Time.now
|
|
174
205
|
counter.value = read_total_users_in_database
|
175
206
|
counter.log
|
176
207
|
|
177
|
-
|
208
|
+
### Both classes take an option hash
|
178
209
|
|
179
|
-
gauge = Harness::
|
210
|
+
gauge = Harness::Gauge.new :time => Time.now, :id => 'foo.bar'
|
180
211
|
counter = Harness::Counter.new :time => Time.now, :id => 'foo.bar'
|
181
212
|
```
|
182
213
|
|
183
214
|
## Configuration
|
184
215
|
|
216
|
+
### Librato
|
185
217
|
```ruby
|
186
218
|
Harness.config.adapter = :librato
|
187
219
|
|
188
220
|
Harness.config.librato.email = 'example@example.com'
|
189
221
|
Harness.config.librato.token = 'your-api-key'
|
190
222
|
|
191
|
-
|
223
|
+
```
|
224
|
+
|
225
|
+
### StatsD
|
226
|
+
|
227
|
+
Harness does **not** configure StatsD for you. It uses the StatsD class
|
228
|
+
under the covers. If you've already configured that in your own way, great.
|
229
|
+
If not, you can use the configuration proxy as described below. You
|
230
|
+
must also add `statsd-instrument` to your `Gemfile`. This is a soft
|
231
|
+
dependency that is not installed for you.
|
232
|
+
|
233
|
+
```ruby
|
234
|
+
Harness.config.adapter = :statsd
|
235
|
+
|
236
|
+
# Harness.config.statsd is a proxy for the StatsD class
|
237
|
+
Harness.config.statsd.host = 'localhost'
|
238
|
+
Harness.config.statsd.port = '8080'
|
239
|
+
Harness.config.statsd.default_sample_rate = 0.1
|
240
|
+
Harness.config.statsd.logger = Rails.logger
|
241
|
+
|
242
|
+
# You can assign your own StatsD implementation
|
243
|
+
# by setting the "backend" attribute
|
244
|
+
Harness.config.statsd.backend = CustomStatsD
|
245
|
+
```
|
246
|
+
|
247
|
+
### Stathat
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
Harness.config.adapter = :stathat
|
251
|
+
|
252
|
+
Harness.config.stathat.ezkey = 'example@example.com'
|
192
253
|
```
|
193
254
|
|
194
255
|
## Rails Integration
|
@@ -209,8 +270,8 @@ You can configure Harness from `application.rb`
|
|
209
270
|
|
210
271
|
```ruby
|
211
272
|
config.harness.adapter = :librato
|
212
|
-
config.librato.email = 'example@example.com'
|
213
|
-
config.librato.token = 'your-api-key'
|
273
|
+
config.harness.librato.email = 'example@example.com'
|
274
|
+
config.harness.librato.token = 'your-api-key'
|
214
275
|
```
|
215
276
|
|
216
277
|
Redis will be automatically configured if you `REDISTOGO_URL` or
|
@@ -225,7 +286,7 @@ require 'erb'
|
|
225
286
|
file = Rails.root.join 'config', 'resque.yml'
|
226
287
|
config = YAML.load(ERB.new(File.read(Rails.root.join('config', 'redis.yml'))).result)
|
227
288
|
|
228
|
-
Harness.redis = Redis.new(:url => config[Rails.env])
|
289
|
+
Harness.redis = Redis::Namespace.new('harness', :redis => Redis.connect(:url => config[Rails.env]))
|
229
290
|
```
|
230
291
|
|
231
292
|
`rake harness:reset_counters` is also added.
|
@@ -239,10 +300,10 @@ logged in production.
|
|
239
300
|
### Background Processing
|
240
301
|
|
241
302
|
Harness integrates automatically with Resque or Sidekiq. This is because
|
242
|
-
reporting measurements can take time and add
|
303
|
+
reporting measurements can take time and add unnecessary overhead to the
|
243
304
|
response time. If neither of these libraries are present, measurements
|
244
305
|
**will be posted in realtime.** You can set your own queue by
|
245
|
-
|
306
|
+
specifying a class like so:
|
246
307
|
|
247
308
|
```ruby
|
248
309
|
Harness.config.queue = MyCustomQueue
|
data/harness.gemspec
CHANGED
@@ -23,6 +23,10 @@ Gem::Specification.new do |gem|
|
|
23
23
|
gem.add_development_dependency "webmock"
|
24
24
|
gem.add_development_dependency "resque"
|
25
25
|
gem.add_development_dependency "sidekiq"
|
26
|
+
gem.add_development_dependency "delayed_job_active_record"
|
26
27
|
gem.add_development_dependency "active_model_serializers"
|
27
28
|
gem.add_development_dependency "rails"
|
29
|
+
gem.add_development_dependency "sqlite3"
|
30
|
+
gem.add_development_dependency "minitest"
|
31
|
+
gem.add_development_dependency "statsd-instrument"
|
28
32
|
end
|
data/lib/harness.rb
CHANGED
@@ -26,7 +26,7 @@ module Harness
|
|
26
26
|
|
27
27
|
def adapter=(val)
|
28
28
|
if val.is_a? Symbol
|
29
|
-
@adapter = "Harness::#{val.to_s.camelize}Adapter".constantize
|
29
|
+
@adapter = "Harness::#{val.to_s.camelize}Adapter".constantize.new
|
30
30
|
else
|
31
31
|
@adapter = val
|
32
32
|
end
|
@@ -34,9 +34,9 @@ module Harness
|
|
34
34
|
|
35
35
|
def queue=(val)
|
36
36
|
if val.is_a? Symbol
|
37
|
-
@queue= "Harness::#{val.to_s.camelize}Queue".constantize
|
37
|
+
@queue = "Harness::#{val.to_s.camelize}Queue".constantize.new
|
38
38
|
else
|
39
|
-
@queue= val
|
39
|
+
@queue = val
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -90,16 +90,13 @@ require 'harness/instrumentation'
|
|
90
90
|
|
91
91
|
require 'harness/job'
|
92
92
|
|
93
|
-
require 'harness/queues/
|
93
|
+
require 'harness/queues/synchronous_queue'
|
94
94
|
|
95
95
|
require 'harness/adapters/librato_adapter'
|
96
96
|
require 'harness/adapters/memory_adapter'
|
97
97
|
require 'harness/adapters/null_adapter'
|
98
|
-
|
99
|
-
require 'harness/
|
100
|
-
require 'harness/integration/action_view'
|
101
|
-
require 'harness/integration/action_mailer'
|
102
|
-
require 'harness/integration/active_support'
|
98
|
+
require 'harness/adapters/statsd_adapter'
|
99
|
+
require 'harness/adapters/stathat_adapter'
|
103
100
|
|
104
101
|
require 'harness/railtie' if defined?(Rails)
|
105
102
|
|
@@ -12,7 +12,7 @@ module Harness
|
|
12
12
|
@config ||= Config.new
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def log_gauge(gauge)
|
16
16
|
raise Harness::LoggingError if gauge.id.length > 63
|
17
17
|
|
18
18
|
post({:gauges => [{
|
@@ -25,7 +25,7 @@ module Harness
|
|
25
25
|
}]})
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
28
|
+
def log_counter(counter)
|
29
29
|
raise Harness::LoggingError if counter.id.length > 63
|
30
30
|
|
31
31
|
post({:counters => [{
|
@@ -39,7 +39,7 @@ module Harness
|
|
39
39
|
end
|
40
40
|
|
41
41
|
private
|
42
|
-
def
|
42
|
+
def post(params)
|
43
43
|
unless config.email && config.token
|
44
44
|
raise "Adapter not configured. Ensure email and token are set."
|
45
45
|
end
|
@@ -68,7 +68,11 @@ module Harness
|
|
68
68
|
true
|
69
69
|
end
|
70
70
|
|
71
|
-
def
|
71
|
+
def config
|
72
|
+
self.class.config
|
73
|
+
end
|
74
|
+
|
75
|
+
def sanitize(name)
|
72
76
|
if Harness.config.namespace
|
73
77
|
key = "#{name}.#{Harness.config.namespace}"
|
74
78
|
else
|
@@ -8,12 +8,20 @@ module Harness
|
|
8
8
|
@counters ||= []
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
11
|
+
def log_gauge(gauge)
|
12
12
|
gauges << gauge
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def log_counter(counter)
|
16
16
|
counters << counter
|
17
17
|
end
|
18
|
+
|
19
|
+
def counters
|
20
|
+
self.class.counters
|
21
|
+
end
|
22
|
+
|
23
|
+
def gauges
|
24
|
+
self.class.gauges
|
25
|
+
end
|
18
26
|
end
|
19
27
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module Harness
|
5
|
+
class StathatAdapter
|
6
|
+
class Config
|
7
|
+
attr_accessor :ezkey
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.config
|
11
|
+
@config ||= Config.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def log_gauge(gauge)
|
15
|
+
raise Harness::LoggingError if gauge.id.length > 255
|
16
|
+
|
17
|
+
post({
|
18
|
+
:stat => sanitize(gauge.id),
|
19
|
+
:value => gauge.value,
|
20
|
+
})
|
21
|
+
end
|
22
|
+
|
23
|
+
def log_counter(counter)
|
24
|
+
raise Harness::LoggingError if counter.id.length > 255
|
25
|
+
|
26
|
+
post({
|
27
|
+
:stat => sanitize(counter.id),
|
28
|
+
:count => counter.value,
|
29
|
+
})
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def post(params)
|
35
|
+
unless config.ezkey
|
36
|
+
raise "Adapter not configured. Ensure ezkey is set."
|
37
|
+
end
|
38
|
+
|
39
|
+
uri = URI.parse('https://api.stathat.com/ez')
|
40
|
+
|
41
|
+
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
|
42
|
+
request = Net::HTTP::Post.new uri.request_uri
|
43
|
+
|
44
|
+
request.set_form_data params.merge(:ezkey => config.ezkey)
|
45
|
+
|
46
|
+
response = http.request request
|
47
|
+
|
48
|
+
unless response.code.to_i == 200
|
49
|
+
text = %Q{
|
50
|
+
Server Said: #{response.body}
|
51
|
+
Sent: #{params.inspect}
|
52
|
+
}
|
53
|
+
|
54
|
+
raise Harness::LoggingError, text
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
def config
|
62
|
+
self.class.config
|
63
|
+
end
|
64
|
+
|
65
|
+
def sanitize(name)
|
66
|
+
if Harness.config.namespace
|
67
|
+
key = "#{name}.#{Harness.config.namespace}"
|
68
|
+
else
|
69
|
+
key = name
|
70
|
+
end
|
71
|
+
|
72
|
+
key.gsub('/', '.')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'statsd-instrument'
|
2
|
+
|
3
|
+
module Harness
|
4
|
+
class StatsdAdapter
|
5
|
+
class Config
|
6
|
+
delegate :host, :port, :default_sample_rate, :mode, :logger, :to => :backend
|
7
|
+
delegate :host=, :port=, :default_sample_rate=, :mode=, :logger=, :to => :backend
|
8
|
+
|
9
|
+
def backend=(value)
|
10
|
+
@backend = value
|
11
|
+
end
|
12
|
+
|
13
|
+
def backend
|
14
|
+
@backend ||= StatsD
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.config
|
19
|
+
@config ||= Config.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def log_gauge(gauge)
|
23
|
+
validate!
|
24
|
+
backend.gauge sanitize(gauge.id), gauge.value
|
25
|
+
end
|
26
|
+
|
27
|
+
def log_counter(counter)
|
28
|
+
validate!
|
29
|
+
backend.increment sanitize(counter.id), counter.value
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def validate!
|
34
|
+
raise "Adapter not configured. Ensure host and port are set." unless config.host and config.port
|
35
|
+
end
|
36
|
+
|
37
|
+
def sanitize(name)
|
38
|
+
key = Harness.config.namespace ? "#{Harness.config.namespace}.#{name}" : name
|
39
|
+
key.gsub(%r{[^a-z0-9]}, '.')
|
40
|
+
end
|
41
|
+
|
42
|
+
def backend
|
43
|
+
config.backend
|
44
|
+
end
|
45
|
+
|
46
|
+
def config
|
47
|
+
self.class.config
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/harness/gauge.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Harness
|
2
|
-
class
|
3
|
-
def
|
2
|
+
class SynchronousQueue
|
3
|
+
def push(measurement)
|
4
4
|
begin
|
5
5
|
Harness::Job.new.log(measurement)
|
6
6
|
rescue LoggingError => ex
|
@@ -9,5 +9,10 @@ module Harness
|
|
9
9
|
logger.warn "[Harness] Could not post measurement! Enable debug logging to see full errors"
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def logger
|
15
|
+
Harness.logger
|
16
|
+
end
|
12
17
|
end
|
13
18
|
end
|
data/lib/harness/railtie.rb
CHANGED
@@ -12,29 +12,26 @@ module Harness
|
|
12
12
|
# Custom instrumentation can be turned on as follows
|
13
13
|
# See files in lib/harness/integration for available integrations
|
14
14
|
#
|
15
|
-
# config.harness.
|
16
|
-
# config.harness.
|
15
|
+
# config.harness.instrument.sidekiq = true
|
16
|
+
# config.harness.instrument.active_model_serializers = true
|
17
17
|
|
18
18
|
rake_tasks do
|
19
19
|
load "harness/tasks.rake"
|
20
20
|
end
|
21
21
|
|
22
22
|
initializer "harness.adapter" do |app|
|
23
|
-
case Rails.env
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
else
|
29
|
-
app.config.harness.adapter = :librato
|
30
|
-
end
|
23
|
+
app.config.harness.adapter ||= case Rails.env
|
24
|
+
when 'development' then :null
|
25
|
+
when 'test' then :null
|
26
|
+
else :librato
|
27
|
+
end
|
31
28
|
end
|
32
29
|
|
33
30
|
initializer "harness.logger" do |app|
|
34
31
|
Harness.logger = Rails.logger
|
35
32
|
end
|
36
33
|
|
37
|
-
initializer "harness.redis" do
|
34
|
+
initializer "harness.redis" do
|
38
35
|
if existing_url = ENV['REDISTOGO_URL'] || ENV['REDIS_URL']
|
39
36
|
Harness.redis ||= Redis::Namespace.new('harness', :redis => Redis.connect(:url => existing_url))
|
40
37
|
else
|
@@ -43,7 +40,7 @@ module Harness
|
|
43
40
|
end
|
44
41
|
|
45
42
|
initializer "harness.queue" do
|
46
|
-
Harness.config.queue =
|
43
|
+
Harness.config.queue = :synchronous
|
47
44
|
end
|
48
45
|
|
49
46
|
initializer "harness.queue.production" do |app|
|
@@ -55,6 +52,9 @@ module Harness
|
|
55
52
|
elsif defined?(Sidekiq::Worker) && use_real_queue
|
56
53
|
require 'harness/queues/sidekiq_queue'
|
57
54
|
Harness.config.queue = :sidekiq
|
55
|
+
elsif defined?(Delayed::Worker) && use_real_queue
|
56
|
+
require 'harness/queues/delayed_job_queue'
|
57
|
+
Harness.config.queue = :delayed_job
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
data/lib/harness/version.rb
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'harness/queues/delayed_job_queue'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
class DelayedJobTest < IntegrationTest
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
|
9
|
+
tmp = File.expand_path('../../../tmp', __FILE__)
|
10
|
+
db = File.join(tmp, 'db.sqlite3')
|
11
|
+
|
12
|
+
FileUtils.mkdir_p tmp
|
13
|
+
FileUtils.rm_f db
|
14
|
+
|
15
|
+
ActiveRecord::Base.establish_connection(
|
16
|
+
:adapter => "sqlite3",
|
17
|
+
:database => db
|
18
|
+
)
|
19
|
+
|
20
|
+
Class.new(ActiveRecord::Migration) do
|
21
|
+
def self.up
|
22
|
+
suppress_messages do
|
23
|
+
create_table :delayed_jobs, :force => true do |table|
|
24
|
+
table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
|
25
|
+
table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
|
26
|
+
table.text :handler # YAML-encoded string of the object that will do work
|
27
|
+
table.text :last_error # reason for last failure (See Note below)
|
28
|
+
table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
|
29
|
+
table.datetime :locked_at # Set when a client is working on this object
|
30
|
+
table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
|
31
|
+
table.string :locked_by # Who is working on this object (if locked)
|
32
|
+
table.string :queue # The name of the queue this job is in
|
33
|
+
table.timestamps
|
34
|
+
end
|
35
|
+
|
36
|
+
add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end.up
|
40
|
+
|
41
|
+
Delayed::Worker.delay_jobs = false
|
42
|
+
|
43
|
+
Harness.config.queue = :delayed_job
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_a_gauge_is_logged
|
47
|
+
instrument "test-gauge", :gauge => true
|
48
|
+
|
49
|
+
assert_gauge_logged "test-gauge"
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_a_counter_is_logged
|
53
|
+
instrument "test-counter", :counter => true
|
54
|
+
|
55
|
+
assert_counter_logged "test-counter"
|
56
|
+
|
57
|
+
assert_equal 1, counters.first.value
|
58
|
+
end
|
59
|
+
end
|
@@ -19,4 +19,8 @@ class RailtieTest < MiniTest::Unit::TestCase
|
|
19
19
|
assert app.config.harness.instrument.action_view
|
20
20
|
refute app.config.harness.instrument.active_support
|
21
21
|
end
|
22
|
+
|
23
|
+
def test_configures_queue
|
24
|
+
assert_kind_of Harness::SynchronousQueue, app.config.harness.queue
|
25
|
+
end
|
22
26
|
end
|
data/test/test_helper.rb
CHANGED
@@ -5,6 +5,8 @@ SimpleCov.start
|
|
5
5
|
|
6
6
|
require 'resque'
|
7
7
|
require 'sidekiq'
|
8
|
+
require 'delayed_job_active_record'
|
9
|
+
require 'sqlite3'
|
8
10
|
|
9
11
|
require 'harness'
|
10
12
|
|
@@ -23,7 +25,7 @@ Harness.redis = Redis::Namespace.new 'harness-test', :redis => Redis.connect(:ho
|
|
23
25
|
class IntegrationTest < MiniTest::Unit::TestCase
|
24
26
|
def setup
|
25
27
|
Harness.config.adapter = :memory
|
26
|
-
Harness.config.queue = :
|
28
|
+
Harness.config.queue = :synchronous
|
27
29
|
|
28
30
|
gauges.clear ; counters.clear
|
29
31
|
redis.flushall
|
@@ -58,7 +60,7 @@ class IntegrationTest < MiniTest::Unit::TestCase
|
|
58
60
|
end
|
59
61
|
|
60
62
|
def instrument(name, data = {})
|
61
|
-
ActiveSupport::Notifications.instrument name, data do
|
63
|
+
ActiveSupport::Notifications.instrument name, data do
|
62
64
|
# nothing
|
63
65
|
end
|
64
66
|
end
|
@@ -2,7 +2,7 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class LibratoAdapterTest < MiniTest::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
@adapter = Harness::LibratoAdapter
|
5
|
+
@adapter = Harness::LibratoAdapter.new
|
6
6
|
|
7
7
|
@gauge = Harness::Gauge.new
|
8
8
|
@gauge.id = "fake-gauge"
|
@@ -66,7 +66,7 @@ class LibratoAdapterTest < MiniTest::Unit::TestCase
|
|
66
66
|
assert_requested expected_request
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
69
|
+
def test_logging_gauge_raises_an_exception
|
70
70
|
stub_request(:post, %r{metrics}).to_return(:status => 500, :body => "message")
|
71
71
|
|
72
72
|
assert_raises Harness::LoggingError do
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class StathatAdapterTest < MiniTest::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@adapter = Harness::StathatAdapter.new
|
6
|
+
|
7
|
+
@gauge = Harness::Gauge.new
|
8
|
+
@gauge.id = "fake-gauge"
|
9
|
+
@gauge.name = "Fake Gauge"
|
10
|
+
@gauge.source = "minitest"
|
11
|
+
@gauge.time = Time.now
|
12
|
+
@gauge.value = "55"
|
13
|
+
|
14
|
+
@counter = Harness::Counter.new
|
15
|
+
@counter.id = "fake-counter"
|
16
|
+
@counter.name = "Fake Counter"
|
17
|
+
@counter.source = "minitest"
|
18
|
+
@counter.time = Time.now
|
19
|
+
@counter.value = "55"
|
20
|
+
@counter.units = :bytes
|
21
|
+
|
22
|
+
Harness::StathatAdapter.config.ezkey = token
|
23
|
+
Harness.config.namespace = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_gauge_is_logged
|
27
|
+
args = {
|
28
|
+
:stat => @gauge.id,
|
29
|
+
:ezkey => token,
|
30
|
+
:value => @gauge.value,
|
31
|
+
}
|
32
|
+
|
33
|
+
expected_request = stub_request(:post, "https://api.stathat.com/ez").
|
34
|
+
with(:body => args, :headers => {'Content-Type'=>'application/x-www-form-urlencoded'}).
|
35
|
+
to_return(:status => 200)
|
36
|
+
|
37
|
+
assert @adapter.log_gauge(@gauge)
|
38
|
+
assert_requested expected_request
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_gauge_is_logged_with_namespace
|
42
|
+
Harness.config.namespace = :foo
|
43
|
+
|
44
|
+
args = {
|
45
|
+
:stat => "#{@gauge.id}.foo",
|
46
|
+
:ezkey => token,
|
47
|
+
:value => @gauge.value,
|
48
|
+
}
|
49
|
+
|
50
|
+
expected_request = stub_request(:post, "https://api.stathat.com/ez").
|
51
|
+
with(:body => args, :headers => {'Content-Type'=>'application/x-www-form-urlencoded'}).
|
52
|
+
to_return(:status => 200)
|
53
|
+
|
54
|
+
assert @adapter.log_gauge(@gauge)
|
55
|
+
assert_requested expected_request
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_logging_gauge_raises_an_exception
|
59
|
+
stub_request(:post, %r{stathat}).to_return(:status => 500, :body => "message")
|
60
|
+
|
61
|
+
assert_raises Harness::LoggingError do
|
62
|
+
@adapter.log_gauge @gauge
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_logging_gauge_raises_an_exception_when_id_is_too_long
|
67
|
+
@gauge.id = "f" * 256
|
68
|
+
|
69
|
+
assert_raises Harness::LoggingError do
|
70
|
+
@adapter.log_gauge @gauge
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_logging_gauge_raises_an_exception_when_not_configured
|
75
|
+
Harness::StathatAdapter.config.ezkey = nil
|
76
|
+
|
77
|
+
assert_raises RuntimeError do
|
78
|
+
@adapter.log_gauge @gauge
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_counter_is_logged
|
83
|
+
args = {
|
84
|
+
:stat => @counter.id,
|
85
|
+
:ezkey => token,
|
86
|
+
:count => @counter.value,
|
87
|
+
}
|
88
|
+
|
89
|
+
expected_request = stub_request(:post, "https://api.stathat.com/ez").
|
90
|
+
with(:body => args, :headers => {'Content-Type'=>'application/x-www-form-urlencoded'}).
|
91
|
+
to_return(:status => 200)
|
92
|
+
|
93
|
+
assert @adapter.log_counter(@counter)
|
94
|
+
assert_requested expected_request
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_counter_is_logged_with_namespace
|
98
|
+
Harness.config.namespace = :foo
|
99
|
+
|
100
|
+
args = {
|
101
|
+
:stat => "#{@counter.id}.foo",
|
102
|
+
:ezkey => token,
|
103
|
+
:count => @counter.value,
|
104
|
+
}
|
105
|
+
|
106
|
+
expected_request = stub_request(:post, "https://api.stathat.com/ez").
|
107
|
+
with(:body => args, :headers => {'Content-Type'=>'application/x-www-form-urlencoded'}).
|
108
|
+
to_return(:status => 200)
|
109
|
+
|
110
|
+
assert @adapter.log_counter(@counter)
|
111
|
+
assert_requested expected_request
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_logging_counter_raises_an_exception
|
115
|
+
stub_request(:post, %r{stathat}).to_return(:status => 500, :body => "message")
|
116
|
+
|
117
|
+
assert_raises Harness::LoggingError do
|
118
|
+
@adapter.log_counter @counter
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_logging_counter_raises_an_exception_when_not_configured
|
123
|
+
Harness::StathatAdapter.config.ezkey = nil
|
124
|
+
|
125
|
+
assert_raises RuntimeError do
|
126
|
+
@adapter.log_counter @counter
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_logging_counter_raises_an_exception_when_id_is_too_long
|
131
|
+
@counter.id = "f" * 256
|
132
|
+
|
133
|
+
assert_raises Harness::LoggingError do
|
134
|
+
@adapter.log_counter @counter
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
def token
|
141
|
+
'example@example.com'
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
class StatsdAdapterTest < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@adapter = Harness::StatsdAdapter.new
|
7
|
+
|
8
|
+
@gauge = Harness::Gauge.new
|
9
|
+
@gauge.id = "fake-gauge"
|
10
|
+
@gauge.name = "Fake Gauge"
|
11
|
+
@gauge.source = "minitest"
|
12
|
+
@gauge.time = Time.now
|
13
|
+
@gauge.value = 55
|
14
|
+
|
15
|
+
@counter = Harness::Counter.new
|
16
|
+
@counter.id = "fake-counter"
|
17
|
+
@counter.name = "Fake Counter"
|
18
|
+
@counter.source = "minitest"
|
19
|
+
@counter.time = Time.now
|
20
|
+
@counter.value = 1337
|
21
|
+
@counter.units = :bytes
|
22
|
+
Harness.config.namespace = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_gauge_is_logged
|
26
|
+
mock_backend = MiniTest::Mock.new
|
27
|
+
mock_backend.expect :host, 'foo'
|
28
|
+
mock_backend.expect :port, 'bar'
|
29
|
+
|
30
|
+
Harness::StatsdAdapter.config.backend = mock_backend
|
31
|
+
mock_backend.expect :gauge, true, [String, 55]
|
32
|
+
|
33
|
+
assert @adapter.log_gauge(@gauge)
|
34
|
+
assert mock_backend.verify
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_logging_gauge_raises_an_exception_when_not_configured
|
38
|
+
mock_backend = MiniTest::Mock.new
|
39
|
+
mock_backend.expect :host, nil
|
40
|
+
mock_backend.expect :port, nil
|
41
|
+
|
42
|
+
Harness::StatsdAdapter.config.backend = mock_backend
|
43
|
+
mock_backend.expect :gauge, true, [String, 55]
|
44
|
+
|
45
|
+
assert_raises RuntimeError do
|
46
|
+
@adapter.log_gauge @gauge
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_counter_is_logged
|
51
|
+
mock_backend = MiniTest::Mock.new
|
52
|
+
mock_backend.expect :host, 'foo'
|
53
|
+
mock_backend.expect :port, 'bar'
|
54
|
+
|
55
|
+
Harness::StatsdAdapter.config.backend = mock_backend
|
56
|
+
mock_backend.expect :increment, true, [String, 1337]
|
57
|
+
|
58
|
+
assert @adapter.log_counter(@counter)
|
59
|
+
assert mock_backend.verify
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_logging_counter_raises_an_exception_when_not_configured
|
63
|
+
mock_backend = MiniTest::Mock.new
|
64
|
+
mock_backend.expect :host, nil
|
65
|
+
mock_backend.expect :port, nil
|
66
|
+
|
67
|
+
Harness::StatsdAdapter.config.backend = mock_backend
|
68
|
+
|
69
|
+
assert_raises RuntimeError do
|
70
|
+
@adapter.log_counter @counter
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/test/unit/gauge_test.rb
CHANGED
@@ -65,6 +65,16 @@ class GaugeTest < MiniTest::Unit::TestCase
|
|
65
65
|
assert_equal 'foo', gauge.id
|
66
66
|
end
|
67
67
|
|
68
|
+
def test_sets_value_from_payload_if_number
|
69
|
+
base = Time.now
|
70
|
+
|
71
|
+
event = ActiveSupport::Notifications::Event.new "name", base - 1, Time.now, nil, :gauge => {value: 42}
|
72
|
+
|
73
|
+
gauge = Harness::Gauge.from_event event
|
74
|
+
|
75
|
+
assert_equal 42, gauge.value
|
76
|
+
end
|
77
|
+
|
68
78
|
def test_initializes_time_if_not_set
|
69
79
|
gauge = Harness::Gauge.new
|
70
80
|
|
data/test/unit/harness_test.rb
CHANGED
@@ -4,25 +4,25 @@ class HarnessModuleTest < MiniTest::Unit::TestCase
|
|
4
4
|
def test_can_set_the_adapter_with_a_symbol
|
5
5
|
Harness.config.adapter = :memory
|
6
6
|
|
7
|
-
|
7
|
+
assert_kind_of Harness::MemoryAdapter, Harness.config.adapter
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
Harness.config.adapter = Harness::MemoryAdapter
|
10
|
+
def test_can_set_the_adapter_with_an_adapter_instance
|
11
|
+
Harness.config.adapter = Harness::MemoryAdapter.new
|
12
12
|
|
13
|
-
|
13
|
+
assert_kind_of Harness::MemoryAdapter, Harness.config.adapter
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_can_set_the_queue_with_a_symbol
|
17
|
-
Harness.config.queue = :
|
17
|
+
Harness.config.queue = :synchronous
|
18
18
|
|
19
|
-
|
19
|
+
assert_kind_of Harness::SynchronousQueue, Harness.config.queue
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
Harness.config.
|
22
|
+
def test_can_set_the_queue_with_a_queue_instance
|
23
|
+
Harness.config.queue = Harness::SynchronousQueue.new
|
24
24
|
|
25
|
-
|
25
|
+
assert_kind_of Harness::SynchronousQueue, Harness.config.queue
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_uses_method_missing_to_configure_adapters
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: harness
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '3'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: redis
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: redis-namespace
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: simplecov
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :development
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: webmock
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,10 +85,15 @@ dependencies:
|
|
65
85
|
version: '0'
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: resque
|
71
|
-
requirement:
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ! '>='
|
@@ -76,10 +101,31 @@ dependencies:
|
|
76
101
|
version: '0'
|
77
102
|
type: :development
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
80
110
|
- !ruby/object:Gem::Dependency
|
81
111
|
name: sidekiq
|
82
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: delayed_job_active_record
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
83
129
|
none: false
|
84
130
|
requirements:
|
85
131
|
- - ! '>='
|
@@ -87,10 +133,15 @@ dependencies:
|
|
87
133
|
version: '0'
|
88
134
|
type: :development
|
89
135
|
prerelease: false
|
90
|
-
version_requirements:
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
91
142
|
- !ruby/object:Gem::Dependency
|
92
143
|
name: active_model_serializers
|
93
|
-
requirement:
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
94
145
|
none: false
|
95
146
|
requirements:
|
96
147
|
- - ! '>='
|
@@ -98,10 +149,63 @@ dependencies:
|
|
98
149
|
version: '0'
|
99
150
|
type: :development
|
100
151
|
prerelease: false
|
101
|
-
version_requirements:
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
102
158
|
- !ruby/object:Gem::Dependency
|
103
159
|
name: rails
|
104
|
-
requirement:
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: sqlite3
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: minitest
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
- !ruby/object:Gem::Dependency
|
207
|
+
name: statsd-instrument
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
105
209
|
none: false
|
106
210
|
requirements:
|
107
211
|
- - ! '>='
|
@@ -109,7 +213,12 @@ dependencies:
|
|
109
213
|
version: '0'
|
110
214
|
type: :development
|
111
215
|
prerelease: false
|
112
|
-
version_requirements:
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ! '>='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
113
222
|
description: ''
|
114
223
|
email:
|
115
224
|
- me@broadcastingadam.com
|
@@ -127,6 +236,8 @@ files:
|
|
127
236
|
- lib/harness/adapters/librato_adapter.rb
|
128
237
|
- lib/harness/adapters/memory_adapter.rb
|
129
238
|
- lib/harness/adapters/null_adapter.rb
|
239
|
+
- lib/harness/adapters/stathat_adapter.rb
|
240
|
+
- lib/harness/adapters/statsd_adapter.rb
|
130
241
|
- lib/harness/consumer.rb
|
131
242
|
- lib/harness/counter.rb
|
132
243
|
- lib/harness/gauge.rb
|
@@ -140,9 +251,10 @@ files:
|
|
140
251
|
- lib/harness/job.rb
|
141
252
|
- lib/harness/measurement.rb
|
142
253
|
- lib/harness/meter.rb
|
254
|
+
- lib/harness/queues/delayed_job_queue.rb
|
143
255
|
- lib/harness/queues/resque_queue.rb
|
144
256
|
- lib/harness/queues/sidekiq_queue.rb
|
145
|
-
- lib/harness/queues/
|
257
|
+
- lib/harness/queues/synchronous_queue.rb
|
146
258
|
- lib/harness/railtie.rb
|
147
259
|
- lib/harness/tasks.rake
|
148
260
|
- lib/harness/version.rb
|
@@ -156,17 +268,19 @@ files:
|
|
156
268
|
- test/integration/integrations/sidekiq_test.rb
|
157
269
|
- test/integration/logging_test.rb
|
158
270
|
- test/integration/meter_test.rb
|
271
|
+
- test/integration/queues/delayed_job_test.rb
|
159
272
|
- test/integration/queues/resque_test.rb
|
160
273
|
- test/integration/queues/sidekiq_test.rb
|
161
274
|
- test/integration/railtie_test.rb
|
162
275
|
- test/test_helper.rb
|
163
276
|
- test/unit/adapters/librato_adapter_test.rb
|
164
277
|
- test/unit/adapters/memory_adapter_test.rb
|
278
|
+
- test/unit/adapters/stathat_adapter_test.rb
|
279
|
+
- test/unit/adapters/statsd_adapter_test.rb
|
165
280
|
- test/unit/counter_test.rb
|
166
281
|
- test/unit/gauge_test.rb
|
167
282
|
- test/unit/harness_test.rb
|
168
283
|
- test/unit/measurement_test.rb
|
169
|
-
- test/unit/meter_test.rb
|
170
284
|
homepage: ''
|
171
285
|
licenses: []
|
172
286
|
post_install_message:
|
@@ -179,15 +293,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
179
293
|
- - ! '>='
|
180
294
|
- !ruby/object:Gem::Version
|
181
295
|
version: '0'
|
296
|
+
segments:
|
297
|
+
- 0
|
298
|
+
hash: -4565454551887677115
|
182
299
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
300
|
none: false
|
184
301
|
requirements:
|
185
302
|
- - ! '>='
|
186
303
|
- !ruby/object:Gem::Version
|
187
304
|
version: '0'
|
305
|
+
segments:
|
306
|
+
- 0
|
307
|
+
hash: -4565454551887677115
|
188
308
|
requirements: []
|
189
309
|
rubyforge_project:
|
190
|
-
rubygems_version: 1.8.
|
310
|
+
rubygems_version: 1.8.24
|
191
311
|
signing_key:
|
192
312
|
specification_version: 3
|
193
313
|
summary: ''
|
@@ -202,14 +322,16 @@ test_files:
|
|
202
322
|
- test/integration/integrations/sidekiq_test.rb
|
203
323
|
- test/integration/logging_test.rb
|
204
324
|
- test/integration/meter_test.rb
|
325
|
+
- test/integration/queues/delayed_job_test.rb
|
205
326
|
- test/integration/queues/resque_test.rb
|
206
327
|
- test/integration/queues/sidekiq_test.rb
|
207
328
|
- test/integration/railtie_test.rb
|
208
329
|
- test/test_helper.rb
|
209
330
|
- test/unit/adapters/librato_adapter_test.rb
|
210
331
|
- test/unit/adapters/memory_adapter_test.rb
|
332
|
+
- test/unit/adapters/stathat_adapter_test.rb
|
333
|
+
- test/unit/adapters/statsd_adapter_test.rb
|
211
334
|
- test/unit/counter_test.rb
|
212
335
|
- test/unit/gauge_test.rb
|
213
336
|
- test/unit/harness_test.rb
|
214
337
|
- test/unit/measurement_test.rb
|
215
|
-
- test/unit/meter_test.rb
|
data/test/unit/meter_test.rb
DELETED
File without changes
|