instana 1.10.1-java

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.
Files changed (125) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +23 -0
  3. data/.gitignore +16 -0
  4. data/.rubocop.yml +1156 -0
  5. data/.travis.yml +43 -0
  6. data/Configuration.md +149 -0
  7. data/Dockerfile +13 -0
  8. data/Gemfile +41 -0
  9. data/LICENSE +21 -0
  10. data/README.md +102 -0
  11. data/Rakefile +56 -0
  12. data/Tracing.md +145 -0
  13. data/Troubleshooting.md +32 -0
  14. data/benchmarks/Gemfile +7 -0
  15. data/benchmarks/id_generation.rb +12 -0
  16. data/benchmarks/opentracing.rb +26 -0
  17. data/benchmarks/rack_vanilla_vs_traced.rb +80 -0
  18. data/benchmarks/stackprof_rack_tracing.rb +77 -0
  19. data/benchmarks/time_processing.rb +12 -0
  20. data/bin/console +7 -0
  21. data/bin/setup +8 -0
  22. data/examples/opentracing.rb +31 -0
  23. data/examples/tracing.rb +80 -0
  24. data/gemfiles/libraries.gemfile +71 -0
  25. data/gemfiles/rails32.gemfile +51 -0
  26. data/gemfiles/rails42.gemfile +50 -0
  27. data/gemfiles/rails50.gemfile +52 -0
  28. data/instana.gemspec +46 -0
  29. data/lib/instana.rb +12 -0
  30. data/lib/instana/agent.rb +441 -0
  31. data/lib/instana/agent/helpers.rb +61 -0
  32. data/lib/instana/agent/hooks.rb +37 -0
  33. data/lib/instana/agent/tasks.rb +48 -0
  34. data/lib/instana/base.rb +54 -0
  35. data/lib/instana/collector.rb +116 -0
  36. data/lib/instana/collectors/gc.rb +57 -0
  37. data/lib/instana/collectors/memory.rb +34 -0
  38. data/lib/instana/collectors/thread.rb +30 -0
  39. data/lib/instana/config.rb +79 -0
  40. data/lib/instana/eum/eum-test.js.erb +16 -0
  41. data/lib/instana/eum/eum.js.erb +14 -0
  42. data/lib/instana/frameworks/cuba.rb +6 -0
  43. data/lib/instana/frameworks/instrumentation/abstract_mysql_adapter.rb +58 -0
  44. data/lib/instana/frameworks/instrumentation/action_controller.rb +183 -0
  45. data/lib/instana/frameworks/instrumentation/action_view.rb +43 -0
  46. data/lib/instana/frameworks/instrumentation/active_record.rb +27 -0
  47. data/lib/instana/frameworks/instrumentation/mysql2_adapter.rb +81 -0
  48. data/lib/instana/frameworks/instrumentation/mysql_adapter.rb +56 -0
  49. data/lib/instana/frameworks/instrumentation/postgresql_adapter.rb +71 -0
  50. data/lib/instana/frameworks/rails.rb +42 -0
  51. data/lib/instana/frameworks/roda.rb +6 -0
  52. data/lib/instana/frameworks/sinatra.rb +9 -0
  53. data/lib/instana/helpers.rb +40 -0
  54. data/lib/instana/instrumentation.rb +21 -0
  55. data/lib/instana/instrumentation/dalli.rb +78 -0
  56. data/lib/instana/instrumentation/excon.rb +74 -0
  57. data/lib/instana/instrumentation/grpc.rb +84 -0
  58. data/lib/instana/instrumentation/net-http.rb +66 -0
  59. data/lib/instana/instrumentation/rack.rb +77 -0
  60. data/lib/instana/instrumentation/redis.rb +82 -0
  61. data/lib/instana/instrumentation/resque.rb +131 -0
  62. data/lib/instana/instrumentation/rest-client.rb +34 -0
  63. data/lib/instana/instrumentation/sidekiq-client.rb +45 -0
  64. data/lib/instana/instrumentation/sidekiq-worker.rb +54 -0
  65. data/lib/instana/opentracing/carrier.rb +4 -0
  66. data/lib/instana/opentracing/tracer.rb +18 -0
  67. data/lib/instana/rack.rb +10 -0
  68. data/lib/instana/setup.rb +36 -0
  69. data/lib/instana/test.rb +40 -0
  70. data/lib/instana/thread_local.rb +15 -0
  71. data/lib/instana/tracer.rb +392 -0
  72. data/lib/instana/tracing/processor.rb +92 -0
  73. data/lib/instana/tracing/span.rb +401 -0
  74. data/lib/instana/tracing/span_context.rb +33 -0
  75. data/lib/instana/util.rb +261 -0
  76. data/lib/instana/version.rb +4 -0
  77. data/lib/oj_check.rb +16 -0
  78. data/lib/opentracing.rb +6 -0
  79. data/test/agent/agent_test.rb +143 -0
  80. data/test/apps/cuba.rb +15 -0
  81. data/test/apps/grpc_server.rb +81 -0
  82. data/test/apps/roda.rb +10 -0
  83. data/test/apps/sinatra.rb +5 -0
  84. data/test/benchmarks/bench_id_generation.rb +12 -0
  85. data/test/benchmarks/bench_opentracing.rb +13 -0
  86. data/test/config_test.rb +37 -0
  87. data/test/frameworks/cuba_test.rb +44 -0
  88. data/test/frameworks/rack_test.rb +167 -0
  89. data/test/frameworks/rails/actioncontroller_test.rb +93 -0
  90. data/test/frameworks/rails/actionview3_test.rb +255 -0
  91. data/test/frameworks/rails/actionview4_test.rb +254 -0
  92. data/test/frameworks/rails/actionview5_test.rb +221 -0
  93. data/test/frameworks/rails/activerecord3_test.rb +134 -0
  94. data/test/frameworks/rails/activerecord4_test.rb +134 -0
  95. data/test/frameworks/rails/activerecord5_test.rb +87 -0
  96. data/test/frameworks/roda_test.rb +44 -0
  97. data/test/frameworks/sinatra_test.rb +44 -0
  98. data/test/instana_test.rb +27 -0
  99. data/test/instrumentation/dalli_test.rb +253 -0
  100. data/test/instrumentation/excon_test.rb +147 -0
  101. data/test/instrumentation/grpc_test.rb +377 -0
  102. data/test/instrumentation/net-http_test.rb +160 -0
  103. data/test/instrumentation/redis_test.rb +119 -0
  104. data/test/instrumentation/resque_test.rb +128 -0
  105. data/test/instrumentation/rest-client_test.rb +55 -0
  106. data/test/instrumentation/sidekiq-client_test.rb +125 -0
  107. data/test/instrumentation/sidekiq-worker_test.rb +173 -0
  108. data/test/jobs/resque_error_job.rb +22 -0
  109. data/test/jobs/resque_fast_job.rb +20 -0
  110. data/test/jobs/sidekiq_job_1.rb +6 -0
  111. data/test/jobs/sidekiq_job_2.rb +7 -0
  112. data/test/models/block.rb +18 -0
  113. data/test/servers/grpc_50051.rb +20 -0
  114. data/test/servers/helpers/sidekiq_worker_initializer.rb +27 -0
  115. data/test/servers/rackapp_6511.rb +25 -0
  116. data/test/servers/rails_3205.rb +167 -0
  117. data/test/servers/sidekiq/worker.rb +27 -0
  118. data/test/test_helper.rb +145 -0
  119. data/test/tracing/custom_test.rb +158 -0
  120. data/test/tracing/id_management_test.rb +130 -0
  121. data/test/tracing/opentracing_test.rb +335 -0
  122. data/test/tracing/trace_test.rb +67 -0
  123. data/test/tracing/tracer_async_test.rb +198 -0
  124. data/test/tracing/tracer_test.rb +223 -0
  125. metadata +327 -0
