instana 1.199.6 → 1.202.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +41 -6
  3. data/.rubocop.yml +11 -2
  4. data/lib/instana.rb +2 -4
  5. data/lib/instana/activator.rb +13 -1
  6. data/lib/instana/activators/active_job.rb +21 -0
  7. data/lib/instana/activators/aws_sdk_dynamodb.rb +1 -1
  8. data/lib/instana/activators/aws_sdk_s3.rb +1 -1
  9. data/lib/instana/activators/aws_sdk_sns.rb +1 -1
  10. data/lib/instana/activators/aws_sdk_sqs.rb +1 -1
  11. data/lib/instana/activators/redis.rb +1 -1
  12. data/lib/instana/activators/resque_worker.rb +4 -2
  13. data/lib/instana/activators/sidekiq_client.rb +1 -1
  14. data/lib/instana/activators/sidekiq_worker.rb +1 -1
  15. data/lib/instana/backend/host_agent.rb +7 -6
  16. data/lib/instana/backend/host_agent_reporting_observer.rb +2 -4
  17. data/lib/instana/backend/serverless_agent.rb +1 -1
  18. data/lib/instana/config.rb +6 -1
  19. data/lib/instana/frameworks/rails.rb +5 -5
  20. data/lib/instana/frameworks/roda.rb +1 -1
  21. data/lib/instana/instrumentation/active_job.rb +52 -0
  22. data/lib/instana/instrumentation/aws_sdk_s3.rb +1 -1
  23. data/lib/instana/instrumentation/aws_sdk_sns.rb +1 -1
  24. data/lib/instana/instrumentation/aws_sdk_sqs.rb +1 -1
  25. data/lib/instana/instrumentation/instrumented_request.rb +4 -4
  26. data/lib/instana/instrumentation/rack.rb +1 -1
  27. data/lib/instana/instrumentation/shoryuken.rb +1 -1
  28. data/lib/instana/instrumented_logger.rb +26 -0
  29. data/lib/instana/setup.rb +5 -1
  30. data/lib/instana/snapshot/docker_container.rb +1 -1
  31. data/lib/instana/snapshot/fargate_task.rb +1 -1
  32. data/lib/instana/snapshot/google_cloud_run_instance.rb +1 -1
  33. data/lib/instana/tracing/processor.rb +8 -5
  34. data/lib/instana/tracing/span.rb +2 -2
  35. data/lib/instana/tracing/span_context.rb +1 -1
  36. data/lib/instana/version.rb +1 -1
  37. data/test/instrumentation/rails_active_job_test.rb +65 -0
  38. data/test/test_helper.rb +10 -1
  39. data/test/tracing/instrumented_logger_test.rb +39 -0
  40. metadata +9 -10
  41. data/benchmarks/10k-rack-traces.rb +0 -95
  42. data/benchmarks/Gemfile +0 -11
  43. data/benchmarks/Gemfile.lock +0 -38
  44. data/benchmarks/id_generation.rb +0 -16
  45. data/benchmarks/opentracing.rb +0 -30
  46. data/benchmarks/rack_vanilla_vs_traced.rb +0 -88
  47. data/benchmarks/stackprof_rack_tracing.rb +0 -80
  48. data/benchmarks/time_processing.rb +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 526295c3e1f9ca3b4363e61b235d76a80974b34d293c35cd260ab3c675864aa2
4
- data.tar.gz: b9aea4aefede1996ee91bce87ec45b009694486279e76430b4df546733ad4a53
3
+ metadata.gz: 3c72533e116e54ad36227ccdf76c02aaaeb3536f40c99ecf1009f0cf284ebf99
4
+ data.tar.gz: 3f748a84fed00443296d65340fc71e876a69c17d8698637356529d6d5980aa5e
5
5
  SHA512:
