instrumental_agent 0.9.10 → 0.9.11
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +4 -0
- data/README.md +2 -2
- data/lib/instrumental/agent.rb +26 -16
- data/lib/instrumental/version.rb +1 -1
- data/spec/agent_spec.rb +23 -0
- metadata +5 -5
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -91,9 +91,9 @@ after "instrumental:util:deploy_end", "instrumental:record_deploy_notice"
|
|
91
91
|
|
92
92
|
## Tracking metrics in Resque jobs (and Resque-like scenarios)
|
93
93
|
|
94
|
-
If you plan on tracking metrics in
|
94
|
+
If you plan on tracking metrics in Resque jobs, you will need to explicitly cleanup after the agent when the jobs are finished. You can accomplish this by adding `after_perform` and `on_failure` hooks to your Resque jobs. See the Resque [hooks documentation](https://github.com/defunkt/resque/blob/master/docs/HOOKS.md) for more information.
|
95
95
|
|
96
|
-
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.
|
96
|
+
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.cleanup` to ensure any pending metrics are correctly sent to the server before exiting the process.
|
97
97
|
|
98
98
|
## Using with Ruby Enterprise Edition
|
99
99
|
|
data/lib/instrumental/agent.rb
CHANGED
@@ -227,6 +227,29 @@ module Instrumental
|
|
227
227
|
end
|
228
228
|
end
|
229
229
|
|
230
|
+
# Called when a process is exiting to give it some extra time to
|
231
|
+
# push events to the service. An at_exit handler is automatically
|
232
|
+
# registered for this method, but can be called manually in cases
|
233
|
+
# where at_exit is bypassed like Resque workers.
|
234
|
+
def cleanup
|
235
|
+
if running?
|
236
|
+
logger.info "Cleaning up agent, queue size: #{@queue.size}, thread running: #{@thread.alive?}"
|
237
|
+
@allow_reconnect = false
|
238
|
+
if @queue.size > 0
|
239
|
+
queue_message('exit')
|
240
|
+
begin
|
241
|
+
with_timeout(EXIT_FLUSH_TIMEOUT) { @thread.join }
|
242
|
+
rescue Timeout::Error
|
243
|
+
if @queue.size > 0
|
244
|
+
logger.error "Timed out working agent thread on exit, dropping #{@queue.size} metrics"
|
245
|
+
else
|
246
|
+
logger.error "Timed out Instrumental Agent, exiting"
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
230
253
|
private
|
231
254
|
|
232
255
|
def with_timeout(time, &block)
|
@@ -346,7 +369,7 @@ module Instrumental
|
|
346
369
|
test_connection
|
347
370
|
case command_and_args
|
348
371
|
when 'exit'
|
349
|
-
logger.info "
|
372
|
+
logger.info "Exiting, #{@queue.size} commands remain"
|
350
373
|
return true
|
351
374
|
when 'flush'
|
352
375
|
release_resource = true
|
@@ -363,6 +386,7 @@ module Instrumental
|
|
363
386
|
end
|
364
387
|
end
|
365
388
|
rescue Exception => err
|
389
|
+
logger.debug err.to_s
|
366
390
|
logger.debug err.backtrace.join("\n")
|
367
391
|
if @allow_reconnect == false ||
|
368
392
|
(command_options && command_options[:allow_reconnect] == false)
|
@@ -385,21 +409,7 @@ module Instrumental
|
|
385
409
|
|
386
410
|
def setup_cleanup_at_exit
|
387
411
|
at_exit do
|
388
|
-
|
389
|
-
logger.info "Cleaning up agent, queue empty: #{@queue.empty?}, thread running: #{@thread.alive?}"
|
390
|
-
@allow_reconnect = false
|
391
|
-
logger.info "exit received, currently #{@queue.size} commands to be sent"
|
392
|
-
queue_message('exit')
|
393
|
-
begin
|
394
|
-
with_timeout(EXIT_FLUSH_TIMEOUT) { @thread.join }
|
395
|
-
rescue Timeout::Error
|
396
|
-
if @queue.size > 0
|
397
|
-
logger.error "Timed out working agent thread on exit, dropping #{@queue.size} metrics"
|
398
|
-
else
|
399
|
-
logger.error "Timed out Instrumental Agent, exiting"
|
400
|
-
end
|
401
|
-
end
|
402
|
-
end
|
412
|
+
cleanup
|
403
413
|
end
|
404
414
|
end
|
405
415
|
|
data/lib/instrumental/version.rb
CHANGED
data/spec/agent_spec.rb
CHANGED
@@ -450,6 +450,15 @@ describe Instrumental::Agent, "connection problems" do
|
|
450
450
|
end
|
451
451
|
end
|
452
452
|
|
453
|
+
it "should send commands in a process that bypasses at_exit when using #cleanup" do
|
454
|
+
@server = TestServer.new
|
455
|
+
@agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :synchronous => false)
|
456
|
+
if pid = fork { @agent.increment('foo', 1, 1234); @agent.cleanup; exit! }
|
457
|
+
Process.wait(pid)
|
458
|
+
@server.commands.last.should == "increment foo 1 1234"
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
453
462
|
it "should not wait longer than EXIT_FLUSH_TIMEOUT seconds to exit a process" do
|
454
463
|
@server = TestServer.new
|
455
464
|
@agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :synchronous => false)
|
@@ -464,6 +473,20 @@ describe Instrumental::Agent, "connection problems" do
|
|
464
473
|
end
|
465
474
|
end
|
466
475
|
end
|
476
|
+
|
477
|
+
it "should not wait to exit a process if there are no commands queued" do
|
478
|
+
@server = TestServer.new
|
479
|
+
@agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :synchronous => false)
|
480
|
+
TCPSocket.stub!(:new) { |*args| sleep(5) && StringIO.new }
|
481
|
+
with_constants('Instrumental::Agent::EXIT_FLUSH_TIMEOUT' => 3) do
|
482
|
+
if (pid = fork { @agent.increment('foo', 1); @agent.queue.clear })
|
483
|
+
tm = Time.now.to_f
|
484
|
+
Process.wait(pid)
|
485
|
+
diff = Time.now.to_f - tm
|
486
|
+
diff.should < 1
|
487
|
+
end
|
488
|
+
end
|
489
|
+
end
|
467
490
|
end
|
468
491
|
|
469
492
|
describe Instrumental::Agent, "enabled with sync option" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instrumental_agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.11
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-06
|
15
|
+
date: 2012-07-06 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rake
|
@@ -163,7 +163,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
163
|
version: '0'
|
164
164
|
segments:
|
165
165
|
- 0
|
166
|
-
hash:
|
166
|
+
hash: 2378004147866464833
|
167
167
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
168
|
none: false
|
169
169
|
requirements:
|
@@ -172,10 +172,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
172
|
version: '0'
|
173
173
|
segments:
|
174
174
|
- 0
|
175
|
-
hash:
|
175
|
+
hash: 2378004147866464833
|
176
176
|
requirements: []
|
177
177
|
rubyforge_project:
|
178
|
-
rubygems_version: 1.8.
|
178
|
+
rubygems_version: 1.8.21
|
179
179
|
signing_key:
|
180
180
|
specification_version: 3
|
181
181
|
summary: Agent for reporting data to instrumentalapp.com
|