@@ -0,0 +1,66 @@
1
+ require 'net/http'
2
+
3
+ if defined?(::Net::HTTP) && ::Instana.config[:nethttp][:enabled]
4
+ Net::HTTP.class_eval {
5
+
6
+ def request_with_instana(*args, &block)
7
+ if !Instana.tracer.tracing? || !started?
8
+ do_skip = true
9
+ return request_without_instana(*args, &block)
10
+ end
11
+
12
+ ::Instana.tracer.log_entry(:'net-http')
13
+
14
+ # Send out the tracing context with the request
15
+ request = args[0]
16
+
17
+ # Set request headers; encode IDs as hexadecimal strings
18
+ t_context = ::Instana.tracer.context
19
+ request['X-Instana-T'] = t_context.trace_id_header
20
+ request['X-Instana-S'] = t_context.span_id_header
21
+
22
+ # Collect up KV info now in case any exception is raised
23
+ kv_payload = { :http => {} }
24
+ kv_payload[:http][:method] = request.method
25
+
26
+ if request.uri
27
+ kv_payload[:http][:url] = request.uri.to_s
28
+ else
29
+ if use_ssl?
30
+ kv_payload[:http][:url] = "https://#{@address}:#{@port}#{request.path}"
31
+ else
32
+ kv_payload[:http][:url] = "http://#{@address}:#{@port}#{request.path}"
33
+ end
34
+ end
35
+
36
+ # The core call
37
+ response = request_without_instana(*args, &block)
38
+
39
+ # Debug only check: Pickup response headers; convert back to base 10 integer and validate
40
+ if ENV.key?('INSTANA_DEBUG') && response.key?('X-Instana-T')
41
+ if ::Instana.tracer.trace_id != ::Instana::Util.header_to_id(response.header['X-Instana-T'])
42
+ ::Instana.logger.debug "#{Thread.current}: Trace ID mismatch on net/http response! ours: #{::Instana.tracer.trace_id} theirs: #{their_trace_id}"
43
+ end
44
+ end
45
+
46
+ kv_payload[:http][:status] = response.code
47
+ if response.code.to_i.between?(500, 511)
48
+ # Because of the 5xx response, we flag this span as errored but
49
+ # without a backtrace (no exception)
50
+ ::Instana.tracer.log_error(nil)
51
+ end
52
+
53
+ response
54
+ rescue => e
55
+ ::Instana.tracer.log_error(e)
56
+ raise
57
+ ensure
58
+ ::Instana.tracer.log_exit(:'net-http', kv_payload) unless do_skip
59
+ end
60
+
61
+ Instana.logger.info "Instrumenting Net::HTTP"
62
+
63
+ alias request_without_instana request
64
+ alias request request_with_instana
65
+ }
66
+ end
@@ -0,0 +1,77 @@
1
+ # Note: We really only need "cgi/util" here but Ruby 2.4.1 has an issue:
2
+ # https://bugs.ruby-lang.org/issues/13539
3
+ require "cgi"
4
+
5
+ module Instana
6
+ class Rack
7
+ def initialize(app)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ kvs = { :http => {} }
13
+ kvs[:http][:method] = env['REQUEST_METHOD']
14
+ kvs[:http][:url] = ::CGI.unescape(env['PATH_INFO'])
15
+
16
+ if env.key?('HTTP_HOST')
17
+ kvs[:http][:host] = env['HTTP_HOST']
18
+ elsif env.key?('SERVER_NAME')
19
+ kvs[:http][:host] = env['SERVER_NAME']
20
+ end
21
+
22
+ if ENV.key?('INSTANA_SERVICE_NAME')
23
+ kvs[:service] = ENV['INSTANA_SERVICE_NAME']
24
+ end
25
+
26
+ if ::Instana.agent.extra_headers
27
+ ::Instana.agent.extra_headers.each { |custom_header|
28
+ # Headers are available in this format: HTTP_X_CAPTURE_THIS
29
+ rack_header = 'HTTP_' + custom_header.upcase
30
+ rack_header.tr!('-', '_')
31
+ if env.key?(rack_header)
32
+ kvs["http.#{custom_header}"] = env[rack_header]
33
+ end
34
+ }
35
+ end
36
+
37
+ # Check incoming context
38
+ incoming_context = {}
39
+ if env.key?('HTTP_X_INSTANA_T')
40
+ incoming_context[:trace_id] = ::Instana::Util.header_to_id(env['HTTP_X_INSTANA_T'])
41
+ incoming_context[:span_id] = ::Instana::Util.header_to_id(env['HTTP_X_INSTANA_S']) if env.key?('HTTP_X_INSTANA_S')
42
+ incoming_context[:level] = env['HTTP_X_INSTANA_L'] if env.key?('HTTP_X_INSTANA_L')
43
+ end
44
+
45
+ ::Instana.tracer.log_start_or_continue(:rack, {}, incoming_context)
46
+
47
+ status, headers, response = @app.call(env)
48
+
49
+ if ::Instana.tracer.tracing?
50
+ kvs[:http][:status] = status
51
+
52
+ if !status.is_a?(Integer) || status.between?(500, 511)
53
+ # Because of the 5xx response, we flag this span as errored but
54
+ # without a backtrace (no exception)
55
+ ::Instana.tracer.log_error(nil)
56
+ end
57
+
58
+ # Save the IDs before the trace ends so we can place
59
+ # them in the response headers in the ensure block
60
+ trace_id = ::Instana.tracer.current_span.trace_id
61
+ span_id = ::Instana.tracer.current_span.id
62
+ end
63
+
64
+ [status, headers, response]
65
+ rescue Exception => e
66
+ ::Instana.tracer.log_error(e)
67
+ raise
68
+ ensure
69
+ if headers && ::Instana.tracer.tracing?
70
+ # Set reponse headers; encode as hex string
71
+ headers['X-Instana-T'] = ::Instana::Util.id_to_header(trace_id)
72
+ headers['X-Instana-S'] = ::Instana::Util.id_to_header(span_id)
73
+ end
74
+ ::Instana.tracer.log_end(:rack, kvs)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,82 @@
1
+ module Instana
2
+ module Instrumentation
3
+ class Redis
4
+ def self.get_host(client)
5
+ client.host
6
+ end
7
+
8
+ def self.get_port(client)
9
+ client.port
10
+ end
11
+
12
+ def self.pipeline_command(pipeline)
13
+ pipeline.is_a?(::Redis::Pipeline::Multi) ? 'MULTI' : 'PIPELINE'
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ if defined?(::Redis) && ::Instana.config[:redis][:enabled]
20
+ ::Redis::Client.class_eval do
21
+ def call_with_instana(*args, &block)
22
+ kv_payload = { redis: {} }
23
+
24
+ if !Instana.tracer.tracing?
25
+ return call_without_instana(*args, &block)
26
+ end
27
+
28
+ host = ::Instana::Instrumentation::Redis.get_host(self)
29
+ port = ::Instana::Instrumentation::Redis.get_port(self)
30
+ kv_payload[:redis] = {
31
+ connection: "#{host}:#{port}",
32
+ db: db,
33
+ command: args[0][0].to_s.upcase
34
+ }
35
+ ::Instana.tracer.log_entry(:redis, kv_payload)
36
+
37
+ call_without_instana(*args, &block)
38
+ rescue => e
39
+ kv_payload[:redis][:error] = true
40
+ ::Instana.tracer.log_info(kv_payload)
41
+ ::Instana.tracer.log_error(e)
42
+ raise
43
+ ensure
44
+ ::Instana.tracer.log_exit(:redis, {})
45
+ end
46
+
47
+ ::Instana.logger.info "Instrumenting Redis"
48
+
49
+ alias call_without_instana call
50
+ alias call call_with_instana
51
+
52
+ def call_pipeline_with_instana(*args, &block)
53
+ kv_payload = { redis: {} }
54
+
55
+ if !Instana.tracer.tracing?
56
+ return call_pipeline_without_instana(*args, &block)
57
+ end
58
+
59
+ pipeline = args.first
60
+ host = ::Instana::Instrumentation::Redis.get_host(self)
61
+ port = ::Instana::Instrumentation::Redis.get_port(self)
62
+ kv_payload[:redis] = {
63
+ connection: "#{host}:#{port}",
64
+ db: db,
65
+ command: ::Instana::Instrumentation::Redis.pipeline_command(pipeline)
66
+ }
67
+ ::Instana.tracer.log_entry(:redis, kv_payload)
68
+
69
+ call_pipeline_without_instana(*args, &block)
70
+ rescue => e
71
+ kv_payload[:redis][:error] = true
72
+ ::Instana.tracer.log_info(kv_payload)
73
+ ::Instana.tracer.log_error(e)
74
+ raise
75
+ ensure
76
+ ::Instana.tracer.log_exit(:redis, {})
77
+ end
78
+
79
+ alias call_pipeline_without_instana call_pipeline
80
+ alias call_pipeline call_pipeline_with_instana
81
+ end
82
+ end
@@ -0,0 +1,131 @@
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
+ kvs[:'resque-worker'] = {}
72
+
73
+ begin
74
+ if ENV.key?('INSTANA_SERVICE_NAME')
75
+ kvs[:service] = ENV['INSTANA_SERVICE_NAME']
76
+ end
77
+ kvs[:'resque-worker'][:job] = job.payload['class'].to_s
78
+ kvs[:'resque-worker'][:queue] = job.queue
79
+ rescue => e
80
+ ::Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" } if Instana::Config[:verbose]
81
+ end
82
+
83
+ Instana.tracer.start_or_continue_trace(:'resque-worker', kvs) do
84
+ perform_without_instana(job)
85
+ end
86
+ end
87
+ end
88
+
89
+ module ResqueJob
90
+ def self.included(klass)
91
+ ::Instana::Util.method_alias(klass, :fail)
92
+ end
93
+
94
+ def fail_with_instana(exception)
95
+ if Instana.tracer.tracing?
96
+ ::Instana.tracer.log_info(:'resque-worker' => { :error => "#{exception.class}: #{exception}"})
97
+ ::Instana.tracer.log_error(exception)
98
+ end
99
+ rescue Exception => e
100
+ ::Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" } if Instana::Config[:verbose]
101
+ ensure
102
+ fail_without_instana(exception)
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ if defined?(::Resque) && RUBY_VERSION >= '1.9.3'
109
+
110
+ if ::Instana.config[:'resque-client'][:enabled]
111
+ ::Instana.logger.info 'Instrumenting Resque Client'
112
+ ::Instana::Util.send_include(::Resque, ::Instana::Instrumentation::ResqueClient)
113
+ end
114
+
115
+ if ::Instana.config[:'resque-worker'][:enabled]
116
+ ::Instana.logger.info 'Instrumenting Resque Worker'
117
+
118
+ ::Instana::Util.send_include(::Resque::Worker, ::Instana::Instrumentation::ResqueWorker)
119
+ ::Instana::Util.send_include(::Resque::Job, ::Instana::Instrumentation::ResqueJob)
120
+
121
+ ::Resque.before_fork do |job|
122
+ ::Instana.agent.before_resque_fork
123
+ end
124
+ ::Resque.after_fork do |job|
125
+ ::Instana.agent.after_resque_fork
126
+ end
127
+
128
+ # Set this so we assure that any remaining collected traces are reported at_exit
129
+ ENV['RUN_AT_EXIT_HOOKS'] = "1"
130
+ end
131
+ end
@@ -0,0 +1,34 @@
1
+ module Instana
2
+ module Instrumentation
3
+ module RestClientRequest
4
+ def self.included(klass)
5
+ if klass.method_defined?(:execute)
6
+ klass.class_eval do
7
+ alias execute_without_instana execute
8
+ alias execute execute_with_instana
9
+ end
10
+ end
11
+ end
12
+
13
+ def execute_with_instana & block
14
+ # Since RestClient uses net/http under the covers, we just
15
+ # provide span visibility here. HTTP related KVs are reported
16
+ # in the Net::HTTP instrumentation
17
+ ::Instana.tracer.log_entry(:'rest-client')
18
+
19
+ execute_without_instana(&block)
20
+ rescue => e
21
+ ::Instana.tracer.log_error(e)
22
+ raise
23
+ ensure
24
+ ::Instana.tracer.log_exit(:'rest-client')
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+
31
+ if defined?(::RestClient::Request) && ::Instana.config[:'rest-client'][:enabled]
32
+ ::Instana.logger.info "Instrumenting RestClient"
33
+ ::RestClient::Request.send(:include, ::Instana::Instrumentation::RestClientRequest)
34
+ end
@@ -0,0 +1,45 @@
1
+ module Instana
2
+ module Instrumentation
3
+ class SidekiqClient
4
+ def call(worker_class, msg, queue, _redis_pool)
5
+ kv_payload = { :'sidekiq-client' => {} }
6
+ kv_payload[:'sidekiq-client'][:queue] = queue
7
+ kv_payload[:'sidekiq-client'][:job] = worker_class
8
+ kv_payload[:'sidekiq-client'][:retry] = msg['retry'].to_s
9
+ ::Instana.tracer.log_entry(:'sidekiq-client', kv_payload)
10
+
11
+ # Temporary until we move connection collection to redis
12
+ # instrumentation
13
+ Sidekiq.redis_pool.with do |client|
14
+ opts = client.respond_to?(:connection) ? client.connection : client.client.options
15
+ kv_payload[:'sidekiq-client'][:'redis-url'] = "#{opts[:host]}:#{opts[:port]}"
16
+ end
17
+
18
+ context = ::Instana.tracer.context
19
+ if context
20
+ msg['X-Instana-T'] = context.trace_id_header
21
+ msg['X-Instana-S'] = context.span_id_header
22
+ end
23
+
24
+ result = yield
25
+
26
+ kv_payload[:'sidekiq-client'][:job_id] = result['jid']
27
+ result
28
+ rescue => e
29
+ ::Instana.tracer.log_error(e)
30
+ raise
31
+ ensure
32
+ ::Instana.tracer.log_exit(:'sidekiq-client', kv_payload)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ if defined?(::Sidekiq) && ::Instana.config[:'sidekiq-client'][:enabled]
39
+ ::Sidekiq.configure_client do |cfg|
40
+ cfg.client_middleware do |chain|
41
+ ::Instana.logger.info "Instrumenting Sidekiq client"
42
+ chain.add ::Instana::Instrumentation::SidekiqClient
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,54 @@
1
+ module Instana
2
+ module Instrumentation
3
+ class SidekiqWorker
4
+ def call(_worker, msg, _queue)
5
+ kv_payload = { :'sidekiq-worker' => {} }
6
+ kv_payload[:'sidekiq-worker'][:job_id] = msg['jid']
7
+ kv_payload[:'sidekiq-worker'][:queue] = msg['queue']
8
+ kv_payload[:'sidekiq-worker'][:job] = msg['class']
9
+ kv_payload[:'sidekiq-worker'][:retry] = msg['retry'].to_s
10
+
11
+ # Temporary until we move connection collection to redis
12
+ # instrumentation
13
+ Sidekiq.redis_pool.with do |client|
14
+ opts = client.respond_to?(:connection) ? client.connection : client.client.options
15
+ kv_payload[:'sidekiq-worker'][:'redis-url'] = "#{opts[:host]}:#{opts[:port]}"
16
+ end
17
+
18
+ if ENV.key?('INSTANA_SERVICE_NAME')
19
+ kv_payload[:service] = ENV['INSTANA_SERVICE_NAME']
20
+ end
21
+
22
+ context = {}
23
+ if msg.key?('X-Instana-T')
24
+ trace_id = msg.delete('X-Instana-T')
25
+ span_id = msg.delete('X-Instana-S')
26
+ context[:trace_id] = ::Instana::Util.header_to_id(trace_id)
27
+ context[:span_id] = ::Instana::Util.header_to_id(span_id) if span_id
28
+ end
29
+
30
+ ::Instana.tracer.log_start_or_continue(
31
+ :'sidekiq-worker', kv_payload, context
32
+ )
33
+
34
+ yield
35
+ rescue => e
36
+ kv_payload[:'sidekiq-worker'][:error] = true
37
+ ::Instana.tracer.log_info(kv_payload)
38
+ ::Instana.tracer.log_error(e)
39
+ raise
40
+ ensure
41
+ ::Instana.tracer.log_end(:'sidekiq-worker', {}) if ::Instana.tracer.tracing?
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ if defined?(::Sidekiq) && ::Instana.config[:'sidekiq-worker'][:enabled]
48
+ ::Sidekiq.configure_server do |cfg|
49
+ cfg.server_middleware do |chain|
50
+ ::Instana.logger.info "Instrumenting Sidekiq worker"
51
+ chain.add ::Instana::Instrumentation::SidekiqWorker
52
+ end
53
+ end
54
+ end