scout_apm 2.2.0.pre2 → 2.2.0.pre3

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
  SHA1:
3
- metadata.gz: 9b1ea1128aa9aa0aa0b5086860810f324ffe732c
4
- data.tar.gz: 00e3f0e517bfb8b580205bd7709a040fd13d611a
3
+ metadata.gz: b4fa1f78b691cca73f89e5f79902cdc097633773
4
+ data.tar.gz: da4c781988cd5996d6d565b42d5ce25e90e4608a
5
5
  SHA512:
6
- metadata.gz: bea83409eb9f21cccbfc9aeeeeae3f4a22113cfdd13fa1f51ede6df3422ed5a0d2b7a15d922c7d132632c486430372c68616482b9d2356fd80689ba0cf9d74e8
7
- data.tar.gz: 43c32ce10c3e01134904e19a1d2068c1b4a06ac928d44dbb3f1fd46e781ab98414737f9c004858f3ced00fe29534f91af0804f9b2559364ac3e15ad856020918
6
+ metadata.gz: dc8f935276423d6cb568af1dded73c38af744747b07fb8ed390a0f3f968c6ff7188e912da1acd1c3599d683a1ee8160196ff7756c2b55c384b4584342e677ca9
7
+ data.tar.gz: e5709ffa058e1ffed9d16bc37733f38c0d777f1d33d597447f2d38c7a168635ecbca9d13540be7baa3a8e84a8f082b68ce23b2a62b3d92b7cb0c103010443bc5
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ # 80 is stifling, especially with a few levels of nesting before we even start.
2
+ # So bump it to 100 to keep really long lines from creeping in.
3
+ Metrics/LineLength:
4
+ Max: 100
5
+
6
+ Style/UseHashRocketsWithSymbolValues: false
7
+
8
+
data/CHANGELOG.markdown CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  * ScoutProf BETA
4
4
 
5
+ # 2.1.4
6
+
7
+ * Enhance regular expression that determines if a backtrace line is "inside"
8
+ the application
9
+ * Avoids labeling vendor/ as part of the monitored app
10
+
11
+ # 2.1.3
12
+
13
+ * Less noisy output on errors with Context
14
+ * Not logging errors w/nil keys or values
15
+ * Bumping log level down from WARN => INFO on errors
16
+ * Fix error with complicated AR queries
17
+ * Caused high log noise
18
+ * Sidekiq instrumentation changes to handle a variety of edge cases
19
+
20
+ # 2.1.2
21
+
22
+ * Applies `Rails.application.config.filter_parameters` settings to reported transaction trace uris
23
+ * Fix incompatibility with ResqueWeb and middleware instrumentation
24
+
5
25
  # 2.1.1
6
26
 
7
27
  * Fix an issue with AR instrumentation and complex queries
@@ -8,7 +8,7 @@ module ScoutApm
8
8
  end
9
9
 
10
10
  def present?
11
- defined?(::Sidekiq) && (File.basename($0) =~ /\Asidekiq/)
11
+ defined?(::Sidekiq) && File.basename($PROGRAM_NAME).start_with?('sidekiq')
12
12
  end
13
13
 
14
14
  def forking?
@@ -16,22 +16,33 @@ module ScoutApm
16
16
  end
17
17
 
18
18
  def install
19
+ install_tracer
20
+ add_middleware
21
+ install_processor
22
+ end
23
+
24
+ def install_tracer
19
25
  # ScoutApm::Tracer is not available when this class is defined
20
26
  SidekiqMiddleware.class_eval do
21
27
  include ScoutApm::Tracer
22
28
  end
29
+ end
23
30
 
31
+ def add_middleware
24
32
  ::Sidekiq.configure_server do |config|
25
33
  config.server_middleware do |chain|
26
34
  chain.add SidekiqMiddleware
27
35
  end
28
36
  end
37
+ end
29
38
 
39
+ def install_processor
30
40
  require 'sidekiq/processor' # sidekiq v4 has not loaded this file by this point
31
41
 
32
42
  ::Sidekiq::Processor.class_eval do
33
43
  def initialize_with_scout(boss)