6
- metadata.gz: f090f6841a6ce59e4f4c0adeb6ccb5bec5691447a099610651460744ff15dae0b589a801f3e8ee89468ee0bd6df440b57ae4619e9ed0fb6fca07e79af9c4ca2d
7
- data.tar.gz: 4010db830f3fc6d31a775d752be1075d7aa2aa6620a1abeba4298294a8878f17b0b88b4f06e5d7f059b353ef1a1a8d5cce774aa56ccc11366b2a61e2487f2940
6
+ metadata.gz: '009d83c5f6a7d8a5f4da1903fb482c6fe5a5cb68de6c984c1a58f52b01559bae3bbf43a10f028deae5cabe73c41a07e625f5545037ca295d53108e03564efbe1'
7
+ data.tar.gz: 241d6f1b46de88f5e7933dc85530cc5f540f71f9d9ad26b0778ffb970645b2c5c2aa4d0b11f05d85033cb4232339e9e27b92bfcd386fe79a1e3d9578485c9bfc
data/.circleci/config.yml CHANGED
@@ -132,12 +132,12 @@ commands:
132
132
  name: Install Depdendecies
133
133
  command: |
134
134
  bundle check || bundle install
135
- run_tests:
135
+ run_sonarqube:
136
136
  steps:
137
137
  - run:
138
- name: Run Tests
138
+ name: Install Java
139
139
  command: |
140
- bundle exec rake
140
+ sudo apt-get install openjdk-11-jdk
141
141
  - run:
142
142
  name: Run SonarQube to capture coverage
143
143
  command: |
@@ -147,15 +147,35 @@ commands:
147
147
  -Dsonar.projectKey=ruby-sensor \
148
148
  -Dsonar.sources=. \
149
149
  -Dsonar.host.url="${SONARQUBE_URL}" \
150
- -Dsonar.login="${SONARQUBE_LOGIN}" \
151
- -Dsonar.ruby.coverage.reportPaths=coverage/coverage.json
150
+ -Dsonar.login="${SONARQUBE_LOGIN}"
151
+ run_tests:
152
+ steps:
153
+ - run:
154
+ name: Run Tests
155
+ command: |
156
+ mkdir _junit
157
+ bundle exec rake
158
+ - store_test_results:
159
+ path: ~/_junit
152
160
  run_rubocop:
153
161
  steps:
154
162
  - run:
155
163
  name: Run Tests
156
164
  command: |
157
165
  bundle exec rubocop
158
-
166
+ publish_gem:
167
+ steps:
168
+ - run:
169
+ name: Setup Access
170
+ command: |
171
+ mkdir -p ~/.gem
172
+ echo -e "---\r\n:rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials
173
+ chmod 0600 /home/circleci/.gem/credentials
174
+ - run:
175
+ name: Publish Gem
176
+ command: |
177
+ bundle exec rake release[origin]
178
+
159
179
  jobs:
160
180
  test_core:
161
181
  parameters:
@@ -189,8 +209,23 @@ jobs:
189
209
  - checkout
190
210
  - setup
191
211
  - run_rubocop
212
+ - run_sonarqube
213
+ publish:
214
+ executor: ruby_27
215
+ steps:
216
+ - checkout
217
+ - setup
218
+ - publish_gem
192
219
 
193
220
  workflows:
221
+ publish:
222
+ jobs:
223
+ - publish:
224
+ filters:
225
+ branches:
226
+ ignore: /.*/
227
+ tags:
228
+ only: /^v.*/
194
229
  core:
195
230
  jobs:
196
231
  - lint
data/.rubocop.yml CHANGED
@@ -2,11 +2,14 @@ inherit_from: .rubocop_todo.yml
2
2
 
3
3
  require:
4
4
  - ./extras/license_header.rb
5
-
5
+
6
6
  # Remove when we remove .rubocop_todo.yml
7
7
  AllCops:
8
8
  NewCops: disable
9
9
 
10
+ Metrics/PerceivedComplexity:
11
+ Max: 20
12
+
10
13
  # Broken on 1.9
11
14
  Style/HashSyntax:
12
15
  Enabled: false
@@ -19,7 +22,13 @@ Style/NilComparison:
19
22
 
20
23
  Style/SoleNestedConditional:
21
24
  Enabled: false
22
-
25
+
23
26
  # Ruby 2.1 compatibility
24
27
  Style/SafeNavigation:
25
28
  Enabled: false
29
+
30
+ Style/SymbolProc:
31
+ Enabled: false
32
+
33
+ Style/MultilineBlockChain:
34
+ Enabled: false
data/lib/instana.rb CHANGED
@@ -1,10 +1,7 @@
1
1
  # (c) Copyright IBM Corp. 2021
2
2
  # (c) Copyright Instana Inc. 2016
3
3
 
