stackify-ruby-apm 1.10.0 → 1.12.3
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 +4 -4
- data/lib/stackify_apm/agent.rb +0 -2
- data/lib/stackify_apm/config.rb +33 -5
- data/lib/stackify_apm/context.rb +4 -1
- data/lib/stackify_apm/context/prefix.rb +30 -0
- data/lib/stackify_apm/context/request/headers.rb +30 -0
- data/lib/stackify_apm/context_builder.rb +1 -0
- data/lib/stackify_apm/helper/database_helper.rb +39 -1
- data/lib/stackify_apm/instrumenter_helper.rb +90 -4
- data/lib/stackify_apm/logger/log_device.rb +7 -5
- data/lib/stackify_apm/logger/logger_high_version.rb +5 -1
- data/lib/stackify_apm/logger/logger_lower_version.rb +5 -1
- data/lib/stackify_apm/middleware.rb +21 -3
- data/lib/stackify_apm/normalizers/active_record.rb +16 -8
- data/lib/stackify_apm/root_info.rb +7 -1
- data/lib/stackify_apm/serializers/transactions.rb +5 -0
- data/lib/stackify_apm/span/context.rb +39 -1
- data/lib/stackify_apm/spies.rb +4 -2
- data/lib/stackify_apm/spies/action_dispatch.rb +6 -1
- data/lib/stackify_apm/spies/curb.rb +41 -20
- data/lib/stackify_apm/spies/curb/easy.rb +220 -92
- data/lib/stackify_apm/spies/curb/multi.rb +26 -12
- data/lib/stackify_apm/spies/custom_instrumenter.rb +25 -4
- data/lib/stackify_apm/spies/delayed_job.rb +49 -0
- data/lib/stackify_apm/spies/httparty.rb +45 -24
- data/lib/stackify_apm/spies/httpclient.rb +41 -20
- data/lib/stackify_apm/spies/httprb.rb +39 -18
- data/lib/stackify_apm/spies/log4r.rb +59 -0
- data/lib/stackify_apm/spies/logger.rb +116 -0
- data/lib/stackify_apm/spies/logging.rb +65 -0
- data/lib/stackify_apm/spies/net_http.rb +38 -20
- data/lib/stackify_apm/spies/redis.rb +36 -30
- data/lib/stackify_apm/spies/sequel.rb +28 -11
- data/lib/stackify_apm/spies/sinatra_activerecord/mysql_adapter.rb +27 -25
- data/lib/stackify_apm/spies/sinatra_activerecord/postgresql_adapter.rb +27 -24
- data/lib/stackify_apm/spies/sinatra_activerecord/sqlite_adapter.rb +18 -8
- data/lib/stackify_apm/spies/stackify_logger.rb +28 -16
- data/lib/stackify_apm/spies/yell.rb +64 -0
- data/lib/stackify_apm/util.rb +10 -9
- data/lib/stackify_apm/version.rb +1 -1
- data/stackify-ruby-apm.gemspec +1 -0
- metadata +23 -2
@@ -14,19 +14,33 @@ module StackifyRubyAPM
|
|
14
14
|
def self.http(urls_with_config, _multi_options = {}, &blk)
|
15
15
|
return http_without_apm(urls_with_config, _multi_options = {}, &blk) unless StackifyRubyAPM.current_transaction
|
16
16
|
http_without_apm(urls_with_config, _multi_options = {}) do |c, code, method|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
begin
|
18
|
+
status_code = code.zero? ? 404 : code
|
19
|
+
method = method.upcase
|
20
|
+
uri = c.url.to_s.strip
|
21
|
+
name = "#{method} #{uri}"
|
22
|
+
type = "ext.Curb.Multi.#{method}"
|
23
|
+
|
24
|
+
ctx = Span::Context.new(
|
25
|
+
CATEGORY: 'Web External',
|
26
|
+
SUBCATEGORY: 'Execute',
|
27
|
+
URL: uri,
|
28
|
+
STATUS: status_code,
|
29
|
+
METHOD: method
|
30
|
+
)
|
31
|
+
|
32
|
+
if StackifyRubyAPM.agent.config.prefix_enabled
|
33
|
+
ctx.update_request_body(c.post_body || "")
|
34
|
+
ctx.update_request_headers(c.headers || Hash.new)
|
35
|
+
ctx.update_response_body(c.body || "")
|
36
|
+
ctx.update_response_headers(c.proxy_headers || Hash.new)
|
37
|
+
end
|
38
|
+
rescue Exception => e
|
39
|
+
StackifyRubyAPM.agent.error "[CurbMultiSpy] Error: creating span context."
|
40
|
+
StackifyRubyAPM.agent.error "[CurbMultiSpy] #{e.inspect}"
|
41
|
+
return blk.call(c, code, method)
|
42
|
+
end
|
22
43
|
|
23
|
-
ctx = Span::Context.new(
|
24
|
-
CATEGORY: 'Web External',
|
25
|
-
SUBCATEGORY: 'Execute',
|
26
|
-
URL: uri,
|
27
|
-
STATUS: status_code,
|
28
|
-
METHOD: method
|
29
|
-
)
|
30
44
|
# Creates new span from HTTP result
|
31
45
|
StackifyRubyAPM.span name, type, context: ctx do
|
32
46
|
blk.call(c, code, method)
|
@@ -24,16 +24,37 @@ module StackifyRubyAPM
|
|
24
24
|
return unless !to_instrument.nil? && !to_instrument.empty? && defined?(to_instrument['instrumentation']) && (to_instrument['instrumentation'].count > 0)
|
25
25
|
|
26
26
|
to_instrument['instrumentation'].each do |custom_spy|
|
27
|
-
current_class = custom_spy['class']
|
27
|
+
current_class = defined?(custom_spy['class']) ? custom_spy['class'] : nil
|
28
|
+
current_module = defined?(custom_spy['module']) ? custom_spy['module'] : nil
|
28
29
|
current_method = custom_spy['method']
|
29
30
|
tracked_func = custom_spy['trackedFunction']
|
30
31
|
tracked_func_name = defined?(custom_spy['trackedFunctionName']) ? custom_spy['trackedFunctionName'] : ''
|
31
32
|
transaction = defined?(custom_spy['transaction']) ? custom_spy['transaction'] : nil
|
32
33
|
file_path = defined?(custom_spy['file_path']) ? custom_spy['file_path'] : nil
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
if current_class
|
36
|
+
tracked_function_tpl = tracked_func_name.nil? ? '{{ClassName}}.{{MethodName}}' : tracked_func_name
|
37
|
+
tracked_function_name = tracked_function_tpl.to_s.sub '{{ClassName}}', current_class
|
38
|
+
tracked_function_name = tracked_function_name.to_s.sub '{{MethodName}}', current_method
|
39
|
+
elsif current_module
|
40
|
+
tracked_function_tpl = tracked_func_name.nil? ? '{{ModuleName}}.{{MethodName}}' : tracked_func_name
|
41
|
+
tracked_function_name = tracked_function_tpl.to_s.sub '{{ModuleName}}', current_module
|
42
|
+
tracked_function_name = tracked_function_name.to_s.sub '{{MethodName}}', current_method
|
43
|
+
end
|
44
|
+
|
45
|
+
begin
|
46
|
+
if current_module
|
47
|
+
if file_path.nil?
|
48
|
+
config.logger.send(:info, "[StackifyRubyAPM] Error: Missing file_path in module which is required in custom instrumentation.")
|
49
|
+
else
|
50
|
+
require file_path
|
51
|
+
StackifyRubyAPM::InstrumenterHelper.patched_module(tracked_func, current_module, file_path,
|
52
|
+
current_method: current_method, tracked_function_name: tracked_function_name, is_transaction: transaction)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
rescue => e
|
56
|
+
throw e
|
57
|
+
end
|
37
58
|
|
38
59
|
if !class_exists?(current_class) && !file_path.nil?
|
39
60
|
begin
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Monkey patch for the delayed_job class for running async tasks.
|
4
|
+
#
|
5
|
+
|
6
|
+
module StackifyRubyAPM
|
7
|
+
# @api private
|
8
|
+
module Spies
|
9
|
+
# @api private
|
10
|
+
class DelayedJobSpy
|
11
|
+
def install
|
12
|
+
Delayed::Backend::Base.class_eval do
|
13
|
+
alias_method 'invoke_job_without_apm', 'invoke_job'
|
14
|
+
|
15
|
+
def invoke_job(*args, &block)
|
16
|
+
ret = nil
|
17
|
+
begin
|
18
|
+
name = nil
|
19
|
+
if payload_object.is_a?(::Delayed::PerformableMethod)
|
20
|
+
object = payload_object.object
|
21
|
+
klass = object.is_a?(Class) ? object : object.class
|
22
|
+
class_name = klass.name
|
23
|
+
separator = payload_object.object.is_a?(Class) ? '.' : '#'
|
24
|
+
method_name = payload_object.method_name
|
25
|
+
name = "#{class_name}#{separator}#{method_name}"
|
26
|
+
else
|
27
|
+
name = payload_object.class.name
|
28
|
+
end
|
29
|
+
ctx = StackifyRubyAPM::Context.new
|
30
|
+
ctx.category = 'Delayed::Job'
|
31
|
+
transaction = StackifyRubyAPM.transaction name, 'TASK', context: ctx
|
32
|
+
ret = invoke_job_without_apm(*args, &block)
|
33
|
+
rescue StackifyRubyAPM::InternalError
|
34
|
+
raise # Don't report StackifyRubyAPM errors
|
35
|
+
rescue StandardError => e
|
36
|
+
StackifyRubyAPM.report e
|
37
|
+
raise e
|
38
|
+
ensure
|
39
|
+
transaction.submit()
|
40
|
+
end
|
41
|
+
ret
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
register 'Delayed::Backend::Base', 'delayed/backend/base', DelayedJobSpy.new
|
48
|
+
end
|
49
|
+
end
|
@@ -21,34 +21,55 @@ module StackifyRubyAPM
|
|
21
21
|
def perform_request(http_method, path, options, &block)
|
22
22
|
req = nil
|
23
23
|
return perform_request_without_apm(http_method, path, options, &block) unless StackifyRubyAPM.current_transaction
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
24
|
+
|
25
|
+
begin
|
26
|
+
# Data configuration
|
27
|
+
#
|
28
|
+
method = http_method.to_s.gsub('Net::HTTP::', '').upcase
|
29
|
+
uri = path.strip
|
30
|
+
name = "#{method} #{uri}"
|
31
|
+
type = "ext.HTTParty.#{method}"
|
32
|
+
# Submits HTTP request
|
33
|
+
#
|
34
|
+
# req = perform_request_without_apm(http_method, path, options, &block)
|
35
|
+
# Builds span context
|
36
|
+
#
|
37
|
+
# status_code = req.code
|
38
|
+
|
39
|
+
ctx = Span::Context.new(
|
40
|
+
CATEGORY: 'Web External',
|
41
|
+
SUBCATEGORY: 'Execute',
|
42
|
+
URL: uri,
|
43
|
+
STATUS: '',
|
44
|
+
METHOD: method
|
45
|
+
)
|
46
|
+
rescue Exception => e
|
47
|
+
StackifyRubyAPM.agent.error "[HTTPartySpy] Error: creating span context."
|
48
|
+
StackifyRubyAPM.agent.error "[HTTPartySpy] #{e.inspect}"
|
49
|
+
return perform_request_without_apm(http_method, path, options, &block)
|
50
|
+
end
|
51
|
+
|
44
52
|
# Creates new span from HTTP result
|
45
53
|
#
|
46
54
|
# class_info = { 'classname' => 'httparty', 'hostname' => URI.parse(uri).host }
|
47
55
|
StackifyRubyAPM.span name, type, context: ctx do
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
56
|
+
res = perform_request_without_apm(http_method, path, options, &block)
|
57
|
+
|
58
|
+
begin
|
59
|
+
status_code = res.code
|
60
|
+
ctx.update_status(status_code)
|
61
|
+
|
62
|
+
if StackifyRubyAPM.agent.config.prefix_enabled
|
63
|
+
ctx.update_request_body(options[:body] || "")
|
64
|
+
ctx.update_request_headers(options[:headers] || Hash.new)
|
65
|
+
ctx.update_response_body(res.body || "")
|
66
|
+
ctx.update_response_headers(res.each_header || Hash.new)
|
67
|
+
end
|
68
|
+
rescue Exception => e
|
69
|
+
StackifyRubyAPM.agent.error '[HTTPartySpy] Error: getting status code or updating request/response context.'
|
70
|
+
StackifyRubyAPM.agent.error "[HTTPartySpy] #{e.inspect}"
|
71
|
+
end
|
72
|
+
res
|
52
73
|
end
|
53
74
|
end
|
54
75
|
end
|
@@ -16,31 +16,52 @@ module StackifyRubyAPM
|
|
16
16
|
req = nil
|
17
17
|
return request_without_apm(method, uri, *args, &block) unless StackifyRubyAPM.current_transaction
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
# Submits HTTP request
|
27
|
-
#
|
28
|
-
req = request_without_apm(method, uri, *args, &block)
|
19
|
+
begin
|
20
|
+
# Data configuration
|
21
|
+
#
|
22
|
+
method = method.upcase
|
23
|
+
uri = uri.strip
|
24
|
+
name = "#{method} #{uri}"
|
25
|
+
type = "ext.httpclient.#{method}"
|
29
26
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
27
|
+
# Builds span context
|
28
|
+
#
|
29
|
+
ctx = Span::Context.new(
|
30
|
+
CATEGORY: 'Web External',
|
31
|
+
SUBCATEGORY: 'Execute',
|
32
|
+
URL: uri,
|
33
|
+
STATUS: '',
|
34
|
+
METHOD: method
|
35
|
+
)
|
36
|
+
rescue Exception => e
|
37
|
+
StackifyRubyAPM.agent.error "[HTTPClientSpy] Error: creating span context."
|
38
|
+
StackifyRubyAPM.agent.error "[HTTPClientSpy] #{e.inspect}"
|
39
|
+
return request_without_apm(method, uri, *args, &block)
|
40
|
+
end
|
39
41
|
|
40
42
|
# Creates new span from HTTP result
|
41
43
|
#
|
42
44
|
StackifyRubyAPM.span name, type, context: ctx do
|
43
|
-
|
45
|
+
# Submits HTTP request
|
46
|
+
#
|
47
|
+
res = request_without_apm(method, uri, *args, &block)
|
48
|
+
|
49
|
+
begin
|
50
|
+
ctx.update_status(res.status_code)
|
51
|
+
|
52
|
+
if StackifyRubyAPM.agent.config.prefix_enabled
|
53
|
+
options = args && args[0] || Hash.new
|
54
|
+
ctx.update_request_body(options[:body] || "")
|
55
|
+
ctx.update_request_headers(options[:header] || Hash.new)
|
56
|
+
ctx.update_response_body(res.body || "")
|
57
|
+
ctx.update_response_headers(res.headers || Hash.new)
|
58
|
+
end
|
59
|
+
rescue Exception => e
|
60
|
+
StackifyRubyAPM.agent.error '[HTTPClientSpy] Error: getting status code or updating request/response context.'
|
61
|
+
StackifyRubyAPM.agent.error "[HTTPClientSpy] #{e.inspect}"
|
62
|
+
end
|
63
|
+
|
64
|
+
res
|
44
65
|
end
|
45
66
|
end
|
46
67
|
end
|
@@ -10,28 +10,49 @@ module StackifyRubyAPM
|
|
10
10
|
class HTTPRbSpy
|
11
11
|
def install
|
12
12
|
HTTP::Client.class_eval do
|
13
|
-
alias_method '
|
13
|
+
alias_method 'perform_without_apm', 'perform'
|
14
14
|
|
15
15
|
# Make HTTP request
|
16
|
-
def
|
17
|
-
return
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
16
|
+
def perform(req, options)
|
17
|
+
return perform_without_apm(req, options) unless StackifyRubyAPM.current_transaction
|
18
|
+
|
19
|
+
begin
|
20
|
+
method = req.verb.upcase
|
21
|
+
uri = req.uri.to_s.strip
|
22
|
+
name = "#{method} #{uri}"
|
23
|
+
type = "ext.httprb.#{method}"
|
24
|
+
|
25
|
+
ctx = Span::Context.new(
|
26
|
+
CATEGORY: 'Web External',
|
27
|
+
SUBCATEGORY: 'Execute',
|
28
|
+
URL: uri,
|
29
|
+
STATUS: '',
|
30
|
+
METHOD: method
|
31
|
+
)
|
32
|
+
rescue Exception => e
|
33
|
+
StackifyRubyAPM.agent.error "[HTTPRbSpy] Error: creating span context."
|
34
|
+
StackifyRubyAPM.agent.error "[HTTPRbSpy] #{e.inspect}"
|
35
|
+
return perform_without_apm(req, options)
|
36
|
+
end
|
32
37
|
|
33
38
|
StackifyRubyAPM.span name, type, context: ctx do
|
34
|
-
req
|
39
|
+
res = perform_without_apm(req, options)
|
40
|
+
|
41
|
+
begin
|
42
|
+
ctx.update_status(res.code)
|
43
|
+
|
44
|
+
if StackifyRubyAPM.agent.config.prefix_enabled
|
45
|
+
ctx.update_request_body(req.body.source || "")
|
46
|
+
ctx.update_request_headers(req.headers || Hash.new)
|
47
|
+
ctx.update_response_body(res.body || "")
|
48
|
+
ctx.update_response_headers(res.headers || Hash.new)
|
49
|
+
end
|
50
|
+
rescue Exception => e
|
51
|
+
StackifyRubyAPM.agent.error '[HTTPRbSpy] Error: getting status code or updating request/response context.'
|
52
|
+
StackifyRubyAPM.agent.error "[HTTPRbSpy] #{e.inspect}"
|
53
|
+
end
|
54
|
+
|
55
|
+
res
|
35
56
|
end
|
36
57
|
end
|
37
58
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Monkey patch for the Log4r::Outputter class for logging log message.
|
4
|
+
#
|
5
|
+
module StackifyRubyAPM
|
6
|
+
module Spies
|
7
|
+
class Log4rSpy
|
8
|
+
def install
|
9
|
+
Log4r::Outputter.module_eval do
|
10
|
+
alias_method 'canonical_log_without_apm', 'canonical_log'
|
11
|
+
|
12
|
+
# Log message formatted to a logevent object
|
13
|
+
def canonical_log(logevent)
|
14
|
+
return canonical_log_without_apm(logevent) unless StackifyRubyAPM.current_transaction
|
15
|
+
|
16
|
+
begin
|
17
|
+
name = 'log4r'
|
18
|
+
type = 'ext.log4r'
|
19
|
+
log_message = ''
|
20
|
+
exception = nil
|
21
|
+
msg = logevent.data
|
22
|
+
|
23
|
+
case msg
|
24
|
+
when ::String
|
25
|
+
log_message = msg
|
26
|
+
when ::Exception
|
27
|
+
log_message = msg.message
|
28
|
+
exception = "(#{ msg.class })\n#{ msg.backtrace.join("\n") if msg.backtrace }"
|
29
|
+
else
|
30
|
+
log_message = msg.inspect
|
31
|
+
end
|
32
|
+
|
33
|
+
ctx = Span::Context.new(
|
34
|
+
CATEGORY: 'Log',
|
35
|
+
SUBCATEGORY: 'Log4r',
|
36
|
+
LEVEL: Log4r::LNAMES[logevent.level] || 'ANY',
|
37
|
+
MESSAGE: log_message
|
38
|
+
)
|
39
|
+
|
40
|
+
if exception
|
41
|
+
ctx.EXCEPTION = exception
|
42
|
+
end
|
43
|
+
rescue Exception => e
|
44
|
+
StackifyRubyAPM.agent.error "[Log4rSpy] Error: creating span context."
|
45
|
+
StackifyRubyAPM.agent.error "[Log4rSpy] #{e.inspect}"
|
46
|
+
return canonical_log_without_apm(logevent)
|
47
|
+
end
|
48
|
+
|
49
|
+
StackifyRubyAPM.span name, type, context: ctx do
|
50
|
+
canonical_log_without_apm(logevent)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
register 'Log4r::Outputter', 'log4r', Log4rSpy.new
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Monkey patch for the Logger class for logging log messages.
|
5
|
+
#
|
6
|
+
module StackifyRubyAPM
|
7
|
+
module Spies
|
8
|
+
class LoggerSpy
|
9
|
+
NAME = 'logger'
|
10
|
+
TYPE = 'core.devlog'
|
11
|
+
|
12
|
+
def install
|
13
|
+
Logger.class_eval do
|
14
|
+
alias_method 'debug_without_apm', 'debug'
|
15
|
+
alias_method 'info_without_apm', 'info'
|
16
|
+
alias_method 'warn_without_apm', 'warn'
|
17
|
+
alias_method 'error_without_apm', 'error'
|
18
|
+
alias_method 'fatal_without_apm', 'fatal'
|
19
|
+
alias_method 'unknown_without_apm', 'unknown'
|
20
|
+
|
21
|
+
def debug(progname = nil, &block)
|
22
|
+
return debug_without_apm(progname, &block) unless StackifyRubyAPM.current_transaction
|
23
|
+
ctx = StackifyRubyAPM::Spies::LoggerSpy.get_log_context('DEBUG', nil, progname, &block)
|
24
|
+
StackifyRubyAPM.span NAME, TYPE, context: ctx do
|
25
|
+
debug_without_apm(progname, &block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def info(progname = nil, &block)
|
30
|
+
return info_without_apm(progname, &block) unless StackifyRubyAPM.current_transaction
|
31
|
+
ctx = StackifyRubyAPM::Spies::LoggerSpy.get_log_context('INFO', nil, progname, &block)
|
32
|
+
StackifyRubyAPM.span NAME, TYPE, context: ctx do
|
33
|
+
info_without_apm(progname, &block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def warn(progname = nil, &block)
|
38
|
+
return warn_without_apm(progname, &block) unless StackifyRubyAPM.current_transaction
|
39
|
+
ctx = StackifyRubyAPM::Spies::LoggerSpy.get_log_context('WARN', nil, progname, &block)
|
40
|
+
StackifyRubyAPM.span NAME, TYPE, context: ctx do
|
41
|
+
warn_without_apm(progname, &block)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def error(progname = nil, &block)
|
46
|
+
return error_without_apm(progname, &block) unless StackifyRubyAPM.current_transaction
|
47
|
+
ctx = StackifyRubyAPM::Spies::LoggerSpy.get_log_context('ERROR', nil, progname, &block)
|
48
|
+
StackifyRubyAPM.span NAME, TYPE, context: ctx do
|
49
|
+
error_without_apm(progname, &block)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def fatal(progname = nil, &block)
|
54
|
+
return fatal_without_apm(progname, &block) unless StackifyRubyAPM.current_transaction
|
55
|
+
ctx = StackifyRubyAPM::Spies::LoggerSpy.get_log_context('FATAL', nil, progname, &block)
|
56
|
+
StackifyRubyAPM.span NAME, TYPE, context: ctx do
|
57
|
+
fatal_without_apm(progname, &block)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def unknown(progname = nil, &block)
|
62
|
+
return unknown_without_apm(progname, &block) unless StackifyRubyAPM.current_transaction
|
63
|
+
ctx = StackifyRubyAPM::Spies::LoggerSpy.get_log_context('UNKNOWN', nil, progname, &block)
|
64
|
+
StackifyRubyAPM.span NAME, TYPE, context: ctx do
|
65
|
+
unknown_without_apm(progname, &block)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# create and return logger span context
|
72
|
+
def self.get_log_context(severity, message, progname)
|
73
|
+
ctx = nil
|
74
|
+
|
75
|
+
begin
|
76
|
+
log_message = ''
|
77
|
+
exception = nil
|
78
|
+
|
79
|
+
if message.nil?
|
80
|
+
msg = progname
|
81
|
+
else
|
82
|
+
msg = message
|
83
|
+
end
|
84
|
+
|
85
|
+
case msg
|
86
|
+
when ::String
|
87
|
+
log_message = msg
|
88
|
+
when ::Exception
|
89
|
+
log_message = msg.message
|
90
|
+
exception = "(#{ msg.class })\n#{ msg.backtrace.join("\n") if msg.backtrace }"
|
91
|
+
else
|
92
|
+
log_message = msg.inspect
|
93
|
+
end
|
94
|
+
|
95
|
+
ctx = Span::Context.new(
|
96
|
+
CATEGORY: 'Log',
|
97
|
+
SUBCATEGORY: 'Logger',
|
98
|
+
LEVEL: severity || 'ANY',
|
99
|
+
MESSAGE: log_message
|
100
|
+
)
|
101
|
+
|
102
|
+
if exception
|
103
|
+
ctx.EXCEPTION = exception
|
104
|
+
end
|
105
|
+
rescue Exception => e
|
106
|
+
StackifyRubyAPM.agent.error "[LoggerSpy] Error: creating span context."
|
107
|
+
StackifyRubyAPM.agent.error "[LoggerSpy] #{e.inspect}"
|
108
|
+
end
|
109
|
+
|
110
|
+
ctx
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
register 'Logger', 'logger', LoggerSpy.new
|
115
|
+
end
|
116
|
+
end
|