instrumental_agent 0.9.1 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +6 -0
- data/README.md +16 -0
- data/lib/instrumental/agent.rb +60 -43
- data/lib/instrumental/version.rb +1 -1
- data/spec/agent_spec.rb +61 -9
- data/spec/test_server.rb +44 -16
- metadata +115 -81
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
### 0.9.5 [March 23rd, 2012]
|
2
|
+
* Defer startup of agent thread until metrics are submitted - this update is strongly recommended for anyone using Ruby Enterprise Edition in concert w/ a preforking application server (like Phusion Passenger). See the [REE wiki page](https://github.com/fastestforward/instrumental_agent/wiki/Using-with-Ruby-Enterprise-Edition) for more information.
|
3
|
+
* Add .stop method for cancelling agent processing
|
4
|
+
* Changes to how defaults are processed at initialization
|
5
|
+
* Documentation for usage w/ Resque and Resque like scenarios
|
6
|
+
|
1
7
|
### 0.9.1 [March 6th, 2012]
|
2
8
|
* No longer install system_timer on Ruby 1.8.x, but warn if it's not installed
|
3
9
|
|
data/README.md
CHANGED
@@ -89,6 +89,22 @@ after "deploy:migrations", "instrumental:util:deploy_end"
|
|
89
89
|
after "instrumental:util:deploy_end", "instrumental:record_deploy_notice"
|
90
90
|
```
|
91
91
|
|
92
|
+
## Tracking metrics in Resque jobs (and Resque-like scenarios)
|
93
|
+
|
94
|
+
If you plan on tracking metrics in your Resque jobs, you will need to explicitly flush your metrics when the jobs are finished. You can accomplish this by adding the following code to your app initializers:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
Resque.after_perform { I.flush }
|
98
|
+
Resque.on_failure { I.flush }
|
99
|
+
```
|
100
|
+
|
101
|
+
You're required to do this because Resque calls `exit!` when a worker has finished processing, which bypasses Ruby's `at_exit` hooks. The Instrumental Agent installs an `at_exit` hook to flush any pending metrics to the servers, but this hook is bypassed by the `exit!` call; any other code you rely that uses `exit!` should call `I.flush` to ensure any pending metrics are correctly sent to the server before exiting the process.
|
102
|
+
|
103
|
+
## Using with Ruby Enterprise Edition
|
104
|
+
|
105
|
+
Users of Ruby Enterprise Edition should plan on using version 0.9.5 of the Instrumental Agent or greater. Please see the [REE wiki page](https://github.com/fastestforward/instrumental_agent/wiki/Using-with-Ruby-Enterprise-Edition) for more information.
|
106
|
+
|
107
|
+
|
92
108
|
## Troubleshooting & Help
|
93
109
|
|
94
110
|
We are here to help. Email us at [support@instrumentalapp.com](mailto:support@instrumentalapp.com), or visit the [Instrumental Support](https://fastestforward.campfirenow.com/6b934) Campfire room.
|
data/lib/instrumental/agent.rb
CHANGED
@@ -3,6 +3,7 @@ require 'instrumental/version'
|
|
3
3
|
require 'logger'
|
4
4
|
require 'thread'
|
5
5
|
require 'socket'
|
6
|
+
|
6
7
|
if RUBY_VERSION < "1.9" && RUBY_PLATFORM != "java"
|
7
8
|
begin
|
8
9
|
gem 'system_timer'
|
@@ -69,32 +70,28 @@ module Instrumental
|
|
69
70
|
# Instrumental::Agent.new(API_KEY)
|
70
71
|
# Instrumental::Agent.new(API_KEY, :collector => 'hostname:port')
|
71
72
|
def initialize(api_key, options = {})
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
@
|
84
|
-
@
|
85
|
-
@
|
86
|
-
@
|
73
|
+
# symbolize options keys
|
74
|
+
options.replace(
|
75
|
+
options.inject({}) { |m, (k, v)| m[(k.to_sym rescue k) || k] = v; m }
|
76
|
+
)
|
77
|
+
|
78
|
+
# defaults
|
79
|
+
# host: instrumentalapp.com
|
80
|
+
# port: 8000
|
81
|
+
# enabled: true
|
82
|
+
# test_mode: false
|
83
|
+
# synchronous: false
|
84
|
+
@api_key = api_key
|
85
|
+
@host, @port = options[:collector].to_s.split(':')
|
86
|
+
@host ||= 'instrumentalapp.com'
|
87
|
+
@port = (@port || 8000).to_i
|
88
|
+
@enabled = options.has_key?(:enabled) ? !!options[:enabled] : true
|
89
|
+
@test_mode = !!options[:test_mode]
|
90
|
+
@synchronous = !!options[:synchronous]
|
91
|
+
@pid = Process.pid
|
87
92
|
@allow_reconnect = true
|
88
|
-
@pid = Process.pid
|
89
|
-
|
90
93
|
|
91
|
-
if @enabled
|
92
|
-
@failures = 0
|
93
|
-
@queue = Queue.new
|
94
|
-
@sync_mutex = Mutex.new
|
95
|
-
start_connection_worker
|
96
|
-
setup_cleanup_at_exit
|
97
|
-
end
|
94
|
+
setup_cleanup_at_exit if @enabled
|
98
95
|
end
|
99
96
|
|
100
97
|
# Store a gauge for a metric, optionally at a specific time.
|
@@ -204,6 +201,23 @@ module Instrumental
|
|
204
201
|
@logger ||= self.class.logger
|
205
202
|
end
|
206
203
|
|
204
|
+
# Stopping the agent will immediately stop all communication
|
205
|
+
# to Instrumental. If you call this and submit another metric,
|
206
|
+
# the agent will start again.
|
207
|
+
#
|
208
|
+
# Calling stop will cause all metrics waiting to be sent to be
|
209
|
+
# discarded. Don't call it unless you are expecting this behavior.
|
210
|
+
#
|
211
|
+
# agent.stop
|
212
|
+
#
|
213
|
+
def stop
|
214
|
+
disconnect
|
215
|
+
if @thread
|
216
|
+
@thread.kill
|
217
|
+
@thread = nil
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
207
221
|
private
|
208
222
|
|
209
223
|
def with_timeout(time, &block)
|
@@ -242,13 +256,7 @@ module Instrumental
|
|
242
256
|
|
243
257
|
def send_command(cmd, *args)
|
244
258
|
if enabled?
|
245
|
-
if
|
246
|
-
logger.info "Detected fork"
|
247
|
-
@pid = Process.pid
|
248
|
-
@socket = nil
|
249
|
-
@queue = Queue.new
|
250
|
-
start_connection_worker
|
251
|
-
end
|
259
|
+
start_connection_worker if !running?
|
252
260
|
|
253
261
|
cmd = "%s %s\n" % [cmd, args.collect { |a| a.to_s }.join(" ")]
|
254
262
|
if @queue.size < MAX_BUFFER
|
@@ -293,6 +301,10 @@ module Instrumental
|
|
293
301
|
def start_connection_worker
|
294
302
|
if enabled?
|
295
303
|
disconnect
|
304
|
+
@pid = Process.pid
|
305
|
+
@queue = Queue.new
|
306
|
+
@sync_mutex = Mutex.new
|
307
|
+
@failures = 0
|
296
308
|
logger.info "Starting thread"
|
297
309
|
@thread = Thread.new do
|
298
310
|
run_worker_loop
|
@@ -364,23 +376,28 @@ module Instrumental
|
|
364
376
|
|
365
377
|
def setup_cleanup_at_exit
|
366
378
|
at_exit do
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
379
|
+
if running?
|
380
|
+
logger.info "Cleaning up agent, queue empty: #{@queue.empty?}, thread running: #{@thread.alive?}"
|
381
|
+
@allow_reconnect = false
|
382
|
+
logger.info "exit received, currently #{@queue.size} commands to be sent"
|
383
|
+
queue_message('exit')
|
384
|
+
begin
|
385
|
+
with_timeout(EXIT_FLUSH_TIMEOUT) { @thread.join }
|
386
|
+
rescue Timeout::Error
|
387
|
+
if @queue.size > 0
|
388
|
+
logger.error "Timed out working agent thread on exit, dropping #{@queue.size} metrics"
|
389
|
+
else
|
390
|
+
logger.error "Timed out Instrumental Agent, exiting"
|
391
|
+
end
|
378
392
|
end
|
379
393
|
end
|
380
|
-
|
381
394
|
end
|
382
395
|
end
|
383
396
|
|
397
|
+
def running?
|
398
|
+
!@thread.nil? && @pid == Process.pid
|
399
|
+
end
|
400
|
+
|
384
401
|
def disconnect
|
385
402
|
if connected?
|
386
403
|
logger.info "Disconnecting..."
|
data/lib/instrumental/version.rb
CHANGED
data/spec/agent_spec.rb
CHANGED
@@ -12,6 +12,8 @@ describe Instrumental::Agent, "disabled" do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
after do
|
15
|
+
@agent.stop
|
16
|
+
@agent = nil
|
15
17
|
@server.stop
|
16
18
|
end
|
17
19
|
|
@@ -43,26 +45,36 @@ describe Instrumental::Agent, "disabled" do
|
|
43
45
|
end
|
44
46
|
|
45
47
|
describe Instrumental::Agent, "enabled in test_mode" do
|
46
|
-
before do
|
48
|
+
before(:each) do
|
47
49
|
@server = TestServer.new
|
48
50
|
@agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :test_mode => true)
|
49
51
|
end
|
50
52
|
|
51
|
-
after do
|
53
|
+
after(:each) do
|
54
|
+
@agent.stop
|
55
|
+
@agent = nil
|
52
56
|
@server.stop
|
53
57
|
end
|
54
58
|
|
55
|
-
it "should connect to the server" do
|
59
|
+
it "should not connect to the server" do
|
60
|
+
wait
|
61
|
+
@server.connect_count.should == 0
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should connect to the server when the user sends a metric" do
|
65
|
+
@agent.increment("test.foo")
|
56
66
|
wait
|
57
67
|
@server.connect_count.should == 1
|
58
68
|
end
|
59
69
|
|
60
70
|
it "should announce itself, and include version and test_mode flag" do
|
71
|
+
@agent.increment("test.foo")
|
61
72
|
wait
|
62
73
|
@server.commands[0].should =~ /hello .*version .*test_mode true/
|
63
74
|
end
|
64
75
|
|
65
76
|
it "should authenticate using the token" do
|
77
|
+
@agent.increment("test.foo")
|
66
78
|
wait
|
67
79
|
@server.commands[1].should == "authenticate test_token"
|
68
80
|
end
|
@@ -110,7 +122,7 @@ describe Instrumental::Agent, "enabled in test_mode" do
|
|
110
122
|
wait
|
111
123
|
@server.commands.last.should =~ /gauge time_ms_test .* #{now.to_i}/
|
112
124
|
time = @server.commands.last.scan(/gauge time_ms_test (.*) #{now.to_i}/)[0][0].to_f
|
113
|
-
time.should > 100
|
125
|
+
time.should > 100.0
|
114
126
|
end
|
115
127
|
|
116
128
|
it "should report an increment" do
|
@@ -126,6 +138,17 @@ describe Instrumental::Agent, "enabled in test_mode" do
|
|
126
138
|
wait
|
127
139
|
@server.commands.join("\n").should include("notice #{tm.to_i} 0 Test note")
|
128
140
|
end
|
141
|
+
|
142
|
+
it "should allow outgoing metrics to be stopped" do
|
143
|
+
tm = Time.now
|
144
|
+
@agent.increment("foo.bar", 1, tm)
|
145
|
+
@agent.stop
|
146
|
+
wait
|
147
|
+
@agent.increment("foo.baz", 1, tm)
|
148
|
+
wait
|
149
|
+
@server.commands.join("\n").should include("increment foo.baz 1 #{tm.to_i}")
|
150
|
+
@server.commands.join("\n").should_not include("increment foo.bar 1 #{tm.to_i}")
|
151
|
+
end
|
129
152
|
end
|
130
153
|
|
131
154
|
describe Instrumental::Agent, "enabled" do
|
@@ -135,20 +158,30 @@ describe Instrumental::Agent, "enabled" do
|
|
135
158
|
end
|
136
159
|
|
137
160
|
after do
|
161
|
+
@agent.stop
|
162
|
+
@agent = nil
|
138
163
|
@server.stop
|
139
164
|
end
|
140
165
|
|
141
|
-
it "should connect to the server" do
|
166
|
+
it "should not connect to the server" do
|
167
|
+
wait
|
168
|
+
@server.connect_count.should == 0
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should connect to the server after sending a metric" do
|
172
|
+
@agent.increment("test.foo")
|
142
173
|
wait
|
143
174
|
@server.connect_count.should == 1
|
144
175
|
end
|
145
176
|
|
146
177
|
it "should announce itself, and include version" do
|
178
|
+
@agent.increment("test.foo")
|
147
179
|
wait
|
148
180
|
@server.commands[0].should =~ /hello .*version /
|
149
181
|
end
|
150
182
|
|
151
183
|
it "should authenticate using the token" do
|
184
|
+
@agent.increment("test.foo")
|
152
185
|
wait
|
153
186
|
@server.commands[1].should == "authenticate test_token"
|
154
187
|
end
|
@@ -267,10 +300,10 @@ describe Instrumental::Agent, "enabled" do
|
|
267
300
|
end
|
268
301
|
|
269
302
|
it "should return nil if the user overflows the MAX_BUFFER" do
|
270
|
-
thread = @agent.instance_variable_get(:@thread)
|
271
|
-
thread.kill
|
272
303
|
1.upto(Instrumental::Agent::MAX_BUFFER) do
|
273
304
|
@agent.increment("test").should == 1
|
305
|
+
thread = @agent.instance_variable_get(:@thread)
|
306
|
+
thread.kill
|
274
307
|
end
|
275
308
|
@agent.increment("test").should be_nil
|
276
309
|
end
|
@@ -324,6 +357,17 @@ describe Instrumental::Agent, "enabled" do
|
|
324
357
|
@server.commands.join("\n").should_not include("notice Test note")
|
325
358
|
end
|
326
359
|
|
360
|
+
it "should allow outgoing metrics to be stopped" do
|
361
|
+
tm = Time.now
|
362
|
+
@agent.increment("foo.bar", 1, tm)
|
363
|
+
@agent.stop
|
364
|
+
wait
|
365
|
+
@agent.increment("foo.baz", 1, tm)
|
366
|
+
wait
|
367
|
+
@server.commands.join("\n").should include("increment foo.baz 1 #{tm.to_i}")
|
368
|
+
@server.commands.join("\n").should_not include("increment foo.bar 1 #{tm.to_i}")
|
369
|
+
end
|
370
|
+
|
327
371
|
it "should allow flushing pending values to the server" do
|
328
372
|
1.upto(100) { @agent.gauge('a', rand(50)) }
|
329
373
|
@agent.instance_variable_get(:@queue).size.should >= 100
|
@@ -336,18 +380,20 @@ end
|
|
336
380
|
|
337
381
|
describe Instrumental::Agent, "connection problems" do
|
338
382
|
after do
|
383
|
+
@agent.stop
|
339
384
|
@server.stop
|
340
385
|
end
|
341
386
|
|
342
387
|
it "should automatically reconnect on disconnect" do
|
343
388
|
@server = TestServer.new
|
344
389
|
@agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :synchronous => false)
|
390
|
+
@agent.increment("reconnect_test", 1, 1234)
|
345
391
|
wait
|
346
392
|
@server.disconnect_all
|
347
|
-
@agent.increment('reconnect_test', 1,
|
393
|
+
@agent.increment('reconnect_test', 1, 5678) # triggers reconnect
|
348
394
|
wait
|
349
395
|
@server.connect_count.should == 2
|
350
|
-
@server.commands.last.should == "increment reconnect_test 1
|
396
|
+
@server.commands.last.should == "increment reconnect_test 1 5678"
|
351
397
|
end
|
352
398
|
|
353
399
|
it "should buffer commands when server is down" do
|
@@ -408,6 +454,11 @@ describe Instrumental::Agent, "enabled with sync option" do
|
|
408
454
|
@agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :synchronous => true)
|
409
455
|
end
|
410
456
|
|
457
|
+
after do
|
458
|
+
@agent.stop
|
459
|
+
@server.stop
|
460
|
+
end
|
461
|
+
|
411
462
|
it "should send all data in synchronous mode" do
|
412
463
|
with_constants('Instrumental::Agent::MAX_BUFFER' => 3) do
|
413
464
|
5.times do |i|
|
@@ -421,4 +472,5 @@ describe Instrumental::Agent, "enabled with sync option" do
|
|
421
472
|
@server.commands.should include("increment overflow_test 5 300")
|
422
473
|
end
|
423
474
|
end
|
475
|
+
|
424
476
|
end
|
data/spec/test_server.rb
CHANGED
@@ -13,36 +13,50 @@ class TestServer
|
|
13
13
|
@connections = []
|
14
14
|
@commands = []
|
15
15
|
@host = 'localhost'
|
16
|
+
@main_thread = nil
|
17
|
+
@client_threads = []
|
18
|
+
@fd_to_thread = {}
|
16
19
|
listen if @options[:listen]
|
17
20
|
end
|
18
21
|
|
22
|
+
|
19
23
|
def listen
|
20
24
|
@port ||= 10001
|
21
25
|
@server = TCPServer.new(port)
|
22
|
-
Thread.new do
|
26
|
+
@main_thread = Thread.new do
|
23
27
|
begin
|
24
28
|
# puts "listening"
|
25
29
|
loop do
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
client = @server.accept
|
31
|
+
@connections << client
|
32
|
+
@connect_count += 1
|
33
|
+
@fd_to_thread[client.to_i] = Thread.new(client) do |socket|
|
30
34
|
# puts "connection received"
|
31
35
|
loop do
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
begin
|
37
|
+
command = ""
|
38
|
+
while (c = socket.read(1)) != "\n"
|
39
|
+
command << c unless c.nil?
|
40
|
+
end
|
41
|
+
if !command.empty?
|
42
|
+
# puts "got: #{command}"
|
43
|
+
commands << command
|
44
|
+
if %w[hello authenticate].include?(command.split(' ')[0])
|
45
|
+
if @options[:response]
|
46
|
+
if @options[:authenticate]
|
47
|
+
socket.puts "ok"
|
48
|
+
else
|
49
|
+
socket.puts "gtfo"
|
50
|
+
end
|
51
|
+
end
|
41
52
|
end
|
42
53
|
end
|
54
|
+
rescue Exception => e
|
55
|
+
break
|
43
56
|
end
|
44
57
|
end
|
45
58
|
end
|
59
|
+
@client_threads << @fd_to_thread[client.to_i]
|
46
60
|
end
|
47
61
|
rescue Exception => err
|
48
62
|
unless @stopping
|
@@ -67,10 +81,24 @@ class TestServer
|
|
67
81
|
def stop
|
68
82
|
@stopping = true
|
69
83
|
disconnect_all
|
70
|
-
@
|
84
|
+
@main_thread.kill if @main_thread
|
85
|
+
@main_thread = nil
|
86
|
+
@client_threads.each { |thread| thread.kill }
|
87
|
+
@client_threads = []
|
88
|
+
begin
|
89
|
+
@server.close if @server
|
90
|
+
rescue Exception => e
|
91
|
+
end
|
71
92
|
end
|
72
93
|
|
73
94
|
def disconnect_all
|
74
|
-
@connections.each { |c|
|
95
|
+
@connections.each { |c|
|
96
|
+
if (thr = @fd_to_thread[c.to_i])
|
97
|
+
thr.kill
|
98
|
+
end
|
99
|
+
@fd_to_thread.delete(c.to_i)
|
100
|
+
c.close rescue false
|
101
|
+
}
|
102
|
+
@connections = []
|
75
103
|
end
|
76
104
|
end
|
metadata
CHANGED
@@ -1,10 +1,15 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: instrumental_agent
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 49
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 9
|
9
|
+
- 5
|
10
|
+
version: 0.9.5
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Elijah Miller
|
9
14
|
- Christopher Zelenak
|
10
15
|
- Kristopher Chambers
|
@@ -12,92 +17,118 @@ authors:
|
|
12
17
|
autorequire:
|
13
18
|
bindir: bin
|
14
19
|
cert_chain: []
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
requirement: &70101951414580 !ruby/object:Gem::Requirement
|
20
|
-
none: false
|
21
|
-
requirements:
|
22
|
-
- - ! '>='
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: '0'
|
20
|
+
|
21
|
+
date: 2012-03-23 00:00:00 Z
|
22
|
+
dependencies:
|
23
|
+
- !ruby/object:Gem::Dependency
|
25
24
|
type: :development
|
26
25
|
prerelease: false
|
27
|
-
version_requirements:
|
28
|
-
- !ruby/object:Gem::Dependency
|
29
|
-
name: rspec
|
30
|
-
requirement: &70101951413720 !ruby/object:Gem::Requirement
|
26
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
31
27
|
none: false
|
32
|
-
requirements:
|
33
|
-
- -
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
hash: 3
|
32
|
+
segments:
|
33
|
+
- 0
|
34
|
+
version: "0"
|
35
|
+
requirement: *id001
|
36
|
+
name: rake
|
37
|
+
- !ruby/object:Gem::Dependency
|
36
38
|
type: :development
|
37
39
|
prerelease: false
|
38
|
-
version_requirements:
|
39
|
-
- !ruby/object:Gem::Dependency
|
40
|
-
name: fuubar
|
41
|
-
requirement: &70101951429080 !ruby/object:Gem::Requirement
|
40
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
42
41
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 3
|
46
|
+
segments:
|
47
|
+
- 2
|
48
|
+
- 0
|
49
|
+
version: "2.0"
|
50
|
+
requirement: *id002
|
51
|
+
name: rspec
|
52
|
+
- !ruby/object:Gem::Dependency
|
47
53
|
type: :development
|
48
54
|
prerelease: false
|
49
|
-
version_requirements:
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
name: guard
|
52
|
-
requirement: &70101951428440 !ruby/object:Gem::Requirement
|
55
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
53
56
|
none: false
|
54
|
-
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
requirement: *id003
|
65
|
+
name: fuubar
|
66
|
+
- !ruby/object:Gem::Dependency
|
58
67
|
type: :development
|
59
68
|
prerelease: false
|
60
|
-
version_requirements:
|
61
|
-
- !ruby/object:Gem::Dependency
|
62
|
-
name: guard-rspec
|
63
|
-
requirement: &70101951427760 !ruby/object:Gem::Requirement
|
69
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
64
70
|
none: false
|
65
|
-
requirements:
|
66
|
-
- -
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
requirement: *id004
|
79
|
+
name: guard
|
80
|
+
- !ruby/object:Gem::Dependency
|
69
81
|
type: :development
|
70
82
|
prerelease: false
|
71
|
-
version_requirements:
|
72
|
-
- !ruby/object:Gem::Dependency
|
73
|
-
name: growl
|
74
|
-
requirement: &70101951424880 !ruby/object:Gem::Requirement
|
83
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
75
84
|
none: false
|
76
|
-
requirements:
|
77
|
-
- -
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
requirement: *id005
|
93
|
+
name: guard-rspec
|
94
|
+
- !ruby/object:Gem::Dependency
|
80
95
|
type: :development
|
81
96
|
prerelease: false
|
82
|
-
version_requirements:
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rb-fsevent
|
85
|
-
requirement: &70101951423500 !ruby/object:Gem::Requirement
|
97
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
86
98
|
none: false
|
87
|
-
requirements:
|
88
|
-
- -
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
hash: 3
|
103
|
+
segments:
|
104
|
+
- 0
|
105
|
+
version: "0"
|
106
|
+
requirement: *id006
|
107
|
+
name: growl
|
108
|
+
- !ruby/object:Gem::Dependency
|
91
109
|
type: :development
|
92
110
|
prerelease: false
|
93
|
-
version_requirements:
|
111
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
hash: 3
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
version: "0"
|
120
|
+
requirement: *id007
|
121
|
+
name: rb-fsevent
|
94
122
|
description: Track anything.
|
95
|
-
email:
|
123
|
+
email:
|
96
124
|
- support@instrumentalapp.com
|
97
125
|
executables: []
|
126
|
+
|
98
127
|
extensions: []
|
128
|
+
|
99
129
|
extra_rdoc_files: []
|
100
|
-
|
130
|
+
|
131
|
+
files:
|
101
132
|
- .gitignore
|
102
133
|
- .rspec
|
103
134
|
- CHANGELOG.md
|
@@ -116,35 +147,38 @@ files:
|
|
116
147
|
- spec/test_server.rb
|
117
148
|
homepage: http://github.com/fastestforward/instrumental_agent
|
118
149
|
licenses: []
|
150
|
+
|
119
151
|
post_install_message:
|
120
152
|
rdoc_options: []
|
121
|
-
|
153
|
+
|
154
|
+
require_paths:
|
122
155
|
- lib
|
123
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
157
|
none: false
|
125
|
-
requirements:
|
126
|
-
- -
|
127
|
-
- !ruby/object:Gem::Version
|
128
|
-
|
129
|
-
segments:
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
hash: 3
|
162
|
+
segments:
|
130
163
|
- 0
|
131
|
-
|
132
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
version: "0"
|
165
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
166
|
none: false
|
134
|
-
requirements:
|
135
|
-
- -
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
|
138
|
-
segments:
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
hash: 3
|
171
|
+
segments:
|
139
172
|
- 0
|
140
|
-
|
173
|
+
version: "0"
|
141
174
|
requirements: []
|
175
|
+
|
142
176
|
rubyforge_project:
|
143
177
|
rubygems_version: 1.8.10
|
144
178
|
signing_key:
|
145
179
|
specification_version: 3
|
146
180
|
summary: Agent for reporting data to instrumentalapp.com
|
147
|
-
test_files:
|
181
|
+
test_files:
|
148
182
|
- spec/agent_spec.rb
|
149
183
|
- spec/spec_helper.rb
|
150
184
|
- spec/test_server.rb
|