instana 1.8.3 → 1.9.0.daftrabbit
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 +4 -4
- data/gemfiles/libraries.gemfile +3 -0
- data/lib/instana/agent.rb +13 -120
- data/lib/instana/agent/helpers.rb +58 -0
- data/lib/instana/agent/hooks.rb +37 -0
- data/lib/instana/agent/tasks.rb +45 -0
- data/lib/instana/config.rb +4 -2
- data/lib/instana/frameworks/rails.rb +24 -10
- data/lib/instana/instrumentation/resque.rb +127 -0
- data/lib/instana/tracing/span.rb +5 -3
- data/lib/instana/util.rb +9 -6
- data/lib/instana/version.rb +1 -1
- data/test/agent/agent_test.rb +3 -3
- data/test/instrumentation/resque_test.rb +128 -0
- data/test/jobs/resque_error_job.rb +16 -0
- data/test/jobs/resque_fast_job.rb +14 -0
- data/test/test_helper.rb +7 -3
- data/test/tracing/custom_test.rb +1 -1
- metadata +14 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b11875e63a40db84acb015973cfcf38b0f7b5d86a3c92a6ca4178582d525a0a
|
4
|
+
data.tar.gz: 78e31a128e0bed068b84a195e06f205a917b6ded8ac018e5493320dcbb202fa3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 645484fc592fc9578e4d7378b198ea867d61dabe25b51365a3545485e7f0a8b8454e4766104b0009178d2e009da64624f9fc8959fd73b6509162188a4ee55839
|
7
|
+
data.tar.gz: c6d2c36eeea6be0b0b09107a10cc9af56a9d12ec4960efe28dc151ff7570fec3ea8638ba6dc4e40a4699d7caf5dc9d79aab2e039e2982809c9286b92aba6bbb3
|
data/gemfiles/libraries.gemfile
CHANGED
@@ -49,6 +49,7 @@ gem 'excon'
|
|
49
49
|
|
50
50
|
# Memcache
|
51
51
|
gem 'dalli'
|
52
|
+
gem 'redis', '< 4.0.0'
|
52
53
|
|
53
54
|
# Background Job queuing and processing
|
54
55
|
if RUBY_VERSION < '2.2'
|
@@ -57,6 +58,8 @@ else
|
|
57
58
|
gem 'sidekiq', '> 5.0'
|
58
59
|
end
|
59
60
|
|
61
|
+
gem 'resque'
|
62
|
+
|
60
63
|
# Rack v2 dropped support for Ruby 2.2 and higher.
|
61
64
|
if RUBY_VERSION < '2.2'
|
62
65
|
gem 'rack', '< 2.0'
|
data/lib/instana/agent.rb
CHANGED
@@ -5,12 +5,21 @@ require 'sys/proctable'
|
|
5
5
|
require 'timers'
|
6
6
|
require 'uri'
|
7
7
|
require 'thread'
|
8
|
+
|
9
|
+
require 'instana/agent/helpers'
|
10
|
+
require 'instana/agent/hooks'
|
11
|
+
require 'instana/agent/tasks'
|
12
|
+
|
8
13
|
include Sys
|
9
14
|
|
10
15
|
Oj.default_options = {:mode => :strict}
|
11
16
|
|
12
17
|
module Instana
|
13
18
|
class Agent
|
19
|
+
include AgentHelpers
|
20
|
+
include AgentHooks
|
21
|
+
include AgentTasks
|
22
|
+
|
14
23
|
attr_accessor :state
|
15
24
|
attr_accessor :agent_uuid
|
16
25
|
attr_accessor :process
|
@@ -70,21 +79,6 @@ module Instana
|
|
70
79
|
@extra_headers = nil
|
71
80
|
end
|
72
81
|
|
73
|
-
# Used post fork to re-initialize state and restart communications with
|
74
|
-
# the host agent.
|
75
|
-
#
|
76
|
-
def after_fork
|
77
|
-
::Instana.logger.debug "after_fork hook called. Falling back to unannounced state and spawning a new background agent thread."
|
78
|
-
|
79
|
-
# Reseed the random number generator for this
|
80
|
-
# new thread.
|
81
|
-
srand
|
82
|
-
|
83
|
-
transition_to(:unannounced)
|
84
|
-
setup
|
85
|
-
spawn_background_thread
|
86
|
-
end
|
87
|
-
|
88
82
|
# Spawns the background thread and calls start. This method is separated
|
89
83
|
# out for those who wish to control which thread the background agent will
|
90
84
|
# run in.
|
@@ -120,7 +114,7 @@ module Instana
|
|
120
114
|
# In case of failure, we try again in 30 seconds.
|
121
115
|
@announce_timer = @timers.every(30) do
|
122
116
|
if @state == :unannounced
|
123
|
-
if
|
117
|
+
if host_agent_available? && announce_sensor
|
124
118
|
transition_to(:announced)
|
125
119
|
::Instana.logger.info "Host agent available. We're in business. (#{@state} pid:#{Process.pid} #{@process[:name]})"
|
126
120
|
end
|
@@ -156,7 +150,7 @@ module Instana
|
|
156
150
|
# called from an already initialized background thread.
|
157
151
|
#
|
158
152
|
def start
|
159
|
-
if !
|
153
|
+
if !host_agent_available?
|
160
154
|
if !ENV.key?("INSTANA_QUIET")
|
161
155
|
::Instana.logger.warn "Host agent not available. Will retry periodically. (Set env INSTANA_QUIET=1 to shut these messages off)"
|
162
156
|
end
|
@@ -279,50 +273,6 @@ module Instana
|
|
279
273
|
Instana.logger.debug e.backtrace.join("\r\n")
|
280
274
|
end
|
281
275
|
|
282
|
-
# When request(s) are received by the host agent, it is sent here
|
283
|
-
# for handling & processing.
|
284
|
-
#
|
285
|
-
# @param json_string [String] the requests from the host agent
|
286
|
-
#
|
287
|
-
def handle_agent_tasks(json_string)
|
288
|
-
tasks = Oj.load(json_string)
|
289
|
-
|
290
|
-
if tasks.is_a?(Hash)
|
291
|
-
process_agent_task(tasks)
|
292
|
-
elsif tasks.is_a?(Array)
|
293
|
-
tasks.each do |t|
|
294
|
-
process_agent_task(t)
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
# Process a task sent from the host agent.
|
300
|
-
#
|
301
|
-
# @param task [String] the request json from the host agent
|
302
|
-
#
|
303
|
-
def process_agent_task(task)
|
304
|
-
if task.key?("action")
|
305
|
-
if task["action"] == "ruby.source"
|
306
|
-
payload = ::Instana::Util.get_rb_source(task["args"]["file"])
|
307
|
-
else
|
308
|
-
payload = { :error => "Unrecognized action: #{task["action"]}. An newer Instana gem may be required for this. Current version: #{::Instana::VERSION}" }
|
309
|
-
end
|
310
|
-
else
|
311
|
-
payload = { :error => "Instana Ruby: No action specified in request." }
|
312
|
-
end
|
313
|
-
|
314
|
-
path = "com.instana.plugin.ruby/response.#{@process[:report_pid]}?messageId=#{URI.encode(task['messageId'])}"
|
315
|
-
uri = URI.parse("http://#{@discovered[:agent_host]}:#{@discovered[:agent_port]}/#{path}")
|
316
|
-
req = Net::HTTP::Post.new(uri)
|
317
|
-
req.body = Oj.dump(payload)
|
318
|
-
::Instana.logger.debug "Responding to agent request: #{req.inspect}"
|
319
|
-
make_host_agent_request(req)
|
320
|
-
|
321
|
-
rescue StandardError => e
|
322
|
-
Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
323
|
-
Instana.logger.debug e.backtrace.join("\r\n")
|
324
|
-
end
|
325
|
-
|
326
276
|
# Accept and report spans to the host agent.
|
327
277
|
#
|
328
278
|
# @param traces [Array] An array of [Span]
|
@@ -340,7 +290,7 @@ module Instana
|
|
340
290
|
uri = URI.parse("http://#{@discovered[:agent_host]}:#{@discovered[:agent_port]}/#{path}")
|
341
291
|
req = Net::HTTP::Post.new(uri)
|
342
292
|
|
343
|
-
req.body = Oj.dump(spans)
|
293
|
+
req.body = Oj.dump(spans, :omit_nil => true)
|
344
294
|
response = make_host_agent_request(req)
|
345
295
|
|
346
296
|
if response
|
@@ -360,7 +310,7 @@ module Instana
|
|
360
310
|
# first check localhost and if not, then attempt on the default gateway
|
361
311
|
# for docker in bridged mode.
|
362
312
|
#
|
363
|
-
def
|
313
|
+
def host_agent_available?
|
364
314
|
@discovered ||= run_discovery
|
365
315
|
|
366
316
|
if @discovered
|
@@ -428,31 +378,6 @@ module Instana
|
|
428
378
|
nil
|
429
379
|
end
|
430
380
|
|
431
|
-
# Returns the PID that we are reporting to
|
432
|
-
#
|
433
|
-
def report_pid
|
434
|
-
@process[:report_pid]
|
435
|
-
end
|
436
|
-
|
437
|
-
# Indicates if the agent is ready to send metrics
|
438
|
-
# and/or data.
|
439
|
-
#
|
440
|
-
def ready?
|
441
|
-
# In test, we're always ready :-)
|
442
|
-
return true if ENV['INSTANA_GEM_TEST']
|
443
|
-
|
444
|
-
if forked?
|
445
|
-
::Instana.logger.debug "Instana: detected fork. Calling after_fork"
|
446
|
-
after_fork
|
447
|
-
end
|
448
|
-
|
449
|
-
@state == :announced
|
450
|
-
rescue => e
|
451
|
-
Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
452
|
-
Instana.logger.debug e.backtrace.join("\r\n") unless ::Instana.test?
|
453
|
-
return false
|
454
|
-
end
|
455
|
-
|
456
381
|
private
|
457
382
|
|
458
383
|
# Handles any/all steps required in the transtion
|
@@ -511,37 +436,5 @@ module Instana
|
|
511
436
|
Instana.logger.debug e.backtrace.join("\r\n") unless ::Instana.test?
|
512
437
|
return nil
|
513
438
|
end
|
514
|
-
|
515
|
-
# Indicates whether we are running in a pid namespace (such as
|
516
|
-
# Docker).
|
517
|
-
#
|
518
|
-
def pid_namespace?
|
519
|
-
return false unless @is_linux
|
520
|
-
Process.pid != get_real_pid
|
521
|
-
end
|
522
|
-
|
523
|
-
# Attempts to determine the true process ID by querying the
|
524
|
-
# /proc/<pid>/sched file. This works on linux currently.
|
525
|
-
#
|
526
|
-
def get_real_pid
|
527
|
-
raise RuntimeError.new("Unsupported platform: get_real_pid") unless @is_linux
|
528
|
-
|
529
|
-
sched_file = "/proc/#{Process.pid}/sched"
|
530
|
-
pid = Process.pid
|
531
|
-
|
532
|
-
if File.exist?(sched_file)
|
533
|
-
v = File.open(sched_file, &:readline)
|
534
|
-
pid = v.match(/\d+/).to_s.to_i
|
535
|
-
end
|
536
|
-
pid
|
537
|
-
end
|
538
|
-
|
539
|
-
# Determine whether the pid has changed since Agent start.
|
540
|
-
#
|
541
|
-
# @ return [Boolean] true or false to indicate if forked
|
542
|
-
#
|
543
|
-
def forked?
|
544
|
-
@process[:pid] != Process.pid
|
545
|
-
end
|
546
439
|
end
|
547
440
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module AgentHelpers
|
2
|
+
# Indicates whether we are running in a pid namespace (such as
|
3
|
+
# Docker).
|
4
|
+
#
|
5
|
+
def pid_namespace?
|
6
|
+
return false unless @is_linux
|
7
|
+
Process.pid != get_real_pid
|
8
|
+
end
|
9
|
+
|
10
|
+
# Attempts to determine the true process ID by querying the
|
11
|
+
# /proc/<pid>/sched file. This works on linux currently.
|
12
|
+
#
|
13
|
+
def get_real_pid
|
14
|
+
raise RuntimeError.new("Unsupported platform: get_real_pid") unless @is_linux
|
15
|
+
|
16
|
+
sched_file = "/proc/#{Process.pid}/sched"
|
17
|
+
pid = Process.pid
|
18
|
+
|
19
|
+
if File.exist?(sched_file)
|
20
|
+
v = File.open(sched_file, &:readline)
|
21
|
+
pid = v.match(/\d+/).to_s.to_i
|
22
|
+
end
|
23
|
+
pid
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the PID that we are reporting to
|
27
|
+
#
|
28
|
+
def report_pid
|
29
|
+
@process[:report_pid]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Determine whether the pid has changed since Agent start.
|
33
|
+
#
|
34
|
+
# @ return [Boolean] true or false to indicate if forked
|
35
|
+
#
|
36
|
+
def forked?
|
37
|
+
@process[:pid] != Process.pid
|
38
|
+
end
|
39
|
+
|
40
|
+
# Indicates if the agent is ready to send metrics
|
41
|
+
# and/or data.
|
42
|
+
#
|
43
|
+
def ready?
|
44
|
+
# In test, we're always ready :-)
|
45
|
+
return true if ENV['INSTANA_GEM_TEST']
|
46
|
+
|
47
|
+
if !@is_resque_worker && forked?
|
48
|
+
::Instana.logger.debug "Instana: detected fork. (this pid: #{Process.pid}/#{Process.ppid}) Calling after_fork"
|
49
|
+
after_fork
|
50
|
+
end
|
51
|
+
|
52
|
+
@state == :announced
|
53
|
+
rescue => e
|
54
|
+
Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
55
|
+
Instana.logger.debug e.backtrace.join("\r\n") unless ::Instana.test?
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module AgentHooks
|
2
|
+
# Used post fork to re-initialize state and restart communications with
|
3
|
+
# the host agent.
|
4
|
+
#
|
5
|
+
def after_fork
|
6
|
+
::Instana.logger.debug "after_fork hook called. Falling back to unannounced state and spawning a new background agent thread."
|
7
|
+
|
8
|
+
# Reseed the random number generator for this
|
9
|
+
# new thread.
|
10
|
+
srand
|
11
|
+
|
12
|
+
transition_to(:unannounced)
|
13
|
+
|
14
|
+
setup
|
15
|
+
spawn_background_thread
|
16
|
+
end
|
17
|
+
|
18
|
+
def before_resque_fork
|
19
|
+
::Instana.logger.debug "before_resque_fork hook called. pid/ppid: #{Process.pid}/#{Process.ppid}"
|
20
|
+
@is_resque_worker = true
|
21
|
+
end
|
22
|
+
|
23
|
+
def after_resque_fork
|
24
|
+
::Instana.logger.debug "after_resque_fork hook called. pid/ppid: #{Process.pid}/#{Process.ppid}"
|
25
|
+
|
26
|
+
# Reseed the random number generator for this
|
27
|
+
# new thread.
|
28
|
+
srand
|
29
|
+
|
30
|
+
::Instana.config[:metrics][:enabled] = false
|
31
|
+
|
32
|
+
@process[:pid] = Process.pid
|
33
|
+
|
34
|
+
setup
|
35
|
+
spawn_background_thread
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module AgentTasks
|
2
|
+
# When request(s) are received by the host agent, it is sent here
|
3
|
+
# for handling & processing.
|
4
|
+
#
|
5
|
+
# @param json_string [String] the requests from the host agent
|
6
|
+
#
|
7
|
+
def handle_agent_tasks(json_string)
|
8
|
+
tasks = Oj.load(json_string)
|
9
|
+
|
10
|
+
if tasks.is_a?(Hash)
|
11
|
+
process_agent_task(tasks)
|
12
|
+
elsif tasks.is_a?(Array)
|
13
|
+
tasks.each do |t|
|
14
|
+
process_agent_task(t)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Process a task sent from the host agent.
|
20
|
+
#
|
21
|
+
# @param task [String] the request json from the host agent
|
22
|
+
#
|
23
|
+
def process_agent_task(task)
|
24
|
+
if task.key?("action")
|
25
|
+
if task["action"] == "ruby.source"
|
26
|
+
payload = ::Instana::Util.get_rb_source(task["args"]["file"])
|
27
|
+
else
|
28
|
+
payload = { :error => "Unrecognized action: #{task["action"]}. An newer Instana gem may be required for this. Current version: #{::Instana::VERSION}" }
|
29
|
+
end
|
30
|
+
else
|
31
|
+
payload = { :error => "Instana Ruby: No action specified in request." }
|
32
|
+
end
|
33
|
+
|
34
|
+
path = "com.instana.plugin.ruby/response.#{@process[:report_pid]}?messageId=#{URI.encode(task['messageId'])}"
|
35
|
+
uri = URI.parse("http://#{@discovered[:agent_host]}:#{@discovered[:agent_port]}/#{path}")
|
36
|
+
req = Net::HTTP::Post.new(uri)
|
37
|
+
req.body = Oj.dump(payload)
|
38
|
+
::Instana.logger.debug "Responding to agent request: #{req.inspect}"
|
39
|
+
make_host_agent_request(req)
|
40
|
+
|
41
|
+
rescue StandardError => e
|
42
|
+
Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
43
|
+
Instana.logger.debug e.backtrace.join("\r\n")
|
44
|
+
end
|
45
|
+
end
|
data/lib/instana/config.rb
CHANGED
@@ -49,12 +49,14 @@ module Instana
|
|
49
49
|
@config[:active_record] = { :enabled => true }
|
50
50
|
@config[:dalli] = { :enabled => true }
|
51
51
|
@config[:excon] = { :enabled => true }
|
52
|
+
@config[:grpc] = { :enabled => true }
|
52
53
|
@config[:nethttp] = { :enabled => true }
|
54
|
+
@config[:redis] = { :enabled => true }
|
55
|
+
@config[:'resque-client'] = { :enabled => true }
|
56
|
+
@config[:'resque-worker'] = { :enabled => true }
|
53
57
|
@config[:'rest-client'] = { :enabled => true }
|
54
|
-
@config[:grpc] = { :enabled => true }
|
55
58
|
@config[:'sidekiq-client'] = { :enabled => true }
|
56
59
|
@config[:'sidekiq-worker'] = { :enabled => true }
|
57
|
-
@config[:redis] = { :enabled => true }
|
58
60
|
end
|
59
61
|
|
60
62
|
def [](key)
|
@@ -1,26 +1,40 @@
|
|
1
1
|
require "instana/rack"
|
2
2
|
|
3
3
|
if defined?(::Rails)
|
4
|
-
# In Rails, let's use the Rails logger
|
5
|
-
::Instana.logger = ::Rails.logger if ::Rails.logger
|
6
4
|
|
7
5
|
if ::Rails::VERSION::MAJOR < 3
|
8
6
|
::Rails.configuration.after_initialize do
|
9
|
-
|
10
|
-
::Rails.
|
7
|
+
# In Rails, let's use the Rails logger
|
8
|
+
::Instana.logger = ::Rails.logger if ::Rails.logger
|
9
|
+
|
10
|
+
if ::Instana.config[:tracing][:enabled]
|
11
|
+
::Instana.logger.info "Instrumenting Rack"
|
12
|
+
::Rails.configuration.middleware.insert 0, ::Instana::Rack
|
13
|
+
else
|
14
|
+
::Instana.logger.info "Rack: Tracing disabled via config. Not enabling middleware."
|
15
|
+
end
|
11
16
|
end
|
12
17
|
else
|
13
18
|
module ::Instana
|
14
19
|
class Railtie < ::Rails::Railtie
|
15
20
|
initializer 'instana.rack' do |app|
|
16
|
-
|
17
|
-
|
21
|
+
# In Rails, let's use the Rails logger
|
22
|
+
::Instana.logger = ::Rails.logger if ::Rails.logger
|
23
|
+
|
24
|
+
if ::Instana.config[:tracing][:enabled]
|
25
|
+
::Instana.logger.info "Instrumenting Rack"
|
26
|
+
app.config.middleware.insert 0, ::Instana::Rack
|
27
|
+
else
|
28
|
+
::Instana.logger.info "Rack: Tracing disabled via config. Not enabling middleware."
|
29
|
+
end
|
18
30
|
end
|
19
31
|
|
20
|
-
config
|
21
|
-
|
22
|
-
|
23
|
-
|
32
|
+
if ::Instana.config[:tracing][:enabled]
|
33
|
+
config.after_initialize do
|
34
|
+
require "instana/frameworks/instrumentation/active_record"
|
35
|
+
require "instana/frameworks/instrumentation/action_controller"
|
36
|
+
require "instana/frameworks/instrumentation/action_view"
|
37
|
+
end
|
24
38
|
end
|
25
39
|
end
|
26
40
|
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Instana
|
4
|
+
module Instrumentation
|
5
|
+
module ResqueClient
|
6
|
+
def self.included(klass)
|
7
|
+
klass.send :extend, ::Resque
|
8
|
+
::Instana::Util.method_alias(klass, :enqueue)
|
9
|
+
::Instana::Util.method_alias(klass, :enqueue_to)
|
10
|
+
::Instana::Util.method_alias(klass, :dequeue)
|
11
|
+
end
|
12
|
+
|
13
|
+
def collect_kvs(op, klass, args)
|
14
|
+
kvs = {}
|
15
|
+
|
16
|
+
begin
|
17
|
+
kvs[:job] = klass.to_s
|
18
|
+
kvs[:queue] = klass.instance_variable_get(:@queue)
|
19
|
+
rescue => e
|
20
|
+
Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
21
|
+
end
|
22
|
+
|
23
|
+
{ :'resque-client' => kvs }
|
24
|
+
end
|
25
|
+
|
26
|
+
def enqueue_with_instana(klass, *args)
|
27
|
+
if Instana.tracer.tracing?
|
28
|
+
kvs = collect_kvs(:enqueue, klass, args)
|
29
|
+
|
30
|
+
Instana.tracer.trace(:'resque-client', kvs) do
|
31
|
+
enqueue_without_instana(klass, *args)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
enqueue_without_instana(klass, *args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def enqueue_to_with_instana(queue, klass, *args)
|
39
|
+
if Instana.tracer.tracing? && !Instana.tracer.tracing_span?(:'resque-client')
|
40
|
+
kvs = collect_kvs(:enqueue_to, klass, args)
|
41
|
+
kvs[:Queue] = queue.to_s if queue
|
42
|
+
|
43
|
+
Instana.tracer.trace(:'resque-client', kvs) do
|
44
|
+
enqueue_to_without_instana(queue, klass, *args)
|
45
|
+
end
|
46
|
+
else
|
47
|
+
enqueue_to_without_instana(queue, klass, *args)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def dequeue_with_instana(klass, *args)
|
52
|
+
if Instana.tracer.tracing?
|
53
|
+
kvs = collect_kvs(:dequeue, klass, args)
|
54
|
+
|
55
|
+
Instana.tracer.trace(:'resque-client', kvs) do
|
56
|
+
dequeue_without_instana(klass, *args)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
dequeue_without_instana(klass, *args)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
module ResqueWorker
|
65
|
+
def self.included(klass)
|
66
|
+
::Instana::Util.method_alias(klass, :perform)
|
67
|
+
end
|
68
|
+
|
69
|
+
def perform_with_instana(job)
|
70
|
+
kvs = {}
|
71
|
+
|
72
|
+
begin
|
73
|
+
kvs[:job] = job.payload['class'].to_s
|
74
|
+
kvs[:queue] = job.queue
|
75
|
+
rescue => e
|
76
|
+
::Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if Instana::Config[:verbose]
|
77
|
+
end
|
78
|
+
|
79
|
+
Instana.tracer.start_or_continue_trace(:'resque-worker', { :'resque-worker' => kvs }) do
|
80
|
+
perform_without_instana(job)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
module ResqueJob
|
86
|
+
def self.included(klass)
|
87
|
+
::Instana::Util.method_alias(klass, :fail)
|
88
|
+
end
|
89
|
+
|
90
|
+
def fail_with_instana(exception)
|
91
|
+
if Instana.tracer.tracing?
|
92
|
+
::Instana.tracer.log_info(:'resque-worker' => { :error => "#{exception.class}: #{exception}"})
|
93
|
+
::Instana.tracer.log_error(exception)
|
94
|
+
end
|
95
|
+
rescue Exception => e
|
96
|
+
::Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if Instana::Config[:verbose]
|
97
|
+
ensure
|
98
|
+
fail_without_instana(exception)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
if defined?(::Resque) && RUBY_VERSION >= '1.9.3'
|
105
|
+
|
106
|
+
if ::Instana.config[:'resque-client'][:enabled]
|
107
|
+
::Instana.logger.info 'Instrumenting Resque Client'
|
108
|
+
::Instana::Util.send_include(::Resque, ::Instana::Instrumentation::ResqueClient)
|
109
|
+
end
|
110
|
+
|
111
|
+
if ::Instana.config[:'resque-worker'][:enabled]
|
112
|
+
::Instana.logger.info 'Instrumenting Resque Worker'
|
113
|
+
|
114
|
+
::Instana::Util.send_include(::Resque::Worker, ::Instana::Instrumentation::ResqueWorker)
|
115
|
+
::Instana::Util.send_include(::Resque::Job, ::Instana::Instrumentation::ResqueJob)
|
116
|
+
|
117
|
+
::Resque.before_fork do |job|
|
118
|
+
::Instana.agent.before_resque_fork
|
119
|
+
end
|
120
|
+
::Resque.after_fork do |job|
|
121
|
+
::Instana.agent.after_resque_fork
|
122
|
+
end
|
123
|
+
|
124
|
+
# Set this so we assure that any remaining collected traces are reported at_exit
|
125
|
+
ENV['RUN_AT_EXIT_HOOKS'] = "1"
|
126
|
+
end
|
127
|
+
end
|
data/lib/instana/tracing/span.rb
CHANGED
@@ -2,9 +2,11 @@ module Instana
|
|
2
2
|
class Span
|
3
3
|
REGISTERED_SPANS = [ :actioncontroller, :actionview, :activerecord, :excon,
|
4
4
|
:memcache, :'net-http', :rack, :render, :'rpc-client',
|
5
|
-
:'rpc-server', :'sidekiq-client', :'sidekiq-worker',
|
6
|
-
|
7
|
-
|
5
|
+
:'rpc-server', :'sidekiq-client', :'sidekiq-worker',
|
6
|
+
:redis, :'resque-client', :'resque-worker' ].freeze
|
7
|
+
ENTRY_SPANS = [ :rack, :'resque-worker', :'rpc-server', :'sidekiq-worker' ].freeze
|
8
|
+
EXIT_SPANS = [ :activerecord, :excon, :'net-http', :'resque-client',
|
9
|
+
:'rpc-client', :'sidekiq-client', :redis ].freeze
|
8
10
|
HTTP_SPANS = [ :rack, :excon, :'net-http' ].freeze
|
9
11
|
|
10
12
|
attr_accessor :parent
|
data/lib/instana/util.rb
CHANGED
@@ -160,16 +160,19 @@ module Instana
|
|
160
160
|
#
|
161
161
|
def get_app_name
|
162
162
|
if ENV.key?('INSTANA_SERVICE_NAME')
|
163
|
-
|
163
|
+
return ENV['INSTANA_SERVICE_NAME']
|
164
|
+
end
|
164
165
|
|
165
|
-
elsif defined?(::RailsLts) || defined?(::Rails)
|
166
|
-
name = Rails.application.class.to_s.split('::')[0]
|
167
166
|
|
168
|
-
|
169
|
-
|
167
|
+
if defined?(::Resque) && ($0 =~ /resque-#{Resque::Version}/)
|
168
|
+
return "Resque Worker"
|
169
|
+
end
|
170
|
+
|
171
|
+
if defined?(::RailsLts) || defined?(::Rails)
|
172
|
+
return Rails.application.class.to_s.split('::')[0]
|
170
173
|
end
|
171
174
|
|
172
|
-
return
|
175
|
+
return File.basename($0)
|
173
176
|
rescue Exception => e
|
174
177
|
Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
175
178
|
Instana.logger.debug e.backtrace.join("\r\n")
|
data/lib/instana/version.rb
CHANGED
data/test/agent/agent_test.rb
CHANGED
@@ -7,7 +7,7 @@ class AgentTest < Minitest::Test
|
|
7
7
|
def test_agent_host_detection
|
8
8
|
url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/"
|
9
9
|
stub_request(:get, url)
|
10
|
-
assert_equal true, ::Instana.agent.
|
10
|
+
assert_equal true, ::Instana.agent.host_agent_available?
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_successful_discovery
|
@@ -57,7 +57,7 @@ class AgentTest < Minitest::Test
|
|
57
57
|
stub_request(:get, localhost_url).to_raise(Errno::ECONNREFUSED)
|
58
58
|
docker_url = "http://#{::Instana.agent.instance_variable_get(:@default_gateway)}:#{::Instana.config[:agent_port]}/"
|
59
59
|
stub_request(:get, docker_url).to_timeout
|
60
|
-
assert_equal false, ::Instana.agent.
|
60
|
+
assert_equal false, ::Instana.agent.host_agent_available?
|
61
61
|
end
|
62
62
|
|
63
63
|
def test_announce_sensor
|
@@ -137,6 +137,6 @@ class AgentTest < Minitest::Test
|
|
137
137
|
stub_request(:get, localhost_url).to_timeout
|
138
138
|
docker_url = "http://#{::Instana.agent.instance_variable_get(:@default_gateway)}:#{::Instana.config[:agent_port]}/"
|
139
139
|
stub_request(:get, docker_url).to_timeout
|
140
|
-
assert_equal false, ::Instana.agent.
|
140
|
+
assert_equal false, ::Instana.agent.host_agent_available?
|
141
141
|
end
|
142
142
|
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require_relative "../jobs/resque_fast_job"
|
3
|
+
require_relative "../jobs/resque_error_job"
|
4
|
+
require 'resque'
|
5
|
+
|
6
|
+
if ENV.key?('REDIS_URL')
|
7
|
+
::Resque.redis = ENV['REDIS_URL']
|
8
|
+
else
|
9
|
+
::Resque.redis = 'localhost:6379'
|
10
|
+
end
|
11
|
+
|
12
|
+
class ResqueClientTest < Minitest::Test
|
13
|
+
def setup
|
14
|
+
clear_all!
|
15
|
+
ENV['FORK_PER_JOB'] = 'false'
|
16
|
+
Resque.redis.redis.flushall
|
17
|
+
@worker = Resque::Worker.new(:critical)
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_enqueue
|
24
|
+
::Instana.tracer.start_or_continue_trace('resque-client_test') do
|
25
|
+
::Resque.enqueue(FastJob)
|
26
|
+
end
|
27
|
+
|
28
|
+
traces = Instana.processor.queued_traces
|
29
|
+
assert_equal 1, traces.count
|
30
|
+
|
31
|
+
spans = traces[0].spans.to_a
|
32
|
+
assert_equal 3, spans.count
|
33
|
+
|
34
|
+
assert_equal :'resque-client_test', spans[0][:data][:sdk][:name]
|
35
|
+
|
36
|
+
assert_equal :"resque-client", spans[1][:n]
|
37
|
+
assert_equal "FastJob", spans[1][:data][:'resque-client'][:job]
|
38
|
+
assert_equal :critical, spans[1][:data][:'resque-client'][:queue]
|
39
|
+
assert_equal false, spans[1][:data][:'resque-client'].key?(:error)
|
40
|
+
|
41
|
+
assert_equal :redis, spans[2][:n]
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_enqueue_to
|
45
|
+
::Instana.tracer.start_or_continue_trace('resque-client_test') do
|
46
|
+
::Resque.enqueue_to(:critical, FastJob)
|
47
|
+
end
|
48
|
+
|
49
|
+
traces = Instana.processor.queued_traces
|
50
|
+
assert_equal 1, traces.count
|
51
|
+
|
52
|
+
spans = traces[0].spans.to_a
|
53
|
+
assert_equal 3, spans.count
|
54
|
+
|
55
|
+
assert_equal :'resque-client_test', spans[0][:data][:sdk][:name]
|
56
|
+
assert_equal :"resque-client", spans[1][:n]
|
57
|
+
assert_equal "FastJob", spans[1][:data][:'resque-client'][:job]
|
58
|
+
assert_equal :critical, spans[1][:data][:'resque-client'][:queue]
|
59
|
+
assert_equal false, spans[1][:data][:'resque-client'].key?(:error)
|
60
|
+
assert_equal :redis, spans[2][:n]
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_dequeue
|
64
|
+
::Instana.tracer.start_or_continue_trace('resque-client_test', '', {}) do
|
65
|
+
::Resque.dequeue(FastJob, { :generate => :farfalla })
|
66
|
+
end
|
67
|
+
|
68
|
+
traces = Instana.processor.queued_traces
|
69
|
+
assert_equal 1, traces.count
|
70
|
+
|
71
|
+
spans = traces[0].spans.to_a
|
72
|
+
assert_equal 3, spans.count
|
73
|
+
|
74
|
+
assert_equal :'resque-client_test', spans[0][:data][:sdk][:name]
|
75
|
+
assert_equal :"resque-client", spans[1][:n]
|
76
|
+
assert_equal "FastJob", spans[1][:data][:'resque-client'][:job]
|
77
|
+
assert_equal :critical, spans[1][:data][:'resque-client'][:queue]
|
78
|
+
assert_equal false, spans[1][:data][:'resque-client'].key?(:error)
|
79
|
+
assert_equal :redis, spans[2][:n]
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_worker_job
|
83
|
+
Resque::Job.create(:critical, FastJob)
|
84
|
+
@worker.work(0)
|
85
|
+
|
86
|
+
traces = Instana.processor.queued_traces
|
87
|
+
assert_equal 1, traces.count
|
88
|
+
|
89
|
+
spans = traces[0].spans.to_a
|
90
|
+
assert_equal 3, spans.count
|
91
|
+
|
92
|
+
resque_span = spans[0]
|
93
|
+
redis1_span = spans[1]
|
94
|
+
redis2_span = spans[2]
|
95
|
+
|
96
|
+
assert_equal :'resque-worker', resque_span[:n]
|
97
|
+
assert_equal false, resque_span.key?(:error)
|
98
|
+
assert_equal false, resque_span.key?(:ec)
|
99
|
+
assert_equal "FastJob", resque_span[:data][:'resque-worker'][:job]
|
100
|
+
assert_equal "critical", resque_span[:data][:'resque-worker'][:queue]
|
101
|
+
assert_equal false, resque_span[:data][:'resque-worker'].key?(:error)
|
102
|
+
|
103
|
+
assert_equal :redis, redis1_span[:n]
|
104
|
+
assert_equal "SET", redis1_span[:data][:redis][:command]
|
105
|
+
assert_equal :redis, redis2_span[:n]
|
106
|
+
assert_equal "SET", redis2_span[:data][:redis][:command]
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_worker_error_job
|
110
|
+
Resque::Job.create(:critical, ErrorJob)
|
111
|
+
@worker.work(0)
|
112
|
+
|
113
|
+
traces = Instana.processor.queued_traces
|
114
|
+
assert_equal 1, traces.count
|
115
|
+
|
116
|
+
spans = traces[0].spans.to_a
|
117
|
+
resque_span = spans[0]
|
118
|
+
assert_equal 5, spans.count
|
119
|
+
|
120
|
+
assert_equal :'resque-worker', resque_span[:n]
|
121
|
+
assert_equal true, resque_span.key?(:error)
|
122
|
+
assert_equal 1, resque_span[:ec]
|
123
|
+
assert_equal "ErrorJob", resque_span[:data][:'resque-worker'][:job]
|
124
|
+
assert_equal "critical", resque_span[:data][:'resque-worker'][:queue]
|
125
|
+
assert_equal "Exception: Silly Rabbit, Trix are for kids.", resque_span[:data][:'resque-worker'][:error]
|
126
|
+
assert_equal Array, resque_span[:stack].class
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "redis"
|
2
|
+
require "net/http"
|
3
|
+
|
4
|
+
class ErrorJob
|
5
|
+
@queue = :critical
|
6
|
+
|
7
|
+
def self.perform
|
8
|
+
redis = Redis.new(url: ENV['REDIS_URL'])
|
9
|
+
|
10
|
+
dt = Time.now
|
11
|
+
redis.set('ts', dt)
|
12
|
+
|
13
|
+
raise Exception.new("Silly Rabbit, Trix are for kids.")
|
14
|
+
redis.set(:nb_id, 2)
|
15
|
+
end
|
16
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -14,12 +14,16 @@ require 'webmock/minitest'
|
|
14
14
|
require "instana/test"
|
15
15
|
::Instana::Test.setup_environment
|
16
16
|
|
17
|
+
# Webmock: Whitelist local IPs
|
18
|
+
whitelist = ['127.0.0.1', 'localhost', '172.17.0.1', '172.0.12.100']
|
19
|
+
allowed_sites = lambda{|uri|
|
20
|
+
whitelist.include?(uri.host)
|
21
|
+
}
|
22
|
+
::WebMock.disable_net_connect!(allow: allowed_sites)
|
23
|
+
|
17
24
|
# Boot background webservers to test against.
|
18
25
|
require "./test/servers/rackapp_6511"
|
19
26
|
|
20
|
-
# Allow localhost calls to the internal rails servers
|
21
|
-
::WebMock.disable_net_connect!(allow_localhost: true)
|
22
|
-
|
23
27
|
case File.basename(ENV['BUNDLE_GEMFILE'])
|
24
28
|
when /rails50|rails42|rails32/
|
25
29
|
require './test/servers/rails_3205'
|
data/test/tracing/custom_test.rb
CHANGED
@@ -10,7 +10,7 @@ class CustomTracingTest < Minitest::Test
|
|
10
10
|
assert_equal true, ::Instana.tracer.tracing?
|
11
11
|
::Instana.tracer.log_info({:info_logged => 1})
|
12
12
|
# End tracing
|
13
|
-
::Instana.tracer.log_end(:
|
13
|
+
::Instana.tracer.log_end(:custom_trace, {:close_one => 1})
|
14
14
|
assert_equal false, ::Instana.tracer.tracing?
|
15
15
|
|
16
16
|
traces = ::Instana.processor.queued_traces
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instana
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0.daftrabbit
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Giacomo Lombardo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -201,6 +201,9 @@ files:
|
|
201
201
|
- instana.gemspec
|
202
202
|
- lib/instana.rb
|
203
203
|
- lib/instana/agent.rb
|
204
|
+
- lib/instana/agent/helpers.rb
|
205
|
+
- lib/instana/agent/hooks.rb
|
206
|
+
- lib/instana/agent/tasks.rb
|
204
207
|
- lib/instana/base.rb
|
205
208
|
- lib/instana/collector.rb
|
206
209
|
- lib/instana/collectors/gc.rb
|
@@ -228,6 +231,7 @@ files:
|
|
228
231
|
- lib/instana/instrumentation/net-http.rb
|
229
232
|
- lib/instana/instrumentation/rack.rb
|
230
233
|
- lib/instana/instrumentation/redis.rb
|
234
|
+
- lib/instana/instrumentation/resque.rb
|
231
235
|
- lib/instana/instrumentation/rest-client.rb
|
232
236
|
- lib/instana/instrumentation/sidekiq-client.rb
|
233
237
|
- lib/instana/instrumentation/sidekiq-worker.rb
|
@@ -272,9 +276,12 @@ files:
|
|
272
276
|
- test/instrumentation/grpc_test.rb
|
273
277
|
- test/instrumentation/net-http_test.rb
|
274
278
|
- test/instrumentation/redis_test.rb
|
279
|
+
- test/instrumentation/resque_test.rb
|
275
280
|
- test/instrumentation/rest-client_test.rb
|
276
281
|
- test/instrumentation/sidekiq-client_test.rb
|
277
282
|
- test/instrumentation/sidekiq-worker_test.rb
|
283
|
+
- test/jobs/resque_error_job.rb
|
284
|
+
- test/jobs/resque_fast_job.rb
|
278
285
|
- test/jobs/sidekiq_job_1.rb
|
279
286
|
- test/jobs/sidekiq_job_2.rb
|
280
287
|
- test/models/block.rb
|
@@ -305,9 +312,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
305
312
|
version: '2.1'
|
306
313
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
307
314
|
requirements:
|
308
|
-
- - "
|
315
|
+
- - ">"
|
309
316
|
- !ruby/object:Gem::Version
|
310
|
-
version:
|
317
|
+
version: 1.3.1
|
311
318
|
requirements: []
|
312
319
|
rubyforge_project:
|
313
320
|
rubygems_version: 2.7.6
|
@@ -340,9 +347,12 @@ test_files:
|
|
340
347
|
- test/instrumentation/grpc_test.rb
|
341
348
|
- test/instrumentation/net-http_test.rb
|
342
349
|
- test/instrumentation/redis_test.rb
|
350
|
+
- test/instrumentation/resque_test.rb
|
343
351
|
- test/instrumentation/rest-client_test.rb
|
344
352
|
- test/instrumentation/sidekiq-client_test.rb
|
345
353
|
- test/instrumentation/sidekiq-worker_test.rb
|
354
|
+
- test/jobs/resque_error_job.rb
|
355
|
+
- test/jobs/resque_fast_job.rb
|
346
356
|
- test/jobs/sidekiq_job_1.rb
|
347
357
|
- test/jobs/sidekiq_job_2.rb
|
348
358
|
- test/models/block.rb
|