4
- require 'concurrent'
5
- require 'sys-proctable'
6
-
7
- require "instana/setup"
4
+ require 'instana/setup'
8
5
 
9
6
  # Boot the instana agent background thread. If you wish to have greater
10
7
  # control on the where and which thread this is run in, instead use
@@ -15,4 +12,5 @@ require "instana/setup"
15
12
  # the thread of your choice.
16
13
  #
17
14
 
15
+ ::Instana::Activator.start
18
16
  ::Instana.agent.spawn_background_thread
@@ -43,4 +43,16 @@ module Instana
43
43
  end
44
44
  end
45
45
 
46
- Dir["#{__dir__}/activators/*.rb"].sort.each { |f| require(f) }
46
+ Dir["#{__dir__}/activators/*.rb"]
47
+ .sort
48
+ .select do |f|
49
+ # :nocov:
50
+ if ENV['INSTANA_ACTIVATE_SET']
51
+ base = File.basename(f, '.rb')
52
+ ENV.fetch('INSTANA_ACTIVATE_SET', '').split(',').include?(base)
53
+ else
54
+ true
55
+ end
56
+ # :nocov:
57
+ end
58
+ .each { |f| require(f) }
@@ -0,0 +1,21 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Activators
6
+ class ActiveJob < Activator
7
+ def can_instrument?
8
+ defined?(::ActiveJob::Base)
9
+ end
10
+
11
+ def instrument
12
+ require 'instana/instrumentation/active_job'
13
+
14
+ ::ActiveJob::Base
15
+ .prepend(Instana::Instrumentation::ActiveJob)
16
+
17
+ true
18
+ end
19
+ end
20
+ end
21
+ end
@@ -5,7 +5,7 @@ module Instana
5
5
  module Activators
6
6
  class AwsDynamoDB < Activator
7
7
  def can_instrument?
8
- defined?(Aws::DynamoDB::Client)
8
+ defined?(::Aws::DynamoDB::Client) && ::Aws::DynamoDB::Client.respond_to?(:add_plugin)
9
9
  end
10
10
 
11
11
  def instrument
@@ -5,7 +5,7 @@ module Instana
5
5
  module Activators
6
6
  class AwsS3 < Activator
7
7
  def can_instrument?
8
- defined?(Aws::S3::Client)
8
+ defined?(::Aws::S3::Client) && ::Aws::S3::Client.respond_to?(:add_plugin)
9
9
  end
10
10
 
11
11
  def instrument
@@ -5,7 +5,7 @@ module Instana
5
5
  module Activators
6
6
  class AwsSdkSns < Activator
7
7
  def can_instrument?
8
- defined?(Aws::SNS::Client)
8
+ defined?(::Aws::SNS::Client) && ::Aws::SNS::Client.respond_to?(:add_plugin)
9
9
  end
10
10
 
11
11
  def instrument
@@ -5,7 +5,7 @@ module Instana
5
5
  module Activators
6
6
  class AwsSdkSqs < Activator
7
7
  def can_instrument?
8
- defined?(Aws::SQS::Client)
8
+ defined?(::Aws::SQS::Client) && ::Aws::SQS::Client.respond_to?(:add_plugin)
9
9
  end
10
10
 
11
11
  def instrument
@@ -5,7 +5,7 @@ module Instana
5
5
  module Activators
6
6
  class Redis < Activator
7
7
  def can_instrument?
8
- defined?(::Redis) && ::Instana.config[:redis][:enabled]
8
+ defined?(::Redis) && defined?(::Redis::Client) && ::Instana.config[:redis][:enabled]
9
9
  end
10
10
 
11
11
  def instrument
@@ -16,8 +16,10 @@ module Instana
16
16
  ::Resque::Worker.prepend(::Instana::Instrumentation::ResqueWorker)
17
17
  ::Resque::Job.prepend(::Instana::Instrumentation::ResqueJob)
18
18
 
19
- ::Resque.after_fork do |_job|
20
- ::Instana.agent.after_fork
19
+ if ::Instana.config[:'resque-worker'][:'setup-fork']
20
+ ::Resque.after_fork do |_job|
21
+ ::Instana.agent.after_fork
22
+ end
21
23
  end
22
24
 
23
25
  # Set this so we assure that any remaining collected traces are reported at_exit
