elastic-apm 0.6.2 → 0.7.0
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.
Potentially problematic release.
This version of elastic-apm might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.rubocop.yml +3 -0
- data/Gemfile +0 -3
- data/elastic-apm.gemspec +1 -2
- data/lib/elastic_apm/agent.rb +13 -8
- data/lib/elastic_apm/config.rb +7 -6
- data/lib/elastic_apm/context_builder.rb +1 -1
- data/lib/elastic_apm/error_builder.rb +13 -5
- data/lib/elastic_apm/instrumenter.rb +10 -9
- data/lib/elastic_apm/middleware.rb +4 -3
- data/lib/elastic_apm/normalizers/active_record.rb +2 -2
- data/lib/elastic_apm/railtie.rb +10 -3
- data/lib/elastic_apm/{injectors.rb → spies.rb} +17 -17
- data/lib/elastic_apm/{injectors → spies}/action_dispatch.rb +3 -3
- data/lib/elastic_apm/{injectors → spies}/delayed_job.rb +4 -4
- data/lib/elastic_apm/{injectors → spies}/elasticsearch.rb +3 -3
- data/lib/elastic_apm/{injectors → spies}/json.rb +3 -3
- data/lib/elastic_apm/{injectors → spies}/mongo.rb +9 -5
- data/lib/elastic_apm/{injectors → spies}/net_http.rb +3 -3
- data/lib/elastic_apm/{injectors → spies}/redis.rb +3 -3
- data/lib/elastic_apm/{injectors → spies}/sequel.rb +4 -4
- data/lib/elastic_apm/{injectors → spies}/sidekiq.rb +10 -7
- data/lib/elastic_apm/{injectors → spies}/sinatra.rb +4 -4
- data/lib/elastic_apm/{injectors → spies}/tilt.rb +3 -3
- data/lib/elastic_apm/sql_summarizer.rb +10 -5
- data/lib/elastic_apm/stacktrace.rb +1 -105
- data/lib/elastic_apm/stacktrace/frame.rb +1 -5
- data/lib/elastic_apm/stacktrace_builder.rb +98 -0
- data/lib/elastic_apm/subscriber.rb +2 -3
- data/lib/elastic_apm/timed_worker.rb +4 -0
- data/lib/elastic_apm/transaction.rb +6 -2
- data/lib/elastic_apm/util/inflector.rb +45 -11
- data/lib/elastic_apm/version.rb +1 -1
- metadata +16 -30
- data/lib/elastic_apm/stacktrace/line_cache.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09106c431ff50c403a81c2013f49d9b6dfb17a23fefd88a1643919322dcf4ebe'
|
4
|
+
data.tar.gz: 4d3bde4e2bbd1de3dba89e992cd4ff032ad8580b82bce0b3d22eed5ce7c11f12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2f6b1e3e0da8311d54801cc8f9e84f2e9d6b119652a97e86549fdb9ddc03cab252830507c8c2489fbddb77e2903139490c710753f29a2f40357c65803575d53
|
7
|
+
data.tar.gz: 18050a76699c39f5cda9783a4c8eefb4443d2eefef61f5eaaf5107128f54806a34e6460271c63076425235eb86f408ca6663c9609a6547e969ff30f8eda0e5c6
|
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/elastic-apm.gemspec
CHANGED
@@ -14,10 +14,9 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.license = 'Apache-2.0'
|
15
15
|
spec.required_ruby_version = ">= 2.2.0"
|
16
16
|
|
17
|
-
spec.add_dependency('activesupport', '>= 3.0.0')
|
18
|
-
|
19
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
20
18
|
f.match(%r{^(test|spec|features)/})
|
21
19
|
end
|
20
|
+
|
22
21
|
spec.require_paths = ['lib']
|
23
22
|
end
|
data/lib/elastic_apm/agent.rb
CHANGED
@@ -3,9 +3,10 @@
|
|
3
3
|
require 'elastic_apm/naively_hashable'
|
4
4
|
require 'elastic_apm/context_builder'
|
5
5
|
require 'elastic_apm/error_builder'
|
6
|
+
require 'elastic_apm/stacktrace_builder'
|
6
7
|
require 'elastic_apm/error'
|
7
8
|
require 'elastic_apm/http'
|
8
|
-
require 'elastic_apm/
|
9
|
+
require 'elastic_apm/spies'
|
9
10
|
require 'elastic_apm/serializers'
|
10
11
|
require 'elastic_apm/timed_worker'
|
11
12
|
|
@@ -58,26 +59,28 @@ module ElasticAPM
|
|
58
59
|
|
59
60
|
def initialize(config)
|
60
61
|
@config = config
|
62
|
+
@http = Http.new(config)
|
61
63
|
|
62
64
|
@messages = Queue.new
|
63
65
|
@pending_transactions = Queue.new
|
64
|
-
@http = Http.new(config)
|
65
66
|
|
66
|
-
@instrumenter = Instrumenter.new(
|
67
|
-
|
68
|
-
@
|
67
|
+
@instrumenter = Instrumenter.new(self)
|
68
|
+
|
69
|
+
@context_builder = ContextBuilder.new(self)
|
70
|
+
@error_builder = ErrorBuilder.new(self)
|
71
|
+
@stacktrace_builder = StacktraceBuilder.new(self)
|
69
72
|
end
|
70
73
|
|
71
74
|
attr_reader :config, :messages, :pending_transactions, :instrumenter,
|
72
|
-
:context_builder, :http
|
75
|
+
:context_builder, :stacktrace_builder, :http
|
73
76
|
|
74
77
|
def start
|
75
78
|
debug '[%s] Starting agent, reporting to %s', VERSION, config.server_url
|
76
79
|
|
77
80
|
@instrumenter.start
|
78
81
|
|
79
|
-
config.
|
80
|
-
require "elastic_apm/
|
82
|
+
config.enabled_spies.each do |lib|
|
83
|
+
require "elastic_apm/spies/#{lib}"
|
81
84
|
end
|
82
85
|
|
83
86
|
self
|
@@ -95,6 +98,8 @@ module ElasticAPM
|
|
95
98
|
stop
|
96
99
|
end
|
97
100
|
|
101
|
+
# queues
|
102
|
+
|
98
103
|
def enqueue_transaction(transaction)
|
99
104
|
boot_worker unless worker_running?
|
100
105
|
|
data/lib/elastic_apm/config.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'logger'
|
4
|
+
require 'yaml'
|
4
5
|
|
5
6
|
module ElasticAPM
|
6
7
|
# rubocop:disable Metrics/ClassLength
|
@@ -36,7 +37,7 @@ module ElasticAPM
|
|
36
37
|
source_lines_error_library_frames: 0,
|
37
38
|
source_lines_span_library_frames: 0,
|
38
39
|
|
39
|
-
|
40
|
+
disabled_spies: %w[json],
|
40
41
|
|
41
42
|
current_user_id_method: :id,
|
42
43
|
current_user_email_method: :email,
|
@@ -74,7 +75,7 @@ module ElasticAPM
|
|
74
75
|
'ELASTIC_APM_VERIFY_SERVER_CERT' => [:bool, 'verify_server_cert'],
|
75
76
|
'ELASTIC_APM_TRANSACTION_MAX_SPANS' => [:int, 'transaction_max_spans'],
|
76
77
|
|
77
|
-
'
|
78
|
+
'ELASTIC_APM_DISABLED_SPIES' => [:list, 'disabled_spies']
|
78
79
|
}.freeze
|
79
80
|
|
80
81
|
def initialize(options = {})
|
@@ -123,7 +124,7 @@ module ElasticAPM
|
|
123
124
|
attr_accessor :source_lines_error_library_frames
|
124
125
|
attr_accessor :source_lines_span_library_frames
|
125
126
|
|
126
|
-
attr_accessor :
|
127
|
+
attr_accessor :disabled_spies
|
127
128
|
|
128
129
|
attr_accessor :view_paths
|
129
130
|
attr_accessor :root_path
|
@@ -170,7 +171,7 @@ module ElasticAPM
|
|
170
171
|
end
|
171
172
|
|
172
173
|
# rubocop:disable Metrics/MethodLength
|
173
|
-
def
|
174
|
+
def available_spies
|
174
175
|
%w[
|
175
176
|
action_dispatch
|
176
177
|
delayed_job
|
@@ -187,8 +188,8 @@ module ElasticAPM
|
|
187
188
|
end
|
188
189
|
# rubocop:enable Metrics/MethodLength
|
189
190
|
|
190
|
-
def
|
191
|
-
|
191
|
+
def enabled_spies
|
192
|
+
available_spies - disabled_spies
|
192
193
|
end
|
193
194
|
|
194
195
|
private
|
@@ -3,15 +3,18 @@
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
5
|
class ErrorBuilder
|
6
|
-
def initialize(
|
7
|
-
@
|
6
|
+
def initialize(agent)
|
7
|
+
@agent = agent
|
8
8
|
end
|
9
9
|
|
10
10
|
def build_exception(exception, handled: true)
|
11
11
|
error = Error.new
|
12
12
|
error.exception = Error::Exception.new(exception, handled: handled)
|
13
13
|
|
14
|
-
|
14
|
+
if exception.backtrace
|
15
|
+
add_stacktrace error, :exception, exception.backtrace
|
16
|
+
end
|
17
|
+
|
15
18
|
add_transaction_id error
|
16
19
|
|
17
20
|
if (transaction = ElasticAPM.current_transaction)
|
@@ -25,7 +28,10 @@ module ElasticAPM
|
|
25
28
|
error = Error.new
|
26
29
|
error.log = Error::Log.new(message, **attrs)
|
27
30
|
|
28
|
-
|
31
|
+
if backtrace
|
32
|
+
add_stacktrace error, :log, backtrace
|
33
|
+
end
|
34
|
+
|
29
35
|
add_transaction_id error
|
30
36
|
|
31
37
|
error
|
@@ -34,7 +40,9 @@ module ElasticAPM
|
|
34
40
|
private
|
35
41
|
|
36
42
|
def add_stacktrace(error, kind, backtrace)
|
37
|
-
|
43
|
+
stacktrace =
|
44
|
+
@agent.stacktrace_builder.build(backtrace, type: :error)
|
45
|
+
return unless stacktrace
|
38
46
|
|
39
47
|
case kind
|
40
48
|
when :exception
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'elastic_apm/subscriber'
|
4
3
|
require 'elastic_apm/span'
|
5
4
|
require 'elastic_apm/transaction'
|
6
5
|
|
@@ -26,24 +25,26 @@ module ElasticAPM
|
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
|
-
def initialize(
|
30
|
-
@config = config
|
28
|
+
def initialize(agent)
|
31
29
|
@agent = agent
|
30
|
+
@config = agent.config
|
32
31
|
|
33
32
|
@transaction_info = TransactionInfo.new
|
34
|
-
|
35
|
-
@subscriber = subscriber_class.new(config)
|
36
33
|
end
|
37
34
|
|
38
|
-
attr_reader :config, :pending_transactions
|
35
|
+
attr_reader :agent, :config, :pending_transactions
|
39
36
|
|
40
37
|
def start
|
41
|
-
@subscriber.register!
|
42
38
|
end
|
43
39
|
|
44
40
|
def stop
|
45
41
|
current_transaction.release if current_transaction
|
46
|
-
@subscriber.unregister!
|
42
|
+
@subscriber.unregister! if @subscriber
|
43
|
+
end
|
44
|
+
|
45
|
+
def subscriber=(subscriber)
|
46
|
+
@subscriber = subscriber
|
47
|
+
@subscriber.register!
|
47
48
|
end
|
48
49
|
|
49
50
|
def current_transaction
|
@@ -112,7 +113,7 @@ module ElasticAPM
|
|
112
113
|
end
|
113
114
|
|
114
115
|
def submit_transaction(transaction)
|
115
|
-
|
116
|
+
agent.enqueue_transaction transaction
|
116
117
|
|
117
118
|
return unless config.debug_transactions
|
118
119
|
debug('Submitted transaction:') { Util.inspect_transaction transaction }
|
@@ -10,20 +10,21 @@ module ElasticAPM
|
|
10
10
|
# rubocop:disable Metrics/MethodLength
|
11
11
|
def call(env)
|
12
12
|
begin
|
13
|
-
transaction = ElasticAPM.transaction 'Rack', '
|
13
|
+
transaction = ElasticAPM.transaction 'Rack', 'request',
|
14
14
|
context: ElasticAPM.build_context(env)
|
15
15
|
|
16
16
|
resp = @app.call env
|
17
17
|
status, headers, = resp
|
18
18
|
|
19
19
|
if transaction
|
20
|
-
|
20
|
+
result = "HTTP #{status.to_s[0]}xx"
|
21
|
+
transaction.submit(result, status: status, headers: headers)
|
21
22
|
end
|
22
23
|
rescue InternalError
|
23
24
|
raise # Don't report ElasticAPM errors
|
24
25
|
rescue ::Exception => e
|
25
26
|
ElasticAPM.report(e, handled: false)
|
26
|
-
transaction.submit(
|
27
|
+
transaction.submit('HTTP 5xx', status: 500) if transaction
|
27
28
|
raise
|
28
29
|
ensure
|
29
30
|
transaction.release if transaction
|
@@ -19,8 +19,8 @@ module ElasticAPM
|
|
19
19
|
def normalize(_transaction, _name, payload)
|
20
20
|
return :skip if %w[SCHEMA CACHE].include?(payload[:name])
|
21
21
|
|
22
|
-
name = summarize(payload[:sql]) || payload[:name]
|
23
|
-
context = Span::Context.new(statement: payload[:sql])
|
22
|
+
name = summarize(payload[:sql]) || payload[:name]
|
23
|
+
context = Span::Context.new(statement: payload[:sql].to_s)
|
24
24
|
[name, @type, context]
|
25
25
|
end
|
26
26
|
|
data/lib/elastic_apm/railtie.rb
CHANGED
@@ -1,18 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'elastic_apm/subscriber'
|
4
|
+
|
3
5
|
module ElasticAPM
|
4
6
|
# @api private
|
5
7
|
class Railtie < Rails::Railtie
|
6
8
|
config.elastic_apm = ActiveSupport::OrderedOptions.new
|
9
|
+
|
7
10
|
Config::DEFAULTS.each { |option, value| config.elastic_apm[option] = value }
|
8
11
|
|
9
12
|
initializer 'elastic_apm.initialize' do |app|
|
10
13
|
config = app.config.elastic_apm.merge(app: app)
|
11
14
|
|
12
15
|
begin
|
13
|
-
ElasticAPM.start config
|
16
|
+
agent = ElasticAPM.start config
|
17
|
+
|
18
|
+
if agent
|
19
|
+
agent.instrumenter.subscriber = ElasticAPM::Subscriber.new(agent)
|
14
20
|
|
15
|
-
|
21
|
+
app.middleware.insert 0, Middleware
|
22
|
+
end
|
16
23
|
rescue StandardError => e
|
17
24
|
Rails.logger.error "#{Log::PREFIX}Failed to start: #{e.message}"
|
18
25
|
Rails.logger.debug e.backtrace.join("\n")
|
@@ -20,7 +27,7 @@ module ElasticAPM
|
|
20
27
|
end
|
21
28
|
|
22
29
|
config.after_initialize do
|
23
|
-
require 'elastic_apm/
|
30
|
+
require 'elastic_apm/spies/action_dispatch'
|
24
31
|
end
|
25
32
|
end
|
26
33
|
end
|
@@ -4,20 +4,20 @@ require 'elastic_apm/util/inflector'
|
|
4
4
|
|
5
5
|
module ElasticAPM
|
6
6
|
# @api private
|
7
|
-
module
|
7
|
+
module Spies
|
8
8
|
# @api private
|
9
9
|
class Registration
|
10
|
-
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
def initialize(const_name, require_paths, spy)
|
11
13
|
@const_name = const_name
|
12
14
|
@require_paths = Array(require_paths)
|
13
|
-
@
|
15
|
+
@spy = spy
|
14
16
|
end
|
15
17
|
|
16
|
-
attr_reader :const_name, :require_paths
|
18
|
+
attr_reader :const_name, :require_paths
|
17
19
|
|
18
|
-
|
19
|
-
injector.install
|
20
|
-
end
|
20
|
+
def_delegator :@spy, :install
|
21
21
|
end
|
22
22
|
|
23
23
|
def self.require_hooks
|
@@ -31,9 +31,9 @@ module ElasticAPM
|
|
31
31
|
def self.register(*args)
|
32
32
|
registration = Registration.new(*args)
|
33
33
|
|
34
|
-
if
|
35
|
-
installed[registration.const_name] = registration
|
34
|
+
if safe_defined?(registration.const_name)
|
36
35
|
registration.install
|
36
|
+
installed[registration.const_name] = registration
|
37
37
|
else
|
38
38
|
register_require_hook registration
|
39
39
|
end
|
@@ -47,7 +47,7 @@ module ElasticAPM
|
|
47
47
|
|
48
48
|
def self.hook_into(name)
|
49
49
|
return unless (registration = require_hooks[name])
|
50
|
-
return unless
|
50
|
+
return unless safe_defined?(registration.const_name)
|
51
51
|
|
52
52
|
installed[registration.const_name] = registration
|
53
53
|
registration.install
|
@@ -57,11 +57,8 @@ module ElasticAPM
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
def self.
|
61
|
-
|
62
|
-
!!const
|
63
|
-
rescue NameError
|
64
|
-
false
|
60
|
+
def self.safe_defined?(const_name)
|
61
|
+
Util::Inflector.safe_constantize(const_name)
|
65
62
|
end
|
66
63
|
end
|
67
64
|
end
|
@@ -76,8 +73,11 @@ module Kernel
|
|
76
73
|
res = require_without_apm(path)
|
77
74
|
|
78
75
|
begin
|
79
|
-
ElasticAPM::
|
80
|
-
rescue ::Exception
|
76
|
+
ElasticAPM::Spies.hook_into(path)
|
77
|
+
rescue ::Exception => e
|
78
|
+
puts "Failed hooking into '#{path}'. Please report this at " \
|
79
|
+
'github.com/elastic/apm-agent-ruby'
|
80
|
+
puts e.backtrace.join("\n")
|
81
81
|
end
|
82
82
|
|
83
83
|
res
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
|
-
module
|
5
|
+
module Spies
|
6
6
|
# @api private
|
7
|
-
class
|
7
|
+
class ActionDispatchSpy
|
8
8
|
def install
|
9
9
|
::ActionDispatch::ShowExceptions.class_eval do
|
10
10
|
alias render_exception_without_apm render_exception
|
@@ -20,7 +20,7 @@ module ElasticAPM
|
|
20
20
|
register(
|
21
21
|
'ActionDispatch::ShowExceptions',
|
22
22
|
'action_dispatch/show_exception',
|
23
|
-
|
23
|
+
ActionDispatchSpy.new
|
24
24
|
)
|
25
25
|
end
|
26
26
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
|
-
module
|
5
|
+
module Spies
|
6
6
|
# @api private
|
7
|
-
class
|
7
|
+
class DelayedJobSpy
|
8
8
|
CLASS_SEPARATOR = '.'.freeze
|
9
9
|
METHOD_SEPARATOR = '#'.freeze
|
10
10
|
TYPE = 'Delayed::Job'.freeze
|
@@ -14,7 +14,7 @@ module ElasticAPM
|
|
14
14
|
alias invoke_job_without_apm invoke_job
|
15
15
|
|
16
16
|
def invoke_job(*args, &block)
|
17
|
-
::ElasticAPM::
|
17
|
+
::ElasticAPM::Spies::DelayedJobSpy
|
18
18
|
.invoke_job(self, *args, &block)
|
19
19
|
end
|
20
20
|
end
|
@@ -62,7 +62,7 @@ module ElasticAPM
|
|
62
62
|
register(
|
63
63
|
'Delayed::Backend::Base',
|
64
64
|
'delayed/backend/base',
|
65
|
-
|
65
|
+
DelayedJobSpy.new
|
66
66
|
)
|
67
67
|
end
|
68
68
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
|
-
module
|
5
|
+
module Spies
|
6
6
|
# @api private
|
7
|
-
class
|
7
|
+
class ElasticsearchSpy
|
8
8
|
NAME_FORMAT = '%s %s'.freeze
|
9
9
|
TYPE = 'db.elasticsearch'.freeze
|
10
10
|
|
@@ -27,7 +27,7 @@ module ElasticAPM
|
|
27
27
|
register(
|
28
28
|
'Elasticsearch::Transport::Client',
|
29
29
|
'elasticsearch-transport',
|
30
|
-
|
30
|
+
ElasticsearchSpy.new
|
31
31
|
)
|
32
32
|
end
|
33
33
|
end
|
@@ -4,9 +4,9 @@ require 'elastic_apm/span_helpers'
|
|
4
4
|
|
5
5
|
module ElasticAPM
|
6
6
|
# @api private
|
7
|
-
module
|
7
|
+
module Spies
|
8
8
|
# @api private
|
9
|
-
class
|
9
|
+
class JSONSpy
|
10
10
|
def install
|
11
11
|
::JSON.class_eval do
|
12
12
|
include SpanHelpers
|
@@ -17,6 +17,6 @@ module ElasticAPM
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
register 'JSON', 'json',
|
20
|
+
register 'JSON', 'json', JSONSpy.new
|
21
21
|
end
|
22
22
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
|
-
module
|
5
|
+
module Spies
|
6
6
|
# @api private
|
7
|
-
class
|
7
|
+
class MongoSpy
|
8
8
|
def install
|
9
9
|
::Mongo::Monitoring::Global.subscribe(
|
10
10
|
::Mongo::Monitoring::COMMAND,
|
@@ -35,6 +35,8 @@ module ElasticAPM
|
|
35
35
|
private
|
36
36
|
|
37
37
|
def push_event(event)
|
38
|
+
return unless ElasticAPM.current_transaction
|
39
|
+
|
38
40
|
ctx = Span::Context.new(
|
39
41
|
instance: event.database_name,
|
40
42
|
statement: nil,
|
@@ -46,12 +48,14 @@ module ElasticAPM
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def pop_event(event)
|
49
|
-
|
50
|
-
|
51
|
+
return unless ElasticAPM.current_transaction
|
52
|
+
|
53
|
+
span = @events.delete(event.operation_id)
|
54
|
+
span && span.done
|
51
55
|
end
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
55
|
-
register 'Mongo', 'mongo',
|
59
|
+
register 'Mongo', 'mongo', MongoSpy.new
|
56
60
|
end
|
57
61
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
|
-
module
|
5
|
+
module Spies
|
6
6
|
# @api private
|
7
|
-
class
|
7
|
+
class NetHTTPSpy
|
8
8
|
# rubocop:disable Metrics/MethodLength
|
9
9
|
def install
|
10
10
|
Net::HTTP.class_eval do
|
@@ -32,6 +32,6 @@ module ElasticAPM
|
|
32
32
|
# rubocop:enable Metrics/MethodLength
|
33
33
|
end
|
34
34
|
|
35
|
-
register 'Net::HTTP', 'net/http',
|
35
|
+
register 'Net::HTTP', 'net/http', NetHTTPSpy.new
|
36
36
|
end
|
37
37
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
|
-
module
|
5
|
+
module Spies
|
6
6
|
# @api private
|
7
|
-
class
|
7
|
+
class RedisSpy
|
8
8
|
def install
|
9
9
|
::Redis::Client.class_eval do
|
10
10
|
alias call_without_apm call
|
@@ -22,6 +22,6 @@ module ElasticAPM
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
register 'Redis', 'redis',
|
25
|
+
register 'Redis', 'redis', RedisSpy.new
|
26
26
|
end
|
27
27
|
end
|
@@ -4,9 +4,9 @@ require 'elastic_apm/sql_summarizer'
|
|
4
4
|
|
5
5
|
module ElasticAPM
|
6
6
|
# @api private
|
7
|
-
module
|
7
|
+
module Spies
|
8
8
|
# @api private
|
9
|
-
class
|
9
|
+
class SequelSpy
|
10
10
|
TYPE = 'db.sequel.sql'.freeze
|
11
11
|
|
12
12
|
def self.summarizer
|
@@ -25,7 +25,7 @@ module ElasticAPM
|
|
25
25
|
return log_connection_yield_without_apm(sql, *args, &block)
|
26
26
|
end
|
27
27
|
|
28
|
-
summarizer = ElasticAPM::
|
28
|
+
summarizer = ElasticAPM::Spies::SequelSpy.summarizer
|
29
29
|
name = summarizer.summarize sql
|
30
30
|
context = Span::Context.new(
|
31
31
|
statement: sql,
|
@@ -40,6 +40,6 @@ module ElasticAPM
|
|
40
40
|
# rubocop:enable Metrics/MethodLength
|
41
41
|
end
|
42
42
|
|
43
|
-
register 'Sequel', 'sequel',
|
43
|
+
register 'Sequel', 'sequel', SequelSpy.new
|
44
44
|
end
|
45
45
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
|
-
module
|
5
|
+
module Spies
|
6
6
|
# @api private
|
7
|
-
class
|
7
|
+
class SidekiqSpy
|
8
8
|
ACTIVE_JOB_WRAPPER =
|
9
9
|
'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper'.freeze
|
10
10
|
|
@@ -12,7 +12,7 @@ module ElasticAPM
|
|
12
12
|
class Middleware
|
13
13
|
# rubocop:disable Metrics/MethodLength
|
14
14
|
def call(_worker, job, queue)
|
15
|
-
name =
|
15
|
+
name = SidekiqSpy.name_for(job)
|
16
16
|
transaction = ElasticAPM.transaction(name, 'Sidekiq')
|
17
17
|
ElasticAPM.set_tag(:queue, queue)
|
18
18
|
|
@@ -58,10 +58,13 @@ module ElasticAPM
|
|
58
58
|
|
59
59
|
def start
|
60
60
|
result = start_without_apm
|
61
|
-
ElasticAPM.start # might already be running from railtie
|
62
61
|
|
63
|
-
|
64
|
-
ElasticAPM.
|
62
|
+
# Already running from Railtie if Rails
|
63
|
+
if ElasticAPM.running?
|
64
|
+
ElasticAPM.agent.config.logger = Sidekiq.logger
|
65
|
+
else
|
66
|
+
ElasticAPM.start
|
67
|
+
end
|
65
68
|
|
66
69
|
result
|
67
70
|
end
|
@@ -81,6 +84,6 @@ module ElasticAPM
|
|
81
84
|
end
|
82
85
|
end
|
83
86
|
|
84
|
-
register 'Sidekiq', 'sidekiq',
|
87
|
+
register 'Sidekiq', 'sidekiq', SidekiqSpy.new
|
85
88
|
end
|
86
89
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
|
-
module
|
5
|
+
module Spies
|
6
6
|
# @api private
|
7
|
-
class
|
7
|
+
class SinatraSpy
|
8
8
|
# rubocop:disable Metrics/MethodLength
|
9
9
|
def install
|
10
10
|
::Sinatra::Base.class_eval do
|
@@ -34,8 +34,8 @@ module ElasticAPM
|
|
34
34
|
# rubocop:enable Metrics/MethodLength
|
35
35
|
end
|
36
36
|
|
37
|
-
register 'Sinatra::Base', 'sinatra/base',
|
37
|
+
register 'Sinatra::Base', 'sinatra/base', SinatraSpy.new
|
38
38
|
|
39
|
-
require 'elastic_apm/
|
39
|
+
require 'elastic_apm/spies/tilt'
|
40
40
|
end
|
41
41
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
|
-
module
|
5
|
+
module Spies
|
6
6
|
# @api private
|
7
|
-
class
|
7
|
+
class TiltSpy
|
8
8
|
TYPE = 'template.tilt'.freeze
|
9
9
|
|
10
10
|
def install
|
@@ -22,6 +22,6 @@ module ElasticAPM
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
register 'Tilt::Template', 'tilt/template',
|
25
|
+
register 'Tilt::Template', 'tilt/template', TiltSpy.new
|
26
26
|
end
|
27
27
|
end
|
@@ -5,11 +5,16 @@ require 'elastic_apm/util/lru_cache'
|
|
5
5
|
module ElasticAPM
|
6
6
|
# @api private
|
7
7
|
class SqlSummarizer
|
8
|
+
DEFAULT = 'SQL'.freeze
|
9
|
+
TABLE_REGEX = %{["'`]?([A-Za-z0-9]+)}.freeze
|
10
|
+
|
8
11
|
REGEXES = {
|
9
|
-
/^
|
10
|
-
/^
|
11
|
-
/^
|
12
|
-
/^
|
12
|
+
/^BEGIN/i => 'BEGIN',
|
13
|
+
/^COMMIT/i => 'COMMIT',
|
14
|
+
/^SELECT .* FROM #{TABLE_REGEX}/i => 'SELECT FROM ',
|
15
|
+
/^INSERT INTO #{TABLE_REGEX}/i => 'INSERT INTO ',
|
16
|
+
/^UPDATE #{TABLE_REGEX}/i => 'UPDATE ',
|
17
|
+
/^DELETE FROM #{TABLE_REGEX}/i => 'DELETE FROM '
|
13
18
|
}.freeze
|
14
19
|
|
15
20
|
FORMAT = '%s%s'.freeze
|
@@ -24,7 +29,7 @@ module ElasticAPM
|
|
24
29
|
if (match = sql.match(regex))
|
25
30
|
break format(FORMAT, sig, match[1].gsub(/["']/, ''))
|
26
31
|
end
|
27
|
-
end
|
32
|
+
end || DEFAULT
|
28
33
|
end
|
29
34
|
end
|
30
35
|
end
|
@@ -1,36 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'elastic_apm/stacktrace/frame'
|
4
|
-
require 'elastic_apm/stacktrace/line_cache'
|
5
|
-
|
6
3
|
module ElasticAPM
|
7
4
|
# @api private
|
8
5
|
class Stacktrace
|
9
|
-
|
10
|
-
RUBY_FORMAT = /^(.+?):(\d+)(?::in `(.+?)')?$/
|
11
|
-
|
12
|
-
RUBY_VERS_REGEX = %r{ruby(/gems)?[-/](\d+\.)+\d}
|
13
|
-
JRUBY_ORG_REGEX = %r{org/jruby}
|
14
|
-
|
15
|
-
def initialize(backtrace)
|
16
|
-
@backtrace = backtrace
|
17
|
-
end
|
18
|
-
|
19
|
-
attr_reader :frames
|
20
|
-
|
21
|
-
def self.build(config, backtrace, type)
|
22
|
-
return nil unless backtrace
|
23
|
-
|
24
|
-
stack = new(backtrace)
|
25
|
-
stack.build_frames(config, type)
|
26
|
-
stack
|
27
|
-
end
|
28
|
-
|
29
|
-
def build_frames(config, type)
|
30
|
-
@frames = @backtrace.map do |line|
|
31
|
-
build_frame(config, line, type)
|
32
|
-
end
|
33
|
-
end
|
6
|
+
attr_accessor :frames
|
34
7
|
|
35
8
|
def length
|
36
9
|
frames.length
|
@@ -39,82 +12,5 @@ module ElasticAPM
|
|
39
12
|
def to_a
|
40
13
|
frames.map(&:to_h)
|
41
14
|
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def parse_line(line)
|
46
|
-
ruby_match = line.match(RUBY_FORMAT)
|
47
|
-
|
48
|
-
if ruby_match
|
49
|
-
_, file, number, method = ruby_match.to_a
|
50
|
-
file.sub!(/\.class$/, '.rb')
|
51
|
-
module_name = nil
|
52
|
-
else
|
53
|
-
java_match = line.match(JAVA_FORMAT)
|
54
|
-
_, module_name, method, file, number = java_match.to_a
|
55
|
-
end
|
56
|
-
|
57
|
-
[file, number, method, module_name]
|
58
|
-
end
|
59
|
-
|
60
|
-
def library_frame?(config, abs_path)
|
61
|
-
return false unless abs_path
|
62
|
-
|
63
|
-
if abs_path.start_with?(config.root_path)
|
64
|
-
return true if abs_path.start_with?(config.root_path + '/vendor')
|
65
|
-
return false
|
66
|
-
end
|
67
|
-
|
68
|
-
return true if abs_path.match(RUBY_VERS_REGEX)
|
69
|
-
return true if abs_path.match(JRUBY_ORG_REGEX)
|
70
|
-
|
71
|
-
false
|
72
|
-
end
|
73
|
-
|
74
|
-
class << self
|
75
|
-
attr_accessor :frame_cache
|
76
|
-
end
|
77
|
-
|
78
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
79
|
-
def build_frame(config, line, type)
|
80
|
-
# TODO: Eventually move this to agent 'context'
|
81
|
-
self.class.frame_cache ||= Util::LruCache.new(2048) do |cache, keys|
|
82
|
-
line, type = keys
|
83
|
-
abs_path, lineno, function, _module_name = parse_line(line)
|
84
|
-
|
85
|
-
frame = Frame.new
|
86
|
-
frame.abs_path = abs_path
|
87
|
-
frame.filename = strip_load_path(abs_path)
|
88
|
-
frame.function = function
|
89
|
-
frame.lineno = lineno.to_i
|
90
|
-
frame.library_frame = library_frame?(config, abs_path)
|
91
|
-
|
92
|
-
line_count =
|
93
|
-
context_lines_for(config, type, library_frame: frame.library_frame)
|
94
|
-
frame.build_context line_count
|
95
|
-
|
96
|
-
cache[[line, type]] = frame
|
97
|
-
end
|
98
|
-
|
99
|
-
self.class.frame_cache[[line, type]]
|
100
|
-
end
|
101
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
102
|
-
|
103
|
-
def strip_load_path(path)
|
104
|
-
return nil if path.nil?
|
105
|
-
|
106
|
-
prefix =
|
107
|
-
$LOAD_PATH
|
108
|
-
.map(&:to_s)
|
109
|
-
.select { |s| path.start_with?(s) }
|
110
|
-
.max_by(&:length)
|
111
|
-
|
112
|
-
prefix ? path[prefix.chomp(File::SEPARATOR).length + 1..-1] : path
|
113
|
-
end
|
114
|
-
|
115
|
-
def context_lines_for(config, type, library_frame:)
|
116
|
-
key = "source_lines_#{type}_#{library_frame ? 'library' : 'app'}_frames"
|
117
|
-
config.send(key.to_sym)
|
118
|
-
end
|
119
15
|
end
|
120
16
|
end
|
@@ -38,11 +38,7 @@ module ElasticAPM
|
|
38
38
|
private
|
39
39
|
|
40
40
|
def read_lines(path, range)
|
41
|
-
|
42
|
-
return cached
|
43
|
-
end
|
44
|
-
|
45
|
-
LineCache.set(path, range, File.readlines(path)[range]) || []
|
41
|
+
File.readlines(path)[range]
|
46
42
|
rescue Errno::ENOENT
|
47
43
|
[]
|
48
44
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'elastic_apm/stacktrace/frame'
|
4
|
+
require 'elastic_apm/util/lru_cache'
|
5
|
+
|
6
|
+
module ElasticAPM
|
7
|
+
# @api private
|
8
|
+
class StacktraceBuilder
|
9
|
+
JAVA_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/
|
10
|
+
RUBY_FORMAT = /^(.+?):(\d+)(?::in `(.+?)')?$/
|
11
|
+
|
12
|
+
RUBY_VERS_REGEX = %r{ruby(/gems)?[-/](\d+\.)+\d}
|
13
|
+
JRUBY_ORG_REGEX = %r{org/jruby}
|
14
|
+
|
15
|
+
def initialize(agent)
|
16
|
+
@config = agent.config
|
17
|
+
@cache = Util::LruCache.new(2048, &method(:build_frame))
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :config
|
21
|
+
|
22
|
+
def build(backtrace, type:)
|
23
|
+
Stacktrace.new.tap do |s|
|
24
|
+
s.frames = backtrace.map do |line|
|
25
|
+
@cache[[line, type]]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
33
|
+
def build_frame(cache, keys)
|
34
|
+
line, type = keys
|
35
|
+
abs_path, lineno, function, _module_name = parse_line(line)
|
36
|
+
|
37
|
+
frame = Stacktrace::Frame.new
|
38
|
+
frame.abs_path = abs_path
|
39
|
+
frame.filename = strip_load_path(abs_path)
|
40
|
+
frame.function = function
|
41
|
+
frame.lineno = lineno.to_i
|
42
|
+
frame.library_frame = library_frame?(config, abs_path)
|
43
|
+
|
44
|
+
line_count =
|
45
|
+
context_lines_for(config, type, library_frame: frame.library_frame)
|
46
|
+
frame.build_context line_count
|
47
|
+
|
48
|
+
cache[[line, type]] = frame
|
49
|
+
end
|
50
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
51
|
+
|
52
|
+
def parse_line(line)
|
53
|
+
ruby_match = line.match(RUBY_FORMAT)
|
54
|
+
|
55
|
+
if ruby_match
|
56
|
+
_, file, number, method = ruby_match.to_a
|
57
|
+
file.sub!(/\.class$/, '.rb')
|
58
|
+
module_name = nil
|
59
|
+
else
|
60
|
+
java_match = line.match(JAVA_FORMAT)
|
61
|
+
_, module_name, method, file, number = java_match.to_a
|
62
|
+
end
|
63
|
+
|
64
|
+
[file, number, method, module_name]
|
65
|
+
end
|
66
|
+
|
67
|
+
def library_frame?(config, abs_path)
|
68
|
+
return false unless abs_path
|
69
|
+
|
70
|
+
if abs_path.start_with?(config.root_path)
|
71
|
+
return true if abs_path.start_with?(config.root_path + '/vendor')
|
72
|
+
return false
|
73
|
+
end
|
74
|
+
|
75
|
+
return true if abs_path.match(RUBY_VERS_REGEX)
|
76
|
+
return true if abs_path.match(JRUBY_ORG_REGEX)
|
77
|
+
|
78
|
+
false
|
79
|
+
end
|
80
|
+
|
81
|
+
def strip_load_path(path)
|
82
|
+
return nil if path.nil?
|
83
|
+
|
84
|
+
prefix =
|
85
|
+
$LOAD_PATH
|
86
|
+
.map(&:to_s)
|
87
|
+
.select { |s| path.start_with?(s) }
|
88
|
+
.max_by(&:length)
|
89
|
+
|
90
|
+
prefix ? path[prefix.chomp(File::SEPARATOR).length + 1..-1] : path
|
91
|
+
end
|
92
|
+
|
93
|
+
def context_lines_for(config, type, library_frame:)
|
94
|
+
key = "source_lines_#{type}_#{library_frame ? 'library' : 'app'}_frames"
|
95
|
+
config.send(key.to_sym)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -8,10 +8,9 @@ module ElasticAPM
|
|
8
8
|
class Subscriber
|
9
9
|
include Log
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
@config = config
|
11
|
+
def initialize(agent)
|
13
12
|
@agent = agent
|
14
|
-
@normalizers = Normalizers.build(config)
|
13
|
+
@normalizers = Normalizers.build(agent.config)
|
15
14
|
end
|
16
15
|
|
17
16
|
def register!
|
@@ -75,6 +75,7 @@ module ElasticAPM
|
|
75
75
|
@adapter.post('/v1/errors', payload)
|
76
76
|
end
|
77
77
|
|
78
|
+
# rubocop:disable Metrics/MethodLength
|
78
79
|
def collect_and_send_transactions
|
79
80
|
return if pending_transactions.empty?
|
80
81
|
|
@@ -89,7 +90,10 @@ module ElasticAPM
|
|
89
90
|
debug e.backtrace.join("\n")
|
90
91
|
nil
|
91
92
|
end
|
93
|
+
|
94
|
+
@last_sent_transactions = Time.now
|
92
95
|
end
|
96
|
+
# rubocop:enable Metrics/MethodLength
|
93
97
|
|
94
98
|
def collect_batched_transactions
|
95
99
|
batch = []
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ElasticAPM
|
4
|
+
# rubocop:disable Metrics/ClassLength
|
4
5
|
# @api private
|
5
6
|
class Transaction
|
6
7
|
DEFAULT_TYPE = 'custom'.freeze
|
@@ -103,8 +104,10 @@ module ElasticAPM
|
|
103
104
|
span = next_span(name, type, context)
|
104
105
|
spans << span
|
105
106
|
|
106
|
-
|
107
|
-
|
107
|
+
if backtrace
|
108
|
+
span.stacktrace =
|
109
|
+
@instrumenter.agent.stacktrace_builder.build(backtrace, type: :span)
|
110
|
+
end
|
108
111
|
|
109
112
|
span.start
|
110
113
|
end
|
@@ -141,4 +144,5 @@ module ElasticAPM
|
|
141
144
|
)
|
142
145
|
end
|
143
146
|
end
|
147
|
+
# rubocop:enable Metrics/ClassLength
|
144
148
|
end
|
@@ -1,14 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ElasticAPM
|
4
|
+
# rubocop:disable all
|
2
5
|
module Util
|
3
|
-
#
|
6
|
+
# From https://github.com/rails/rails/blob/v5.2.0/activesupport/lib/active_support/inflector/methods.rb#L254-L332
|
4
7
|
module Inflector
|
5
|
-
|
6
|
-
|
8
|
+
extend self
|
9
|
+
|
7
10
|
#
|
8
11
|
# Tries to find a constant with the name specified in the argument string.
|
9
12
|
#
|
10
|
-
# 'Module'
|
11
|
-
# '
|
13
|
+
# constantize('Module') # => Module
|
14
|
+
# constantize('Foo::Bar') # => Foo::Bar
|
12
15
|
#
|
13
16
|
# The name is assumed to be the one of a top-level constant, no matter
|
14
17
|
# whether it starts with "::" or not. No lexical context is taken into
|
@@ -17,14 +20,14 @@ module ElasticAPM
|
|
17
20
|
# C = 'outside'
|
18
21
|
# module M
|
19
22
|
# C = 'inside'
|
20
|
-
# C
|
21
|
-
# 'C'
|
23
|
+
# C # => 'inside'
|
24
|
+
# constantize('C') # => 'outside', same as ::C
|
22
25
|
# end
|
23
26
|
#
|
24
27
|
# NameError is raised when the name is not in CamelCase or the constant is
|
25
28
|
# unknown.
|
26
|
-
def
|
27
|
-
names = camel_cased_word.split(
|
29
|
+
def constantize(camel_cased_word)
|
30
|
+
names = camel_cased_word.split("::".freeze)
|
28
31
|
|
29
32
|
# Trigger a built-in NameError exception including the ill-formed constant in the message.
|
30
33
|
Object.const_get(camel_cased_word) if names.empty?
|
@@ -42,7 +45,7 @@ module ElasticAPM
|
|
42
45
|
|
43
46
|
# Go down the ancestors to check if it is owned directly. The check
|
44
47
|
# stops when we reach Object or the end of ancestors tree.
|
45
|
-
constant = constant.ancestors.inject do |const, ancestor|
|
48
|
+
constant = constant.ancestors.inject(constant) do |const, ancestor|
|
46
49
|
break const if ancestor == Object
|
47
50
|
break ancestor if ancestor.const_defined?(name, false)
|
48
51
|
const
|
@@ -53,7 +56,38 @@ module ElasticAPM
|
|
53
56
|
end
|
54
57
|
end
|
55
58
|
end
|
56
|
-
|
59
|
+
|
60
|
+
# Tries to find a constant with the name specified in the argument string.
|
61
|
+
#
|
62
|
+
# safe_constantize('Module') # => Module
|
63
|
+
# safe_constantize('Foo::Bar') # => Foo::Bar
|
64
|
+
#
|
65
|
+
# The name is assumed to be the one of a top-level constant, no matter
|
66
|
+
# whether it starts with "::" or not. No lexical context is taken into
|
67
|
+
# account:
|
68
|
+
#
|
69
|
+
# C = 'outside'
|
70
|
+
# module M
|
71
|
+
# C = 'inside'
|
72
|
+
# C # => 'inside'
|
73
|
+
# safe_constantize('C') # => 'outside', same as ::C
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# +nil+ is returned when the name is not in CamelCase or the constant (or
|
77
|
+
# part of it) is unknown.
|
78
|
+
#
|
79
|
+
# safe_constantize('blargle') # => nil
|
80
|
+
# safe_constantize('UnknownModule') # => nil
|
81
|
+
# safe_constantize('UnknownModule::Foo::Bar') # => nil
|
82
|
+
def safe_constantize(camel_cased_word)
|
83
|
+
constantize(camel_cased_word)
|
84
|
+
rescue NameError => e
|
85
|
+
raise if e.name && !(camel_cased_word.to_s.split("::").include?(e.name.to_s) ||
|
86
|
+
e.name.to_s == camel_cased_word.to_s)
|
87
|
+
rescue ArgumentError => e
|
88
|
+
raise unless /not missing constant #{const_regexp(camel_cased_word)}!$/.match?(e.message)
|
89
|
+
end
|
57
90
|
end
|
58
91
|
end
|
92
|
+
# rubocop:enable all
|
59
93
|
end
|
data/lib/elastic_apm/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastic-apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mikkel Malmberg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activesupport
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 3.0.0
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 3.0.0
|
11
|
+
date: 2018-05-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
27
13
|
description:
|
28
14
|
email:
|
29
15
|
- mikkel@elastic.co
|
@@ -71,18 +57,6 @@ files:
|
|
71
57
|
- lib/elastic_apm/filters/request_body_filter.rb
|
72
58
|
- lib/elastic_apm/filters/secrets_filter.rb
|
73
59
|
- lib/elastic_apm/http.rb
|
74
|
-
- lib/elastic_apm/injectors.rb
|
75
|
-
- lib/elastic_apm/injectors/action_dispatch.rb
|
76
|
-
- lib/elastic_apm/injectors/delayed_job.rb
|
77
|
-
- lib/elastic_apm/injectors/elasticsearch.rb
|
78
|
-
- lib/elastic_apm/injectors/json.rb
|
79
|
-
- lib/elastic_apm/injectors/mongo.rb
|
80
|
-
- lib/elastic_apm/injectors/net_http.rb
|
81
|
-
- lib/elastic_apm/injectors/redis.rb
|
82
|
-
- lib/elastic_apm/injectors/sequel.rb
|
83
|
-
- lib/elastic_apm/injectors/sidekiq.rb
|
84
|
-
- lib/elastic_apm/injectors/sinatra.rb
|
85
|
-
- lib/elastic_apm/injectors/tilt.rb
|
86
60
|
- lib/elastic_apm/instrumenter.rb
|
87
61
|
- lib/elastic_apm/internal_error.rb
|
88
62
|
- lib/elastic_apm/log.rb
|
@@ -102,10 +76,22 @@ files:
|
|
102
76
|
- lib/elastic_apm/span.rb
|
103
77
|
- lib/elastic_apm/span/context.rb
|
104
78
|
- lib/elastic_apm/span_helpers.rb
|
79
|
+
- lib/elastic_apm/spies.rb
|
80
|
+
- lib/elastic_apm/spies/action_dispatch.rb
|
81
|
+
- lib/elastic_apm/spies/delayed_job.rb
|
82
|
+
- lib/elastic_apm/spies/elasticsearch.rb
|
83
|
+
- lib/elastic_apm/spies/json.rb
|
84
|
+
- lib/elastic_apm/spies/mongo.rb
|
85
|
+
- lib/elastic_apm/spies/net_http.rb
|
86
|
+
- lib/elastic_apm/spies/redis.rb
|
87
|
+
- lib/elastic_apm/spies/sequel.rb
|
88
|
+
- lib/elastic_apm/spies/sidekiq.rb
|
89
|
+
- lib/elastic_apm/spies/sinatra.rb
|
90
|
+
- lib/elastic_apm/spies/tilt.rb
|
105
91
|
- lib/elastic_apm/sql_summarizer.rb
|
106
92
|
- lib/elastic_apm/stacktrace.rb
|
107
93
|
- lib/elastic_apm/stacktrace/frame.rb
|
108
|
-
- lib/elastic_apm/
|
94
|
+
- lib/elastic_apm/stacktrace_builder.rb
|
109
95
|
- lib/elastic_apm/subscriber.rb
|
110
96
|
- lib/elastic_apm/system_info.rb
|
111
97
|
- lib/elastic_apm/timed_worker.rb
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'elastic_apm/util/lru_cache'
|
4
|
-
|
5
|
-
module ElasticAPM
|
6
|
-
class Stacktrace
|
7
|
-
# A basic LRU Cache
|
8
|
-
# @api private
|
9
|
-
class LineCache
|
10
|
-
class << self
|
11
|
-
def cache
|
12
|
-
@cache ||= Util::LruCache.new
|
13
|
-
end
|
14
|
-
|
15
|
-
def get(*key)
|
16
|
-
cache[key]
|
17
|
-
end
|
18
|
-
|
19
|
-
def set(*key, value)
|
20
|
-
cache[key] = value
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|