instrumental_agent 0.9.10 → 0.9.11
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/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
|