@@ -5,7 +5,7 @@ module Instana
5
5
  module Activators
6
6
  class SidekiqClient < Activator
7
7
  def can_instrument?
8
- defined?(::Sidekiq) && ::Instana.config[:'sidekiq-client'][:enabled]
8
+ defined?(::Sidekiq) && ::Sidekiq.respond_to?(:configure_client) && ::Instana.config[:'sidekiq-client'][:enabled]
9
9
  end
10
10
 
11
11
  def instrument
@@ -5,7 +5,7 @@ module Instana
5
5
  module Activators
6
6
  class SidekiqWorker < Activator
7
7
  def can_instrument?
8
- defined?(::Sidekiq) && ::Instana.config[:'sidekiq-worker'][:enabled]
8
+ defined?(::Sidekiq) && ::Sidekiq.respond_to?(:configure_server) && ::Instana.config[:'sidekiq-worker'][:enabled]
9
9
  end
10
10
 
11
11
  def instrument
@@ -5,12 +5,13 @@ module Instana
5
5
  module Backend
6
6
  # @since 1.197.0
7
7
  class HostAgent
8
- attr_reader :future
8
+ attr_reader :future, :client
9
9
 
10
10
  def initialize(discovery: Concurrent::Atom.new(nil), logger: ::Instana.logger)
11
11
  @discovery = discovery
12
12
  @logger = logger
13
13
  @future = nil
14
+ @client = nil
14
15
  end
15
16
 
16
17
  def setup; end
@@ -26,14 +27,14 @@ module Instana
26
27
  alias start spawn_background_thread
27
28
 
28
29
  def announce
29
- client = until_not_nil { HostAgentLookup.new.call }
30
+ @client = until_not_nil { HostAgentLookup.new.call }
30
31
  @discovery.delete_observers
31
32
  @discovery
32
- .with_observer(HostAgentActivationObserver.new(client, @discovery))
33
- .with_observer(HostAgentReportingObserver.new(client, @discovery))
33
+ .with_observer(HostAgentActivationObserver.new(@client, @discovery))
34
+ .with_observer(HostAgentReportingObserver.new(@client, @discovery))
34
35
 
35
36
  @discovery.swap { nil }
36
- client
37
+ @client
37
38
  end
38
39
 
39
40
  alias after_fork announce
@@ -48,7 +49,7 @@ module Instana
48
49
  {
49
50
  e: discovery_value['pid'],
50
51
  h: discovery_value['agentUuid']
51
- }.compact
52
+ }.reject { |_, v| v.nil? }
52
53
  end
53
54
 
54
55
  # @return [Array] extra headers to include in the trace
@@ -49,11 +49,10 @@ module Instana
49
49
  response = @client.send_request('POST', path, spans)
50
50
 
51
51
  unless response.ok?
52
+ @logger.debug("Sent `#{spans.count}` spans to `#{path}` and got `#{response.code}`.")
52
53
  @discovery.swap { nil }
53
54
  break
54
55
  end
55
-
56
- @logger.debug("Sent `#{spans.count}` spans to `#{path}` and got `#{response.code}`.")
57
56
  end
58
57
  end
59
58
 
@@ -68,10 +67,9 @@ module Instana
68
67
  if response.ok?
69
68
  handle_agent_tasks(response, discovery) unless response.body.empty?
70
69
  else
70
+ @logger.debug("Sent `#{payload}` to `#{path}` and got `#{response.code}`.")
71
71
  @discovery.swap { nil }
72
72
  end
73
-
74
- @logger.debug("Sent `#{payload}` to `#{path}` and got `#{response.code}`.")
75
73
  end
76
74
 
77
75
  def handle_agent_tasks(response, discovery)
@@ -98,7 +98,7 @@ module Instana
98
98
  @logger.error(e.message)
99
99
  nil
100
100
  end
101
- end.compact
101
+ end.reject { |_, v| v.nil? }
102
102
  end
103
103
 
104
104
  def host_name
@@ -27,6 +27,9 @@ module Instana
27
27
  # Enable/disable tracing (default: enabled)
28
28
  @config[:tracing] = { :enabled => true }
29
29
 
30
+ # Enable/Disable logging
31
+ @config[:logging] = { :enabled => true }
32
+
30
33
  # Collector interval
31
34
  @config[:collector] = { :enabled => true, :interval => 1 }