34
- ::ScoutApm::Agent.instance.start_background_worker unless ::ScoutApm::Agent.instance.background_worker_running?
44
+ agent = ::ScoutApm::Agent.instance
45
+ agent.start_background_worker
35
46
  initialize_without_scout(boss)
36
47
  end
37
48
 
@@ -41,21 +52,18 @@ module ScoutApm
41
52
  end
42
53
  end
43
54
 
55
+ # We insert this middleware into the Sidekiq stack, to capture each job,
56
+ # and time them.
44
57
  class SidekiqMiddleware
45
- def call(worker, msg, queue)
46
- job_class = msg["class"] # TODO: Validate this across different versions of Sidekiq
47
- if job_class == "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper" && msg.has_key?("wrapped")
48
- job_class = msg["wrapped"]
49
- end
50
-
51
- latency = (Time.now.to_f - (msg['enqueued_at'] || msg['created_at']))
58
+ ACTIVE_JOB_KLASS = 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper'.freeze
52
59
 
60
+ def call(_worker, msg, queue)
53
61
  req = ScoutApm::RequestManager.lookup
54
62
  req.job!
55
- req.annotate_request(:queue_latency => latency)
63
+ req.annotate_request(:queue_latency => latency(msg))
56
64
 
57
- queue_layer = ScoutApm::Layer.new("Queue", queue)
58
- job_layer = ScoutApm::Layer.new("Job", job_class)
65
+ queue_layer = ScoutApm::Layer.new('Queue', queue)
66
+ job_layer = ScoutApm::Layer.new('Job', job_class(msg))
59
67
 
60
68
  if ScoutApm::Agent.instance.config.value('profile') && SidekiqMiddleware.version_supports_profiling?
61
69
  # Capture ScoutProf if we can
@@ -64,18 +72,43 @@ module ScoutApm
64
72
  #job_layer.traced!
65
73
  end
66
74
 
67
- req.start_layer(queue_layer)
68
- req.start_layer(job_layer)
69
-
70
75
  begin
76
+ req.start_layer(queue_layer)
77
+ started_queue = true
78
+ req.start_layer(job_layer)
79
+ started_job = true
80
+
71
81
  yield
72
82
  rescue
73
83
  req.error!
74
84
  raise
85
+ ensure
86
+ req.stop_layer if started_job
87
+ req.stop_layer if started_queue
88
+ end
89
+ end
90
+
91
+ UNKNOWN_CLASS_PLACEHOLDER = 'UnknownJob'.freeze
92
+
93
+ def job_class(msg)
94
+ job_class = msg.fetch('class', UNKNOWN_CLASS_PLACEHOLDER)
95
+ if job_class == ACTIVE_JOB_KLASS && msg.key?('wrapped')
96
+ job_class = msg['wrapped']
97
+ end
98
+ job_class
99
+ rescue
100
+ UNKNOWN_CLASS_PLACEHOLDER
101
+ end
102
+
103
+ def latency(msg, time = Time.now.to_f)
104
+ created_at = msg['enqueued_at'] || msg['created_at']
105
+ if created_at
106
+ (time - created_at)
107
+ else
108
+ 0
75
109
  end
76
- ensure
77
- req.stop_layer # Job
78
- req.stop_layer # Queue
110
+ rescue
111
+ 0
79
112
  end
80
113
 
81
114
  def self.version_supports_profiling?
@@ -75,8 +75,10 @@ module ScoutApm
75
75
  def value_valid?(key_value)
76
76
  # ensure one of our accepted types.
77
77
  value = key_value.values.last
78
- if !valid_type?([String, Symbol, Numeric, Time, Date, TrueClass, FalseClass],value)
79
- ScoutApm::Agent.instance.logger.warn "The value for [#{key_value.keys.first}] is not a valid type [#{value.class}]."
78
+ if value.nil?
79
+ false # don't log this ... easy to happen
80
+ elsif !valid_type?([String, Symbol, Numeric, Time, Date, TrueClass, FalseClass],value)
81
+ ScoutApm::Agent.instance.logger.info "The value for [#{key_value.keys.first}] is not a valid type [#{value.class}]."
80
82
  false
81
83
  else
82
84
  true
