instana 1.201.0 → 1.204.0.pre1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a12265a63ae5d07df74d4e8c1b81fe17559960726a5562c6c59b83571eb4f25
4
- data.tar.gz: 2844f85c68a18ead499aef5ec6634d726305b824dada97d1e1e386e1c40774fb
3
+ metadata.gz: 99eb3bcbb6b1c801c556d28c7c9831d2bd65c6d17f07ae53ac6a9336dc423e41
4
+ data.tar.gz: '0804abf2466856db1597e10146865e8fa3bdb10db167dda3c850ac29ae7c44de'
5
5
  SHA512:
6
- metadata.gz: 97c13b14a55c13d2e5e898711fee065699d817169cc39ab1b15c322bf075d1f4c3b715dc4fa1490f8cc7d53ef01e0ba348f7548cae400ab028c8da1fed607484
7
- data.tar.gz: 0c4e03ef64a6273cbbf2f41bb2e57228a68b4a579298c4c26c3bd109b5002ba7e7fb1337609bc8a712e9fb7ff1902a0e46a2a0bdcd386fd13ca454172228032d
6
+ metadata.gz: d422c7e103d9839835aeac082b2a42fbbb1bf46f7b0f891ee065d4cbfda5de2257bc4e0470ded8768bb2bf52a6c717591b8f76b4183a09a31167d51faba44fb3
7
+ data.tar.gz: 6395be74fa6318c073abcd3b5c3e71022d59269b11accda6fef9996a7c3a5f21a353cde4afc6e766f414678c6992b21ad69474cce83fd7c025504f95e375187a
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,8 +147,16 @@ 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:
@@ -201,6 +209,7 @@ jobs:
201
209
  - checkout
202
210
  - setup
203
211
  - run_rubocop
212
+ - run_sonarqube
204
213
  publish:
205
214
  executor: ruby_27
206
215
  steps:
@@ -0,0 +1,39 @@
1
+ name: Bug Report
2
+ description: File a bug report
3
+ title: "[Bug]: "
4
+ labels: [bug]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Thank you for taking the time to fill out this report. Remember that these issues are public and if you need to discuss implementation specific issues securely, please [use our support portal](https://support.instana.com/hc/en-us).
10
+ - type: textarea
11
+ id: problem-description
12
+ attributes:
13
+ label: Problem Description
14
+ description: What was the issue that caused you to file this bug?
15
+ validations:
16
+ required: true
17
+ - type: textarea
18
+ id: mcve
19
+ attributes:
20
+ label: Minimal, Complete, Verifiable, Example
21
+ description: Can you provide steps needed to reproduce this issue outside of your application?
22
+ validations:
23
+ required: false
24
+ - type: textarea
25
+ id: gemfile-lock
26
+ attributes:
27
+ label: Gemfile.lock
28
+ description: Please paste the contents of the Gemfile.lock for the application that was affected by this bug.
29
+ render: shell
30
+ validations:
31
+ required: true
32
+ - type: textarea
33
+ id: ruby-version
34
+ attributes:
35
+ label: Ruby Version
36
+ description: What version of Ruby was the application running under when it encountered this bug?
37
+ render: shell
38
+ validations:
39
+ required: true
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Instana Support Portal
4
+ url: https://support.instana.com
5
+ about: Please ask questions related to your installation there.
data/Appraisals CHANGED
@@ -6,6 +6,7 @@ appraise 'aws-30' do
6
6
  gem 'aws-sdk-s3', '~> 1.59'
7
7
  gem 'aws-sdk-sns', '~> 1.38'
8
8
  gem 'aws-sdk-sqs', '~> 1.36'
9
+ gem 'aws-sdk-lambda', '~> 1.62'
9
10
  end
10
11
 
11
12
  appraise 'cuba-30' do
data/README.md CHANGED
@@ -77,5 +77,5 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/instan
77
77
 
78
78
  ## More
79
79
 
80
- Want to instrument other languages? See our [Node.js](https://github.com/instana/nodejs-sensor), [Go](https://github.com/instana/golang-sensor), [Python](https://github.com/instana/python-sensor) repositories or [many other supported technologies](https://www.instana.com/supported-technologies/).
80
+ Want to instrument other languages? See our [Node.js](https://github.com/instana/nodejs), [Go](https://github.com/instana/golang-sensor), [Python](https://github.com/instana/python-sensor) repositories or [many other supported technologies](https://www.instana.com/supported-technologies/).
81
81
 
@@ -17,5 +17,6 @@ gem "aws-sdk-dynamodb", "~> 1.59"
17
17
  gem "aws-sdk-s3", "~> 1.59"
18
18
  gem "aws-sdk-sns", "~> 1.38"
19
19
  gem "aws-sdk-sqs", "~> 1.36"
20
+ gem "aws-sdk-lambda", "~> 1.62"
20
21
 
21
22
  gemspec path: "../"
@@ -46,11 +46,13 @@ end
46
46
  Dir["#{__dir__}/activators/*.rb"]
47
47
  .sort
48
48
  .select do |f|
49
+ # :nocov:
49
50
  if ENV['INSTANA_ACTIVATE_SET']
50
51
  base = File.basename(f, '.rb')
51
52
  ENV.fetch('INSTANA_ACTIVATE_SET', '').split(',').include?(base)
52
53
  else
53
54
  true
54
55
  end
56
+ # :nocov:
55
57
  end
56
58
  .each { |f| require(f) }
@@ -0,0 +1,22 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Activators
6
+ class ActionMailer < Activator
7
+ def can_instrument?
8
+ defined?(::ActionMailer::Base)
9
+ end
10
+
11
+ def instrument
12
+ require 'instana/instrumentation/action_mailer'
13
+
14
+ ::ActionMailer::Base
15
+ .singleton_class
16
+ .prepend(Instana::Instrumentation::ActionMailer)
17
+
18
+ true
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Activators
6
+ class AwsSdkLambda < Activator
7
+ def can_instrument?
8
+ defined?(::Aws::Lambda::Client) && ::Aws::Lambda::Client.respond_to?(:add_plugin)
9
+ end
10
+
11
+ def instrument
12
+ require 'instana/instrumentation/aws_sdk_lambda'
13
+
14
+ ::Aws::Lambda::Client.add_plugin(Instana::Instrumentation::Lambda)
15
+
16
+ true
17
+ end
18
+ end
19
+ end
20
+ end
@@ -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
 
@@ -64,7 +67,7 @@ module Instana
64
67
  @config[:graphql] = { :enabled => true }
65
68
  @config[:nethttp] = { :enabled => true }
66
69
  @config[:redis] = { :enabled => true }
67
- @config[:'resque-client'] = { :enabled => true }
70
+ @config[:'resque-client'] = { :enabled => true, :propagate => true }
68
71
  @config[:'resque-worker'] = { :enabled => true, :'setup-fork' => true }
69
72
  @config[:'rest-client'] = { :enabled => true }
70
73
  @config[:'sidekiq-client'] = { :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"
@@ -0,0 +1,22 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Instrumentation
6
+ module ActionMailer
7
+ def method_missing(method_name, *args) # rubocop:disable Style/MissingRespondToMissing
8
+ if action_methods.include?(method_name.to_s)
9
+ tags = {
10
+ actionmailer: {
11
+ class: to_s,
12
+ method: method_name.to_s
13
+ }
14
+ }
15
+ Instana::Tracer.trace(:'mail.actionmailer', tags) { super }
16
+ else
17
+ super
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+ require 'base64'
4
+
5
+ module Instana
6
+ module Instrumentation
7
+ class Lambda < Seahorse::Client::Plugin
8
+ class Handler < Seahorse::Client::Handler
9
+ def call(context)
10
+ return @handler.call(context) unless [:invoke_async, :invoke].include?(context.operation_name)
11
+
12
+ if context.params[:client_context].nil? && ::Instana.tracer.tracing? && context.operation_name == :invoke
13
+ span_context = ::Instana.tracer.context
14
+ payload = {
15
+ 'X-INSTANA-T' => span_context.trace_id,
16
+ 'X-INSTANA-S' => span_context.span_id,
17
+ 'X-INSTANA-L' => span_context.level.to_s
18
+ }
19
+
20
+ context.params[:client_context] = JSON.dump(payload)
21
+ end
22
+
23
+ tags = {
24
+ function: context.params[:function_name],
25
+ type: context.params[:invocation_type]
26
+ }.reject { |_, v| v.nil? }
27
+
28
+ ::Instana.tracer.trace(:"aws.lambda.invoke", {aws: {lambda: {invoke: tags}}}) { @handler.call(context) }
29
+ end
30
+ end
31
+
32
+ def add_handlers(handlers, _config)
33
+ handlers.add(Handler, step: :initialize)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -28,6 +28,7 @@ module Instana
28
28
  kvs = collect_kvs(:enqueue, klass, args)
29
29
 
30
30
  Instana.tracer.trace(:'resque-client', kvs) do
31
+ args.push(::Instana.tracer.context.to_hash) if ::Instana.config[:'resque-client'][:propagate]
31
32
  super(klass, *args)
32
33
  end
33
34
  else
@@ -41,6 +42,7 @@ module Instana
41
42
  kvs[:Queue] = queue.to_s if queue
42
43
 
43
44
  Instana.tracer.trace(:'resque-client', kvs) do
45
+ args.push(::Instana.tracer.context.to_hash) if ::Instana.config[:'resque-client'][:propagate]
44
46
  super(queue, klass, *args)
45
47
  end
46
48
  else
@@ -76,7 +78,15 @@ module Instana
76
78
  ::Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" } if Instana::Config[:verbose]
77
79
  end
78
80
 
79
- Instana.tracer.start_or_continue_trace(:'resque-worker', kvs) do
81
+ trace_context = if ::Instana.config[:'resque-client'][:propagate] && job.payload['args'][-1].is_a?(Hash) && job.payload['args'][-1].keys.include?('trace_id')
82
+ context_from_wire = job.payload['args'].pop
83
+ ::Instana::SpanContext.new(
84
+ context_from_wire['trace_id'],
85
+ context_from_wire['span_id']
86
+ )
87
+ end
88
+
89
+ Instana.tracer.start_or_continue_trace(:'resque-worker', kvs, trace_context) do
80
90
  super(job)
81
91
  end
82
92
  end
@@ -0,0 +1,26 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ class InstrumentedLogger < Logger
6
+ LEVEL_LABELS = %w[Debug Info Warn Error Fatal Any].freeze
7
+
8
+ def instana_log_level
9
+ WARN
10
+ end
11
+
12
+ def add(severity, message = nil, progname = nil)
13
+ severity ||= UNKNOWN
14
+
15
+ if severity >= instana_log_level && ::Instana.tracer.tracing?
16
+ tags = {
17
+ level: LEVEL_LABELS[severity],
18
+ message: "#{message} #{progname}".strip
19
+ }
20
+ Instana::Tracer.trace(:log, {log: tags}) {}
21
+ end
22
+
23
+ super(severity, message, progname)
24
+ end
25
+ end
26
+ end
@@ -23,7 +23,7 @@ module Instana
23
23
 
24
24
  def wrap_aws(event, context, &block)
25
25
  Thread.current[:instana_function_arn] = [context.invoked_function_arn, context.function_version].join(':')
26
- trigger, event_tags, span_context = trigger_from_event(event)
26
+ trigger, event_tags, span_context = trigger_from_event(event, context)
27
27
 
28
28
  tags = {
29
29
  lambda: {
@@ -53,7 +53,7 @@ module Instana
53
53
 
54
54
  private
55
55
 
56
- def trigger_from_event(event) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
56
+ def trigger_from_event(event, context) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
57
57
  case event
58
58
  when ->(e) { defined?(::Instana::InstrumentedRequest) && e.is_a?(Hash) && e.key?('requestContext') && e['requestContext'].key?('elb') }
59
59
  request = InstrumentedRequest.new(event_to_rack(event))
@@ -74,7 +74,28 @@ module Instana
74
74
  tags = decode_sqs(event)
75
75
  ['aws:sqs', {sqs: tags}, {}]
76
76
  else
77
- ['aws:api.gateway.noproxy', {}, {}]
77
+ ctx = context_from_lambda_context(context)
78
+ if ctx.empty?
79
+ ['aws:api.gateway.noproxy', {}, {}]
80
+ else
81
+ ['aws.lambda.invoke', {}, ctx]
82
+ end
83
+ end
84
+ end
85
+
86
+ def context_from_lambda_context(context)
87
+ return {} unless context.client_context
88
+
89
+ begin
90
+ context = JSON.parse(Base64.decode64(context.client_context))
91
+
92
+ {
93
+ trace_id: context['X-INSTANA-T'],
94
+ span_id: context['X-INSTANA-S'],
95
+ level: Integer(context['X-INSTANA-L'])
96
+ }
97
+ rescue TypeError, JSON::ParserError, NoMethodError => _e
98
+ {}
78
99
  end
79
100
  end
80
101
 
data/lib/instana/setup.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  # (c) Copyright IBM Corp. 2021
2
2
  # (c) Copyright Instana Inc. 2016
3
3
 
4
+ require 'logger'
4
5
  require 'concurrent'
5
6
  require 'sys-proctable'
6
7
 
7
8
  require 'instana/logger_delegator'
9
+ require 'instana/instrumented_logger'
8
10
 
9
11
  require "instana/base"
10
12
  require "instana/config"
@@ -2,6 +2,7 @@
2
2
  # (c) Copyright Instana Inc. 2016
3
3
 
4
4
  require 'thread'
5
+ require 'forwardable'
5
6
 
6
7
  module Instana
7
8
  class Processor
@@ -6,10 +6,13 @@ module Instana
6
6
  REGISTERED_SPANS = [ :actioncontroller, :actionview, :activerecord, :excon,
7
7
  :memcache, :'net-http', :rack, :render, :'rpc-client',
8
8
  :'rpc-server', :'sidekiq-client', :'sidekiq-worker',
9
- :redis, :'resque-client', :'resque-worker', :'graphql.server', :dynamodb, :s3, :sns, :sqs, :'aws.lambda.entry', :activejob ].freeze
10
- ENTRY_SPANS = [ :rack, :'resque-worker', :'rpc-server', :'sidekiq-worker', :'graphql.server', :sqs, :'aws.lambda.entry' ].freeze
9
+ :redis, :'resque-client', :'resque-worker', :'graphql.server', :dynamodb, :s3, :sns, :sqs, :'aws.lambda.entry', :activejob, :log, :"mail.actionmailer",
10
+ :"aws.lambda.invoke" ].freeze
11
+ ENTRY_SPANS = [ :rack, :'resque-worker', :'rpc-server', :'sidekiq-worker', :'graphql.server', :sqs,
12
+ :'aws.lambda.entry' ].freeze
11
13
  EXIT_SPANS = [ :activerecord, :excon, :'net-http', :'resque-client',
12
- :'rpc-client', :'sidekiq-client', :redis, :dynamodb, :s3, :sns, :sqs ].freeze
14
+ :'rpc-client', :'sidekiq-client', :redis, :dynamodb, :s3, :sns, :sqs, :log, :"mail.actionmailer",
15
+ :"aws.lambda.invoke" ].freeze
13
16
  HTTP_SPANS = [ :rack, :excon, :'net-http' ].freeze
14
17
 
15
18
  attr_accessor :parent
@@ -77,34 +80,16 @@ module Instana
77
80
  # @param limit [Integer] Limit the backtrace to the top <limit> frames
78
81
  #
79
82
  def add_stack(limit: 30, stack: Kernel.caller)
80
- frame_count = 0
81
- sanitized_stack = []
82
- @data[:stack] = []
83
- limit = 40 if limit > 40
84
-
85
- stack.each do |i|
86
- # If the stack has the full instana gem version in it's path
87
- # then don't include that frame. Also don't exclude the Rack module.
88
- if !i.match(/instana\/instrumentation\/rack.rb/).nil? ||
89
- (i.match(::Instana::VERSION_FULL).nil? && i.match('lib/instana/').nil?)
90
-
91
- x = i.split(':')
92
-
93
- sanitized_stack << {
94
- :c => x[0],
95
- :n => x[1],
96
- :m => x[2]
97
- }
98
- end
99
- end
100
-
101
- if sanitized_stack.length > limit
102
- # (limit * -1) gives us negative form of <limit> used for
103
- # slicing from the end of the list. e.g. stack[-30, 30]
104
- @data[:stack] = sanitized_stack[limit*-1, limit]
105
- else
106
- @data[:stack] = sanitized_stack
107
- end
83
+ @data[:stack] = stack
84
+ .map do |call|
85
+ file, line, *method = call.split(':')
86
+
87
+ {
88
+ c: file,
89
+ n: line,
90
+ m: method.join(' ')
91
+ }
92
+ end.take(limit > 40 ? 40 : limit)
108
93
  end
109
94
 
110
95
  # Log an error into the span
@@ -2,6 +2,6 @@
2
2
  # (c) Copyright Instana Inc. 2016
3
3
 
4
4
  module Instana
5
- VERSION = "1.201.0"
5
+ VERSION = "1.204.0.pre1"
6
6
  VERSION_FULL = "instana-#{VERSION}"
7
7
  end
@@ -158,4 +158,39 @@ class AwsTest < Minitest::Test
158
158
  assert_equal send_span[:s], message.message_attributes['X_INSTANA_S'].string_value
159
159
  assert_equal 'Sample', message.body
160
160
  end
161
+
162
+ def test_lambda
163
+ stub_request(:post, "https://lambda.local.amazonaws.com/2015-03-31/functions/Test/invocations")
164
+ .with(
165
+ body: "data",
166
+ headers: {
167
+ 'X-Amz-Client-Context' => /.+/
168
+ }
169
+ )
170
+ .to_return(status: 200, body: "", headers: {})
171
+
172
+ lambda = Aws::Lambda::Client.new(
173
+ endpoint: 'https://lambda.local.amazonaws.com',
174
+ region: 'local',
175
+ access_key_id: "test",
176
+ secret_access_key: "test"
177
+ )
178
+
179
+ Instana::Tracer.start_or_continue_trace(:lambda_test, {}) do
180
+ lambda.invoke(
181
+ function_name: 'Test',
182
+ invocation_type: 'Event',
183
+ payload: 'data'
184
+ )
185
+ end
186
+
187
+ spans = ::Instana.processor.queued_spans
188
+ lambda_span, _entry_span, *rest = spans
189
+
190
+ assert rest.empty?
191
+
192
+ assert_equal :"aws.lambda.invoke", lambda_span[:n]
193
+ assert_equal 'Test', lambda_span[:data][:aws][:lambda][:invoke][:function]
194
+ assert_equal 'Event', lambda_span[:data][:aws][:lambda][:invoke][:type]
195
+ end
161
196
  end
@@ -0,0 +1,37 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ require 'test_helper'
5
+ require 'action_mailer'
6
+
7
+ class RailsActionMailerTest < Minitest::Test
8
+ class TestMailer < ActionMailer::Base
9
+ def sample_email
10
+ mail(
11
+ from: 'test@example.com',
12
+ to: 'test@example.com',
13
+ subject: 'Test Email',
14
+ body: 'Hello',
15
+ content_type: "text/html"
16
+ )
17
+ end
18
+ end
19
+
20
+ def setup
21
+ TestMailer.delivery_method = :sendmail
22
+
23
+ clear_all!
24
+ end
25
+
26
+ def test_mailer
27
+ Instana.tracer.start_or_continue_trace(:test) do
28
+ TestMailer.sample_email.deliver_now
29
+ end
30
+
31
+ mail_span, = *::Instana.processor.queued_spans
32
+
33
+ assert_equal :"mail.actionmailer", mail_span[:n]
34
+ assert_equal 'RailsActionMailerTest::TestMailer', mail_span[:data][:actionmailer][:class]
35
+ assert_equal 'sample_email', mail_span[:data][:actionmailer][:method]
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ require 'test_helper'
5
+ require 'support/apps/active_record/active_record'
6
+ require 'fileutils'
7
+
8
+ class RailsActiveRecordDatabaseMissingTest < Minitest::Test
9
+ def setup
10
+ skip unless ENV['DATABASE_URL']
11
+
12
+ @old_url = ENV['DATABASE_URL']
13
+ SQLite3::Database.new('/tmp/test.db')
14
+ ENV['DATABASE_URL'] = 'sqlite3:///tmp/test.db'
15
+
16
+ @connection = ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
17
+ ActiveRecord::Migration.suppress_messages do
18
+ ActiveRecord::Migration.run(CreateBlocks, direction: :up)
19
+ end
20
+ end
21
+
22
+ def teardown
23
+ ActiveRecord::Base.remove_connection(@connection)
24
+ ENV['DATABASE_URL'] = @old_url
25
+ end
26
+
27
+ def test_error_on_missing_database
28
+ assert_raises(ActiveRecord::StatementInvalid) do
29
+ Instana::Tracer.start_or_continue_trace(:ar_test, {}) do
30
+ b = Block.new
31
+ FileUtils.rm('/tmp/test.db')
32
+ b.save!
33
+ end
34
+ end
35
+
36
+ spans = ::Instana.processor.queued_spans
37
+ assert_equal 3, spans.length
38
+ span = find_first_span_by_name(spans, :activerecord)
39
+
40
+ assert_equal 1, span[:ec]
41
+ assert span[:data][:activerecord][:error].include?("SQLite3::ReadOnlyException: attempt to write a readonly database")
42
+ end
43
+ end
@@ -22,6 +22,7 @@ class ResqueClientTest < Minitest::Test
22
22
  ::Resque.enqueue(FastJob)
23
23
  end
24
24
 
25
+ resque_job = Resque.reserve('critical')
25
26
  spans = ::Instana.processor.queued_spans
26
27
  assert_equal 2, spans.length
27
28
 
@@ -34,6 +35,9 @@ class ResqueClientTest < Minitest::Test
34
35
  assert_equal "FastJob", resque_span[:data][:'resque-client'][:job]
35
36
  assert_equal :critical, resque_span[:data][:'resque-client'][:queue]
36
37
  assert_equal false, resque_span[:data][:'resque-client'].key?(:error)
38
+
39
+ assert_equal resque_job.args.first['trace_id'], resque_span[:t]
40
+ assert_equal resque_job.args.first['span_id'], resque_span[:s]
37
41
  end
38
42
 
39
43
  def test_enqueue_to
@@ -41,6 +45,7 @@ class ResqueClientTest < Minitest::Test
41
45
  ::Resque.enqueue_to(:critical, FastJob)
42
46
  end
43
47
 
48
+ resque_job = Resque.reserve('critical')
44
49
  spans = ::Instana.processor.queued_spans
45
50
  assert_equal 2, spans.length
46
51
 
@@ -52,6 +57,9 @@ class ResqueClientTest < Minitest::Test
52
57
  assert_equal "FastJob", resque_span[:data][:'resque-client'][:job]
53
58
  assert_equal :critical, resque_span[:data][:'resque-client'][:queue]
54
59
  assert_equal false, resque_span[:data][:'resque-client'].key?(:error)
60
+
61
+ assert_equal resque_job.args.first['trace_id'], resque_span[:t]
62
+ assert_equal resque_job.args.first['span_id'], resque_span[:s]
55
63
  end
56
64
 
57
65
  def test_dequeue
@@ -73,17 +81,58 @@ class ResqueClientTest < Minitest::Test
73
81
  end
74
82
 
75
83
  def test_worker_job
76
- Resque::Job.create(:critical, FastJob)
77
- @worker.work(0)
84
+ ::Instana.tracer.start_or_continue_trace(:'resque-client_test') do
85
+ ::Resque.enqueue_to(:critical, FastJob)
86
+ end
87
+
88
+ resque_job = Resque.reserve('critical')
89
+ @worker.work_one_job(resque_job)
90
+
91
+ spans = ::Instana.processor.queued_spans
92
+ assert_equal 5, spans.length
93
+
94
+ client_span = spans[0]
95
+ resque_span = spans[4]
96
+ redis1_span = spans[3]
97
+ redis2_span = spans[2]
98
+
99
+ assert_equal :'resque-client', client_span[:n]
100
+
101
+ assert_equal :'resque-worker', resque_span[:n]
102
+ assert_equal client_span[:s], resque_span[:p]
103
+ assert_equal false, resque_span.key?(:error)
104
+ assert_equal false, resque_span.key?(:ec)
105
+ assert_equal "FastJob", resque_span[:data][:'resque-worker'][:job]
106
+ assert_equal "critical", resque_span[:data][:'resque-worker'][:queue]
107
+ assert_equal false, resque_span[:data][:'resque-worker'].key?(:error)
108
+
109
+ assert_equal :redis, redis1_span[:n]
110
+ assert_equal "SET", redis1_span[:data][:redis][:command]
111
+ assert_equal :redis, redis2_span[:n]
112
+ assert_equal "SET", redis2_span[:data][:redis][:command]
113
+ end
114
+
115
+ def test_worker_job_no_propagate
116
+ ::Instana.config[:'resque-client'][:propagate] = false
117
+ ::Instana.tracer.start_or_continue_trace(:'resque-client_test') do
118
+ ::Resque.enqueue_to(:critical, FastJob)
119
+ end
120
+
121
+ resque_job = Resque.reserve('critical')
122
+ @worker.work_one_job(resque_job)
78
123
 
79
124
  spans = ::Instana.processor.queued_spans
80
- assert_equal 3, spans.length
125
+ assert_equal 5, spans.length
126
+
127
+ client_span = spans[0]
128
+ resque_span = spans[4]
129
+ redis1_span = spans[3]
130
+ redis2_span = spans[2]
81
131
 
82
- resque_span = spans[2]
83
- redis1_span = spans[1]
84
- redis2_span = spans[0]
132
+ assert_equal :'resque-client', client_span[:n]
85
133
 
86
134
  assert_equal :'resque-worker', resque_span[:n]
135
+ refute_equal client_span[:s], resque_span[:p]
87
136
  assert_equal false, resque_span.key?(:error)
88
137
  assert_equal false, resque_span.key?(:ec)
89
138
  assert_equal "FastJob", resque_span[:data][:'resque-worker'][:job]
@@ -94,6 +143,8 @@ class ResqueClientTest < Minitest::Test
94
143
  assert_equal "SET", redis1_span[:data][:redis][:command]
95
144
  assert_equal :redis, redis2_span[:n]
96
145
  assert_equal "SET", redis2_span[:data][:redis][:command]
146
+ ensure
147
+ ::Instana.config[:'resque-client'][:propagate] = true
97
148
  end
98
149
 
99
150
  def test_worker_error_job
@@ -320,4 +320,50 @@ class ServerlessTest < Minitest::Test
320
320
 
321
321
  assert_equal 'test_arn', data[:messages].first[:queue]
322
322
  end
323
+
324
+ def test_lambda_client_context
325
+ clear_all!
326
+
327
+ mock_context = OpenStruct.new(
328
+ invoked_function_arn: 'test_arn',
329
+ function_name: 'test_function',
330
+ function_version: '$TEST',
331
+ client_context: "eyJYLUlOU1RBTkEtVCI6IjEyMyIsIlgtSU5TVEFOQS1TIjoiNDU2IiwiWC1J\nTlNUQU5BLUwiOiIxIn0=\n"
332
+ )
333
+ mock_event = {
334
+ "Invoked" => true
335
+ }
336
+
337
+ @subject.wrap_aws(mock_event, mock_context) { 0 }
338
+
339
+ lambda_span, *rest = Instana.processor.queued_spans
340
+ assert rest.empty?
341
+
342
+ assert_equal 'aws.lambda.invoke', lambda_span[:data][:lambda][:trigger]
343
+ assert_equal '123', lambda_span[:t]
344
+ assert_equal '456', lambda_span[:p]
345
+ end
346
+
347
+ def test_lambda_client_context_error
348
+ clear_all!
349
+
350
+ mock_context = OpenStruct.new(
351
+ invoked_function_arn: 'test_arn',
352
+ function_name: 'test_function',
353
+ function_version: '$TEST',
354
+ client_context: "eyJYLUlOU1RBkEtVCI6IjEyMyIsIlgtSU5TVEFOQS1TIjoiNDU2IiwiWC1J\nTlNUQU5BLUwiOiIxIn0=\n"
355
+ )
356
+ mock_event = {
357
+ "Invoked" => true
358
+ }
359
+
360
+ @subject.wrap_aws(mock_event, mock_context) { 0 }
361
+
362
+ lambda_span, *rest = Instana.processor.queued_spans
363
+ assert rest.empty?
364
+
365
+ refute_equal 'aws.lambda.invoke', lambda_span[:data][:lambda][:trigger]
366
+ refute_equal '123', lambda_span[:t]
367
+ refute_equal '456', lambda_span[:p]
368
+ end
323
369
  end
@@ -7,7 +7,9 @@ require "net/http"
7
7
  class FastJob
8
8
  @queue = :critical
9
9
 
10
- def self.perform
10
+ def self.perform(*args)
11
+ raise 'Invalid Args' unless args.empty?
12
+
11
13
  if ENV.key?('REDIS_URL')
12
14
  redis = Redis.new(:url => ENV['REDIS_URL'])
13
15
  elsif ENV.key?('REDIS_URL')
data/test/test_helper.rb CHANGED
@@ -50,5 +50,14 @@ WebMock.disable_net_connect!(
50
50
 
51
51
  Dir['test/support/*.rb'].each { |f| load(f) }
52
52
 
53
- Minitest::Reporters.use! MiniTest::Reporters::SpecReporter.new
53
+ if ENV['CI']
54
+ Minitest::Reporters.use!([
55
+ Minitest::Reporters::JUnitReporter.new('_junit', false),
56
+ Minitest::Reporters::SpecReporter.new
57
+ ])
58
+ else
59
+ Minitest::Reporters.use!([
60
+ MiniTest::Reporters::SpecReporter.new
61
+ ])
62
+ end
54
63
  Minitest::Test.include(Instana::TestHelpers)
@@ -0,0 +1,39 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ require 'test_helper'
5
+
6
+ class InstrumentedLoggerTest < Minitest::Test
7
+ def setup
8
+ clear_all!
9
+ end
10
+
11
+ def test_log_warn_error
12
+ subject = Instana::InstrumentedLogger.new('/dev/null')
13
+
14
+ Instana::Tracer.start_or_continue_trace(:test_logging) do
15
+ subject.warn('warn')
16
+ subject.debug('test')
17
+ subject.error('error')
18
+ end
19
+
20
+ spans = ::Instana.processor.queued_spans
21
+
22
+ warn_span, error_span, = *spans
23
+
24
+ assert_equal :log, warn_span[:n]
25
+ assert_equal 'warn', warn_span[:data][:log][:message]
26
+ assert_equal 'Warn', warn_span[:data][:log][:level]
27
+
28
+ assert_equal :log, error_span[:n]
29
+ assert_equal 'error', error_span[:data][:log][:message]
30
+ assert_equal 'Error', error_span[:data][:log][:level]
31
+ end
32
+
33
+ def test_no_trace
34
+ subject = Instana::InstrumentedLogger.new('/dev/null')
35
+ subject.warn('warn')
36
+
37
+ assert_equal [], ::Instana.processor.queued_spans
38
+ end
39
+ end
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.201.0
4
+ version: 1.204.0.pre1
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: 2021-06-09 00:00:00.000000000 Z
11
+ date: 2021-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -135,6 +135,8 @@ files:
135
135
  - ".codeclimate.yml"
136
136
  - ".editorconfig"
137
137
  - ".fasterer.yml"
138
+ - ".github/ISSUE_TEMPLATE/bug.yml"
139
+ - ".github/ISSUE_TEMPLATE/config.yml"
138
140
  - ".gitignore"
139
141
  - ".rubocop.yml"
140
142
  - ".rubocop_todo.yml"
@@ -182,10 +184,12 @@ files:
182
184
  - lib/instana/activators/action_cable.rb
183
185
  - lib/instana/activators/action_controller_api.rb
184
186
  - lib/instana/activators/action_controller_base.rb
187
+ - lib/instana/activators/action_mailer.rb
185
188
  - lib/instana/activators/action_view.rb
186
189
  - lib/instana/activators/active_job.rb
187
190
  - lib/instana/activators/active_record.rb
188
191
  - lib/instana/activators/aws_sdk_dynamodb.rb
192
+ - lib/instana/activators/aws_sdk_lambda.rb
189
193
  - lib/instana/activators/aws_sdk_s3.rb
190
194
  - lib/instana/activators/aws_sdk_sns.rb
191
195
  - lib/instana/activators/aws_sdk_sqs.rb
@@ -224,10 +228,12 @@ files:
224
228
  - lib/instana/frameworks/sinatra.rb
225
229
  - lib/instana/instrumentation/action_cable.rb
226
230
  - lib/instana/instrumentation/action_controller.rb
231
+ - lib/instana/instrumentation/action_mailer.rb
227
232
  - lib/instana/instrumentation/action_view.rb
228
233
  - lib/instana/instrumentation/active_job.rb
229
234
  - lib/instana/instrumentation/active_record.rb
230
235
  - lib/instana/instrumentation/aws_sdk_dynamodb.rb
236
+ - lib/instana/instrumentation/aws_sdk_lambda.rb
231
237
  - lib/instana/instrumentation/aws_sdk_s3.rb
232
238
  - lib/instana/instrumentation/aws_sdk_sns.rb
233
239
  - lib/instana/instrumentation/aws_sdk_sqs.rb
@@ -244,6 +250,7 @@ files:
244
250
  - lib/instana/instrumentation/shoryuken.rb
245
251
  - lib/instana/instrumentation/sidekiq-client.rb
246
252
  - lib/instana/instrumentation/sidekiq-worker.rb
253
+ - lib/instana/instrumented_logger.rb
247
254
  - lib/instana/logger_delegator.rb
248
255
  - lib/instana/open_tracing/carrier.rb
249
256
  - lib/instana/open_tracing/instana_tracer.rb
@@ -295,8 +302,10 @@ files:
295
302
  - test/instrumentation/rack_test.rb
296
303
  - test/instrumentation/rails_action_cable_test.rb
297
304
  - test/instrumentation/rails_action_controller_test.rb
305
+ - test/instrumentation/rails_action_mailer_test.rb
298
306
  - test/instrumentation/rails_action_view_test.rb
299
307
  - test/instrumentation/rails_active_job_test.rb
308
+ - test/instrumentation/rails_active_record_database_missing_test.rb
300
309
  - test/instrumentation/rails_active_record_test.rb
301
310
  - test/instrumentation/redis_test.rb
302
311
  - test/instrumentation/resque_test.rb
@@ -334,6 +343,7 @@ files:
334
343
  - test/test_helper.rb
335
344
  - test/tracing/custom_test.rb
336
345
  - test/tracing/id_management_test.rb
346
+ - test/tracing/instrumented_logger_test.rb
337
347
  - test/tracing/opentracing_test.rb
338
348
  - test/tracing/processor_test.rb
339
349
  - test/tracing/span_context_test.rb
@@ -360,9 +370,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
360
370
  version: '2.1'
361
371
  required_rubygems_version: !ruby/object:Gem::Requirement
362
372
  requirements:
363
- - - ">="
373
+ - - ">"
364
374
  - !ruby/object:Gem::Version
365
- version: '0'
375
+ version: 1.3.1
366
376
  requirements: []
367
377
  rubygems_version: 3.1.6
368
378
  signing_key:
@@ -396,8 +406,10 @@ test_files:
396
406
  - test/instrumentation/rack_test.rb
397
407
  - test/instrumentation/rails_action_cable_test.rb
398
408
  - test/instrumentation/rails_action_controller_test.rb
409
+ - test/instrumentation/rails_action_mailer_test.rb
399
410
  - test/instrumentation/rails_action_view_test.rb
400
411
  - test/instrumentation/rails_active_job_test.rb
412
+ - test/instrumentation/rails_active_record_database_missing_test.rb
401
413
  - test/instrumentation/rails_active_record_test.rb
402
414
  - test/instrumentation/redis_test.rb
403
415
  - test/instrumentation/resque_test.rb
@@ -435,6 +447,7 @@ test_files:
435
447
  - test/test_helper.rb
436
448
  - test/tracing/custom_test.rb
437
449
  - test/tracing/id_management_test.rb
450
+ - test/tracing/instrumented_logger_test.rb
438
451
  - test/tracing/opentracing_test.rb
439
452
  - test/tracing/processor_test.rb
440
453
  - test/tracing/span_context_test.rb