32
35
 
@@ -53,6 +56,8 @@ module Instana
53
56
  # W3 Trace Context Support
54
57
  @config[:w3_trace_correlation] = ENV['INSTANA_DISABLE_W3C_TRACE_CORRELATION'].nil?
55
58
 
59
+ @config[:post_fork_proc] = proc { ::Instana.agent.spawn_background_thread }
60
+
56
61
  @config[:action_controller] = { :enabled => true }
57
62
  @config[:action_view] = { :enabled => true }
58
63
  @config[:active_record] = { :enabled => true }
@@ -63,7 +68,7 @@ module Instana
63
68
  @config[:nethttp] = { :enabled => true }
64
69
  @config[:redis] = { :enabled => true }
65
70
  @config[:'resque-client'] = { :enabled => true }
66
- @config[:'resque-worker'] = { :enabled => true }
71
+ @config[:'resque-worker'] = { :enabled => true, :'setup-fork' => true }
67
72
  @config[:'rest-client'] = { :enabled => true }
68
73
  @config[:'sidekiq-client'] = { :enabled => true }
69
74
  @config[:'sidekiq-worker'] = { :enabled => true }
@@ -3,9 +3,6 @@
3
3
 
4
4
  if ::Rails::VERSION::MAJOR < 3
5
5
  ::Rails.configuration.after_initialize do
6
- # In Rails, let's use the Rails logger
7
- ::Instana.logger = ::Rails.logger if ::Rails.logger
8
-
9
6
  if ::Instana.config[:tracing][:enabled]
10
7
  ::Instana.logger.debug "Instrumenting Rack"
11
8
  ::Rails.configuration.middleware.insert 0, ::Instana::Rack
@@ -17,8 +14,11 @@ else
17
14
  module ::Instana
18
15
  class Railtie < ::Rails::Railtie
19
16
  initializer 'instana.rack' do |app|
20
- # In Rails, let's use the Rails logger
21
- ::Instana.logger = ::Rails.logger if ::Rails.logger
17
+ # Configure the Instrumented Logger
18
+ if ::Instana.config[:logging][:enabled] && !ENV.key?('INSTANA_TEST')
19
+ logger = ::Instana::InstrumentedLogger.new('/dev/null')
20
+ Rails.logger.extend(ActiveSupport::Logger.broadcast(logger))
21
+ end
22
22
 
23
23
  if ::Instana.config[:tracing][:enabled]
24
24
  ::Instana.logger.debug "Instrumenting Rack"
@@ -37,7 +37,7 @@ module Instana
37
37
  _, name = parameters.pop
38
38
  "{#{name}}"
39
39
  end
40
- end.compact
40
+ end.reject { |v| v.nil? }
41
41
  end
42
42
  end
43
43
  end
@@ -0,0 +1,52 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Instrumentation
6
+ module ActiveJob
7
+ def self.prepended(target)
8
+ target.around_enqueue do |job, block|
9
+ tags = {
10
+ activejob: {
11
+ queue: job.queue_name,
12
+ job: job.class.to_s,
13
+ action: :enqueue,
14
+ job_id: job.job_id
15
+ }
16
+ }
17
+
18
+ ::Instana::Tracer.trace(:activejob, tags) do
19
+ context = ::Instana.tracer.context
20
+ job.arguments = [{
21
+ given_arguments: job.arguments,
22
+ instana_context: context ? context.to_hash : nil
23
+ }]
24
+
25
+ block.call
26
+ end
27
+ end
28
+
29
+ target.around_perform do |job, block|
30
+ tags = {
31
+ activejob: {
32
+ queue: job.queue_name,
33
+ job: job.class.to_s,
34
+ action: :perform,
35
+ job_id: job.job_id
36
+ }
37
+ }
38
+
39
+ incoming_context = if job.arguments.is_a?(Array) && job.arguments.first.is_a?(Hash)
40
+ instana_context = job.arguments.first[:instana_context]
41
+ job.arguments = job.arguments.first[:given_arguments]
42
+ instana_context ? ::Instana::SpanContext.new(instana_context[:trace_id], instana_context[:span_id]) : nil
43
+ end
44
+
45
+ ::Instana::Tracer.start_or_continue_trace(:activejob, tags, incoming_context) do
46
+ block.call
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end