@@ -86,14 +88,16 @@ module ScoutApm
86
88
  # for consistently with #value_valid?, takes a hash eventhough the value isn't yet used.
87
89
  def key_valid?(key_value)
88
90
  key = key_value.keys.first
91
+ if key.nil?
92
+ false # don't log this ... easy to happen
89
93
  # ensure a string or a symbol
90
- if !valid_type?([String, Symbol],key)
91
- ScoutApm::Agent.instance.logger.warn "The key [#{key}] is not a valid type [#{key.class}]."
94
+ elsif !valid_type?([String, Symbol],key)
95
+ ScoutApm::Agent.instance.logger.info "The key [#{key}] is not a valid type [#{key.class}]."
92
96
  return false
93
97
  end
94
98
  # only alphanumeric, dash, and underscore allowed.
95
99
  if key.to_s.match(/[^\w-]/)
96
- ScoutApm::Agent.instance.logger.warn "They key name [#{key}] is not valid."
100
+ ScoutApm::Agent.instance.logger.info "They key name [#{key}] is not valid."
97
101
  return false
98
102
  end
99
103
  true
@@ -48,8 +48,7 @@ module ScoutApm
48
48
  # specific controller actions.
49
49
  def perform_action_with_scout_instruments(*args, &block)
50
50
  req = ScoutApm::RequestManager.lookup
51
- path = ScoutApm::Agent.instance.config.value("uri_reporting") == 'path' ? request.path : request.fullpath
52
- req.annotate_request(:uri => path)
51
+ req.annotate_request(:uri => request.path) # for security by-default, we don't use request.fullpath which could reveal filtered params.
53
52
  req.context.add_user(:ip => request.remote_ip)
54
53
  req.set_headers(request.headers)
55
54
  req.start_layer( ScoutApm::Layer.new("Controller", "#{controller_path}/#{action_name}") )
@@ -60,8 +60,7 @@ module ScoutApm
60
60
  module ActionControllerRails3Rails4Instruments
61
61
  def process_action(*args)
62
62
  req = ScoutApm::RequestManager.lookup
63
- path = ScoutApm::Agent.instance.config.value("uri_reporting") == 'path' ? request.path : request.fullpath
64
- req.annotate_request(:uri => path)
63
+ req.annotate_request(:uri => scout_transaction_uri(request))
65
64
 
66
65
  # IP Spoofing Protection can throw an exception, just move on w/o remote ip
67
66
  req.context.add_user(:ip => request.remote_ip) rescue nil
@@ -95,8 +94,19 @@ module ScoutApm
95
94
  ensure
96
95
  req.stop_layer
97
96
  end
97
+ end # process_action
98
+
99
+ # Given an +ActionDispatch::Request+, formats the uri based on config settings.
100
+ def scout_transaction_uri(request)
101
+ case ScoutApm::Agent.instance.config.value("uri_reporting")
102
+ when 'path'
103
+ request.path # strips off the query string for more security
104
+ else # default handles filtered params
105
+ request.filtered_path
106
+ end
98
107
  end
99
- end
108
+
109
+ end # ActionControllerRails3Rails4Instruments
100
110
  end
101
111
  end
102
112
 
@@ -23,7 +23,15 @@ module ScoutApm
23
23
  ActionDispatch::MiddlewareStack.class_eval do
24
24
  def build_with_scout_instruments(app = nil, &block)
25
25
  mw_stack = build_without_scout_instruments(app) { block.call if block }
26
- MiddlewareSummaryWrapper.new(mw_stack)
26
+ if app == mw_stack
27
+ # Return the raw middleware stack if it equaled app. No
28
+ # middlewares were created, so nothing to wrap & test.
29
+ #
30
+ # Avoids instrumentation of something that doesn't exist
31
+ mw_stack
32
+ else
33
+ MiddlewareSummaryWrapper.new(mw_stack)
34
+ end
27
35
  end
28
36
 
29
37
  alias_method :build_without_scout_instruments, :build
@@ -45,6 +53,36 @@ module ScoutApm
45
53
  ensure
46
54
  req.stop_layer
47
55
  end
56
+
57
+ # Some code (found in resque_web initially) attempts to call methods
58
+ # directly on `MyApplication.app`, which is the middleware stack.
59
+ # If it hits our middleware instead of the object at the root of the
60
+ # app that it expected, then a method it expects will not be there, and an
61
+ # error thrown.
62
+ #
63
+ # Specifically, resque_web assumes `ResqueWeb::Engine.app.url_helpers`
64
+ # is a method call on rails router for its own Engine, when in fact,
65
+ # we've added a middleware before it.
66
+ #
67
+ # So method_missing just proxies anything to the nested @app object
68
+ #
69
+ # While method_missing is not very performant, this is only here to
70
+ # handle edge-cases in other code, and should not be regularly called
71
+ def method_missing(sym, *arguments, &block)
72
+ if @app.respond_to?(sym)
73
+ @app.send(sym, *arguments, &block)
74
+ else
75
+ super
76
+ end
77
+ end
78
+
79
+ def respond_to?(sym, include_private = false)
80
+ if @app.respond_to?(sym, include_private)
81
+ true
82
+ else
83
+ super
84
+ end
85
+ end
48
86
  end
49
87
  end
50
88
  end
@@ -47,7 +47,7 @@ module ScoutApm
47
47
  @layers = []
48
48
  @call_set = Hash.new { |h, k| h[k] = CallSet.new }
49
49
  @annotations = {}
50
- @ignoring_children = false
50
+ @ignoring_children = 0
51
51
  @context = Context.new
52
52
  @root_layer = nil
53
53
  @error = false
@@ -323,27 +323,41 @@ module ScoutApm
323
323
  # specific, and useful than the fact that InfluxDB happens to use Net::HTTP
324
324
  # internally
325
325
  #
326
- # When enabled, new layers won't be added to the current Request.
326
+ # When enabled, new layers won't be added to the current Request, and calls
327
+ # to stop_layer will be ignored.
327
328
  #
328
329
  # Do not forget to turn if off when leaving a layer, it is the
329
330
  # instrumentation's task to do that.
331
+ #
332
+ # When you use this in code, be sure to use it in this order:
333
+ #
334
+ # start_layer
335
+ # ignore_children
336
+ # -> call
337
+ # acknowledge_children
338
+ # stop_layer
339
+ #
340
+ # If you don't call it in this order, it's possible to get out of sync, and
341
+ # have an ignored start and an actually-executed stop, causing layers to
342
+ # get out of sync
330
343
 
331
344
  def ignore_children!
332
- @ignoring_children = true
345
+ @ignoring_children += 1
333
346
  end
334
347
 
335
348
  def acknowledge_children!
336
- @ignoring_children = false
349
+ if @ignoring_children > 0
350
+ @ignoring_children -= 1
351
+ end
337
352
  end
338
353
 
339
354
  def ignoring_children?
340
- @ignoring_children
355
+ @ignoring_children > 0
341
356
  end
342
357
 
343
358
  # Grab backtraces more aggressively when running in dev trace mode
344
359
  def backtrace_threshold
345
360
  dev_trace ? 0.05 : 0.5 # the minimum threshold in seconds to record the backtrace for a metric.
346
361
  end
347
-
348
362
  end
349
363
  end
@@ -14,7 +14,10 @@ module ScoutApm
14
14
  def initialize(call_stack, root=ScoutApm::Environment.instance.root)
15
15
  @call_stack = call_stack
16
16
  # We can't use a constant as it'd be too early to fetch environment info
17
- @@app_dir_regex = %r|#{root}/(.*)|
17
+ #
18
+ # This regex looks for files under the app root, inside lib/, app/, and
19
+ # config/ dirs, and captures the path under root.
20
+ @@app_dir_regex = %r[#{root}/((?:lib/|app/|config/).*)]
18
21
  end
19
22
 
20
23
  def call
@@ -27,7 +30,6 @@ module ScoutApm
27
30
  end
28
31
  stack
29
32
  end
30
-
31
33
  end
32
34
  end
33
35
  end
@@ -1,4 +1,4 @@
1
1
  module ScoutApm
2
- VERSION = "2.2.0.pre2"
2
+ VERSION = "2.2.0.pre3"
3
3
  end
4
4
 
data/scout_apm.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_runtime_dependency "rusage", '~> 0.2.0'
25
25
 
26
26
  s.add_development_dependency "minitest"
27
+ s.add_development_dependency 'mocha'
27
28
  s.add_development_dependency "pry"
28
29
  s.add_development_dependency "m"
29
30
  s.add_development_dependency "simplecov"
data/test/test_helper.rb CHANGED
@@ -5,6 +5,7 @@ SimpleCov.start
5
5
  require 'minitest/autorun'
6
6
  require 'minitest/unit'
7
7
  require 'minitest/pride'
8
+ require 'mocha/mini_test'
8
9
  require 'pry'
9
10
 
10
11
 
@@ -82,4 +83,3 @@ class Minitest::Test
82
83
  DATA_FILE_PATH = "#{DATA_FILE_DIR}/scout_apm.db"
83
84
  end
84
85
 
85
-
@@ -0,0 +1,104 @@
1
+ require 'test_helper'
2
+ require 'scout_apm/request_manager'
3
+ require 'scout_apm/background_job_integrations/sidekiq'
4
+
5
+ class SidekiqTest < Minitest::Test
6
+ SidekiqMiddleware = ScoutApm::BackgroundJobIntegrations::SidekiqMiddleware
7
+
8
+ ########################################
9
+ # Middleware
10
+ ########################################
11
+ def test_middleware_call_happy_path
12
+ fake_request = mock
13
+ fake_request.expects(:annotate_request)
14
+ fake_request.expects(:job!)
15
+ fake_request.expects(:start_layer).twice
16
+ fake_request.expects(:stop_layer).twice
17
+ fake_request.expects(:error!).never
18
+
19
+ ScoutApm::RequestManager.stubs(:lookup).returns(fake_request)
20
+
21
+ block_called = false
22
+ msg = { 'class' => 'MyJobClass',
23
+ 'created_at' => Time.now }
24
+
25
+ SidekiqMiddleware.new.call(nil, msg, "defaultqueue") { block_called = true }
26
+ assert_equal true, block_called
27
+ end
28
+
29
+ def test_middleware_call_job_exception
30
+ fake_request = mock
31
+ fake_request.expects(:annotate_request)
32
+ fake_request.expects(:job!)
33
+ fake_request.expects(:start_layer).twice
34
+ fake_request.expects(:stop_layer).twice
35
+ fake_request.expects(:error!)
36
+
37
+ ScoutApm::RequestManager.stubs(:lookup).returns(fake_request)
38
+
39
+ msg = { 'class' => 'MyJobClass',
40
+ 'created_at' => Time.now }
41
+
42
+ assert_raises RuntimeError do
43
+ SidekiqMiddleware.new.call(nil, msg, "defaultqueue") { raise "TheJobFailed" }
44
+ end
45
+ end
46
+
47
+ def test_middleware_call_edge_cases
48
+ fake_request = mock
49
+ fake_request.expects(:annotate_request)
50
+ fake_request.expects(:job!)
51
+ fake_request.expects(:start_layer).twice
52
+ fake_request.expects(:stop_layer).twice
53
+ fake_request.expects(:error!)
54
+
55
+ ScoutApm::RequestManager.stubs(:lookup).returns(fake_request)
56
+
57
+ # msg doesn't have anything
58
+ msg = { }
59
+
60
+ assert_raises RuntimeError do
61
+ SidekiqMiddleware.new.call(nil, msg, "defaultqueue") { raise "TheJobFailed" }
62
+ end
63
+ end
64
+
65
+ ########################################
66
+ # Job Class Determination
67
+ ########################################
68
+ def test_job_class_name_normally
69
+ msg = { 'class' => 'AGreatJob' }
70
+ assert_equal 'AGreatJob', SidekiqMiddleware.new.job_class(msg)
71
+ end
72
+
73
+ def test_job_class_name_activejob
74
+ msg = { 'class' => 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper',
75
+ 'wrapped' => 'RealJobClass' }
76
+ assert_equal 'RealJobClass', SidekiqMiddleware.new.job_class(msg)
77
+ end
78
+
79
+ def test_job_class_name_error_default
80
+ msg = {}
81
+ assert_equal 'UnknownJob', SidekiqMiddleware.new.job_class(msg)
82
+ end
83
+
84
+ ########################################
85
+ # Latency Calculation
86
+ ########################################
87
+ def test_latency_from_created_at
88
+ # Created at time 80, but now it is 200. Latency was 120
89
+ msg = { 'created_at' => 80 }
90
+ assert_equal 120, SidekiqMiddleware.new.latency(msg, 200)
91
+ end
92
+
93
+ def test_latency_from_enqueued_at
94
+ # Created at time 80, but now it is 200. Latency was 120
95
+ msg = { 'enqueued_at' => 80 }
96
+ assert_equal 120, SidekiqMiddleware.new.latency(msg, 200)
97
+ end
98
+
99
+ def test_latency_fallback
100
+ # No created at time, so fall back to 0
101
+ msg = {}
102
+ assert_equal 0, SidekiqMiddleware.new.latency(msg, 200)
103
+ end
104
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+
3
+ require 'scout_apm/context'
4
+
5
+ class ContextText < Minitest::Test
6
+ def test_ignore_nil_value
7
+ context = ScoutApm::Context.new
8
+ assert hash = context.add(:nil_key => nil, :org => 'org')
9
+ assert_equal ({:org => 'org'}), hash
10
+ end
11
+
12
+ def test_ignore_nil_key
13
+ context = ScoutApm::Context.new
14
+ assert hash = context.add(nil => nil, :org => 'org')
15
+ assert_equal ({:org => 'org'}), hash
16
+ end
17
+
18
+ def test_ignore_unsupported_value_type
19
+ context = ScoutApm::Context.new
20
+ assert hash = context.add(:array => [1,2,3,4], :org => 'org')
21
+ assert_equal ({:org => 'org'}), hash
22
+ end
23
+
24
+ def test_ignore_unsupported_key_type
25
+ context = ScoutApm::Context.new
26
+ assert hash = context.add([1,2,3,4] => 'hey', :org => 'org')
27
+ assert_equal ({:org => 'org'}), hash
28
+ end
29
+ end
30
+
@@ -49,4 +49,18 @@ class BacktraceParserTest < Minitest::Test
49
49
  result = ScoutApm::Utils::BacktraceParser.new(raw_backtrace, "/Users/scout/different-secrets").call
50
50
  assert_equal 0, result.length
51
51
  end
52
+
53
+ def test_excludes_vendor_paths
54
+ raw_backtrace = [
55
+ "#{root}/vendor/ruby/thing.rb",
56
+ "#{root}/app/controllers/users_controller.rb",
57
+ "#{root}/vendor/ruby/thing.rb",
58
+ "#{root}/config/initializers/inject_something.rb",
59
+ ]
60
+ result = ScoutApm::Utils::BacktraceParser.new(raw_backtrace, root).call
61
+
62
+ assert_equal 2, result.length
63
+ assert_equal false, (result[0] =~ %r|app/controllers/users_controller.rb|).nil?
64
+ assert_equal false, (result[1] =~ %r|config/initializers/inject_something.rb|).nil?
65
+ end
52
66
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout_apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0.pre2
4
+ version: 2.2.0.pre3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Haynes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-08-22 00:00:00.000000000 Z
12
+ date: 2016-08-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rusage
@@ -39,6 +39,20 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: mocha
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: pry
44
58
  requirement: !ruby/object:Gem::Requirement
@@ -105,6 +119,7 @@ extensions:
105
119
  extra_rdoc_files: []
106
120
  files:
107
121
  - ".gitignore"
122
+ - ".rubocop.yml"
108
123
  - CHANGELOG.markdown
109
124
  - Gemfile
110
125
  - LICENSE.md
@@ -229,7 +244,9 @@ files:
229
244
  - test/data/config_test_1.yml
230
245
  - test/test_helper.rb
231
246
  - test/unit/agent_test.rb
247
+ - test/unit/background_job_integrations/sidekiq_test.rb
232
248
  - test/unit/config_test.rb
249
+ - test/unit/context_test.rb
233
250
  - test/unit/environment_test.rb
234
251
  - test/unit/histogram_test.rb
235
252
  - test/unit/ignored_uris_test.rb