stackify-ruby-apm 1.14.3 → 1.14.8
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/context_builder.rb +2 -0
- data/lib/stackify_apm/helper/database_helper.rb +2 -0
- data/lib/stackify_apm/instrumenter_helper.rb +10 -1
- data/lib/stackify_apm/logger/log_device.rb +2 -0
- data/lib/stackify_apm/middleware.rb +2 -0
- data/lib/stackify_apm/normalizers/active_record.rb +62 -8
- data/lib/stackify_apm/spies/custom_instrumenter.rb +13 -2
- data/lib/stackify_apm/spies/faraday.rb +1 -1
- data/lib/stackify_apm/spies/redis.rb +7 -3
- data/lib/stackify_apm/spies/sinatra_activerecord/mysql_adapter.rb +3 -0
- data/lib/stackify_apm/spies/sinatra_activerecord/postgresql_adapter.rb +2 -0
- data/lib/stackify_apm/spies/sinatra_activerecord/sqlite_adapter.rb +2 -0
- data/lib/stackify_apm/transport/agent_http_client.rb +1 -1
- data/lib/stackify_apm/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 071d161a1f209e027f271d462fdc8cdf57c8d68197d8ae1ed6190cebe9e2114b
|
4
|
+
data.tar.gz: 815f90aaa08dcd15878bc93e7a18d71619a8cd1f55959ef18c0918267754a3df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35d8996e6e1bdc270ba44a231e405275d7b090efd316daa590aeefe2875a0b586f19b8c280fdab16c8a8e5f9b482038c344b40c1893358528a9e4ffa2b5018d0
|
7
|
+
data.tar.gz: 1ce353e5bf442f5ae8c18a5f1c323f0aa177586dc46942f9082baf1fa1acfc1980b04f3b5745a538f5eab7271c7bfdd0a340e2455d97d1695eafac7c9522d17f
|
@@ -35,6 +35,8 @@ module StackifyRubyAPM
|
|
35
35
|
classspyitem = "#{current_class}Spy"
|
36
36
|
module_consget_spy = Module.const_get(current_class)
|
37
37
|
current_method_without = "_without_apm_#{current_method}"
|
38
|
+
is_private_method = options[:is_private_method] || false
|
39
|
+
is_protected_method = options[:is_protected_method] || false
|
38
40
|
|
39
41
|
unless @custom_instrumented[current_class.to_s]
|
40
42
|
@custom_instrumented[current_class.to_s] = {}
|
@@ -63,7 +65,14 @@ module StackifyRubyAPM
|
|
63
65
|
def install
|
64
66
|
#{current_class}.class_eval do
|
65
67
|
alias_method "#{current_method_without}", "#{current_method}"
|
66
|
-
|
68
|
+
|
69
|
+
#{
|
70
|
+
if is_private_method
|
71
|
+
then "private"
|
72
|
+
elsif is_protected_method
|
73
|
+
then "protected"
|
74
|
+
end
|
75
|
+
}
|
67
76
|
def #{current_method}(*args, &block)
|
68
77
|
if StackifyRubyAPM.current_transaction.nil? && #{!transaction.nil?}
|
69
78
|
t = StackifyRubyAPM.transaction("custom.#{current_class}.#{current_method}", TRACETYPE)
|
@@ -88,6 +88,8 @@ module StackifyRubyAPM
|
|
88
88
|
|
89
89
|
begin
|
90
90
|
dir_name = File.dirname(filename)
|
91
|
+
# repath current file due to windows separator \\ doesn't work with Dir.glob
|
92
|
+
dir_name = dir_name.split(File::ALT_SEPARATOR).join(File::SEPARATOR)
|
91
93
|
search_files = File.join("#{dir_name}", "{[!stackify-ruby-apm]*}.log")
|
92
94
|
log_files = Dir.glob(search_files).sort_by { |f| File.stat(f).mtime}.reverse
|
93
95
|
|
@@ -127,6 +127,8 @@ module StackifyRubyAPM
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def streaming?(env)
|
130
|
+
# Not used
|
131
|
+
# Possible use of ActiveSupport.on_load(:action_controller_base)
|
130
132
|
return false unless defined?(ActionController::Live)
|
131
133
|
|
132
134
|
env['action_controller.instance'].class.included_modules.include?(ActionController::Live)
|
@@ -1,4 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# Not used
|
3
|
+
# Possible use of ActiveSupport.on_load(:active_record)
|
2
4
|
|
3
5
|
require 'stackify_apm/helper/database_helper'
|
4
6
|
|
@@ -12,8 +14,6 @@ module StackifyRubyAPM
|
|
12
14
|
|
13
15
|
def initialize(*args)
|
14
16
|
super(*args)
|
15
|
-
|
16
|
-
@type = format('db.%s.sql', lookup_adapter || 'unknown').freeze
|
17
17
|
end
|
18
18
|
|
19
19
|
def normalize(_transaction, _name, payload)
|
@@ -23,7 +23,9 @@ module StackifyRubyAPM
|
|
23
23
|
check_prepared_stmt(statement, payload)
|
24
24
|
name = payload[:sql] || payload[:name] || 'Default'
|
25
25
|
context = Span::Context.new(statement)
|
26
|
-
|
26
|
+
|
27
|
+
type = format('db.%s.sql', lookup_adapter(payload) || 'unknown').freeze
|
28
|
+
[name, type, context]
|
27
29
|
end
|
28
30
|
|
29
31
|
private
|
@@ -31,7 +33,7 @@ module StackifyRubyAPM
|
|
31
33
|
def query_variables(payload)
|
32
34
|
adapter_config = lookup_adapter_config
|
33
35
|
props = get_common_db_properties
|
34
|
-
props[:PROVIDER] = get_profiler(lookup_adapter)
|
36
|
+
props[:PROVIDER] = get_profiler(lookup_adapter(payload))
|
35
37
|
props[:SQL] = payload[:sql]
|
36
38
|
if adapter_config
|
37
39
|
props[:URL] = "#{adapter_config[:host]}:#{adapter_config[:port]}"
|
@@ -39,15 +41,67 @@ module StackifyRubyAPM
|
|
39
41
|
props
|
40
42
|
end
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
+
# Ideally the application doesn't connect to the database during boot,
|
45
|
+
# but sometimes it does. In case it did, we want to empty out the
|
46
|
+
# connection pools so that a non-database-using process (e.g. a master
|
47
|
+
# process in a forking server model) doesn't retain a needless
|
48
|
+
# connection. If it was needed, the incremental cost of reestablishing
|
49
|
+
# this connection is trivial: the rest of the pool would need to be
|
50
|
+
# populated anyway.
|
51
|
+
#
|
52
|
+
# Reference: https://github.com/rails/rails/blob/main/activerecord/lib/active_record/railtie.rb#L253
|
53
|
+
#
|
54
|
+
# Miko: Considering we are getting the connection method, it is retrieving connection from the connection pool
|
55
|
+
# Connection Method: lib/active_record/connection_handling.rb#L264
|
56
|
+
# Retrieve Connection: lib/active_record/connection_handling.rb#L309
|
57
|
+
# Handler Retrieve Connection: lib/active_record/connection_adapters/abstract/connection_pool.rb#L1111
|
58
|
+
|
59
|
+
def lookup_adapter(payload)
|
60
|
+
connection = nil
|
61
|
+
if (payload.key?(:connection))
|
62
|
+
connection = payload[:connection]
|
63
|
+
elsif ::ActiveRecord::Base.connection_pool.instance_variable_defined?(:@reserved_connections) and payload.key?(:connection_id)
|
64
|
+
connection_id = payload[:connection_id] # Connection ID here is the object_id of the connection object
|
65
|
+
connections = ::ActiveRecord::Base.connection_pool.instance_variable_get(:@reserved_connections) # Lets check the reserved connections
|
66
|
+
|
67
|
+
if (
|
68
|
+
(connections.class != nil and connections.respond_to?(:class) and
|
69
|
+
(connections.class.to_s == 'ThreadSafe::Cache' or connections.class.to_s == 'Hash')
|
70
|
+
) and connections.size()
|
71
|
+
)
|
72
|
+
connections.each_value do |val|
|
73
|
+
if val.object_id == connection_id
|
74
|
+
connection = val
|
75
|
+
break
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
if (connection.nil?)
|
82
|
+
return 'generic'
|
83
|
+
end
|
84
|
+
|
85
|
+
if (connection.respond_to?(:adapter_name) && connection.adapter_name.nil?)
|
86
|
+
return 'generic'
|
87
|
+
end
|
88
|
+
|
89
|
+
connection.adapter_name.downcase
|
44
90
|
rescue StandardError => error
|
45
91
|
debug '[SqlNormalizer] lookup_adapter err: ' + error.inspect.to_s
|
46
92
|
nil
|
47
93
|
end
|
48
94
|
|
49
95
|
def lookup_adapter_config
|
50
|
-
|
96
|
+
config = nil
|
97
|
+
if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('6.1')
|
98
|
+
config = ::ActiveRecord::Base.connection_db_config
|
99
|
+
else
|
100
|
+
config = ::ActiveRecord::Base.connection_config
|
101
|
+
end
|
102
|
+
if (config != nil && config.respond_to(:to_h))
|
103
|
+
config.to_h
|
104
|
+
end
|
51
105
|
rescue StandardError => error
|
52
106
|
debug '[SqlNormalizer] lookup_adapter_config err: ' + error.inspect.to_s
|
53
107
|
nil
|
@@ -55,7 +109,7 @@ module StackifyRubyAPM
|
|
55
109
|
|
56
110
|
def check_prepared_stmt(statement, payload)
|
57
111
|
if StackifyRubyAPM.agent.config.prefix_enabled
|
58
|
-
case get_profiler(lookup_adapter)
|
112
|
+
case get_profiler(lookup_adapter(payload))
|
59
113
|
when 'generic', 'mysql', 'sqlite', 'oracle', 'db2'
|
60
114
|
check_prepared_stmt_by_placeholder(payload[:sql].include?('?'), statement, payload)
|
61
115
|
when 'postgresql'
|
@@ -70,6 +70,8 @@ module StackifyRubyAPM
|
|
70
70
|
mod_constant = Module.const_get(current_class.to_s)
|
71
71
|
klass_method_flag = mod_constant.method_defined?(current_method.to_s)
|
72
72
|
singleton_method_flag = mod_constant.respond_to?(current_method.to_s)
|
73
|
+
klass_private_method_flag = mod_constant.private_method_defined?(current_method.to_s)
|
74
|
+
klass_protected_method_flag = mod_constant.protected_method_defined?(current_method.to_s)
|
73
75
|
|
74
76
|
class_location = mod_constant.instance_methods(false).map do |m|
|
75
77
|
mod_constant.instance_method(m).source_location.first
|
@@ -77,8 +79,17 @@ module StackifyRubyAPM
|
|
77
79
|
|
78
80
|
class_path = class_location.last
|
79
81
|
|
80
|
-
if klass_method_flag
|
81
|
-
StackifyRubyAPM::InstrumenterHelper.m_class(
|
82
|
+
if klass_method_flag || klass_private_method_flag
|
83
|
+
StackifyRubyAPM::InstrumenterHelper.m_class(
|
84
|
+
tracked_func,
|
85
|
+
current_class,
|
86
|
+
class_path,
|
87
|
+
current_method: current_method,
|
88
|
+
tracked_function_name: tracked_function_name,
|
89
|
+
is_transaction: transaction,
|
90
|
+
is_private_method: klass_private_method_flag,
|
91
|
+
is_protected_method: klass_protected_method_flag
|
92
|
+
)
|
82
93
|
elsif singleton_method_flag
|
83
94
|
StackifyRubyAPM::InstrumenterHelper.m_singleton(tracked_func, current_class, class_path, current_method: current_method, tracked_function_name: tracked_function_name, is_transaction: transaction)
|
84
95
|
end
|
@@ -33,7 +33,11 @@ module StackifyRubyAPM
|
|
33
33
|
# Possible formats:
|
34
34
|
# `<namespace:key/method_name/expires_in=300/ttl=60/>`
|
35
35
|
# `<namespace:key/expires_in=300/ttl=60/>`
|
36
|
-
|
36
|
+
if redis_key.nil?
|
37
|
+
redis_key = redis_details[1]
|
38
|
+
else
|
39
|
+
redis_key = args[0..1].join('/') if args.length > 1 && !args[1].include?('=')
|
40
|
+
end
|
37
41
|
end
|
38
42
|
|
39
43
|
return call_without_apm(command, &block) if command[0] == :auth
|
@@ -48,8 +52,8 @@ module StackifyRubyAPM
|
|
48
52
|
OPERATION: name,
|
49
53
|
URL: "#{self.options[:host]}:#{self.options[:port]}"
|
50
54
|
}.tap do |hash|
|
51
|
-
hash[:CACHEKEY] = redis_key unless redis_key.empty?
|
52
|
-
hash[:CACHENAME] = redis_nspace unless redis_nspace.empty?
|
55
|
+
hash[:CACHEKEY] = redis_key unless redis_key.nil? || redis_key.empty?
|
56
|
+
hash[:CACHENAME] = redis_nspace unless redis_nspace.nil? || redis_nspace.empty?
|
53
57
|
end
|
54
58
|
|
55
59
|
ctx = Span::Context.new(context)
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Spies for active record when sinatra framework is used and active_record is being extended. (mysql adapter)
|
4
|
+
# Not used
|
5
|
+
# Possible use of ActiveSupport.on_load(:active_record)
|
4
6
|
|
5
7
|
require 'stackify_apm/helper/database_helper'
|
6
8
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Spies for active record when sinatra framework is used and active_record is being extended. (mysql adapter)
|
4
|
+
# Not used
|
5
|
+
# Possible use of ActiveSupport.on_load(:active_record)
|
4
6
|
|
5
7
|
require 'stackify_apm/helper/database_helper'
|
6
8
|
|
@@ -42,7 +42,7 @@ module StackifyRubyAPM
|
|
42
42
|
message = get_json_message(transactions)
|
43
43
|
conn = Faraday.new(ssl: { verify: false })
|
44
44
|
response = conn.post do |req|
|
45
|
-
req.url URI(@config.transport_http_endpoint + @config.agent_traces_url)
|
45
|
+
req.url URI(@config.transport_http_endpoint + @config.agent_traces_url).to_s
|
46
46
|
req.headers = get_json_headers
|
47
47
|
req.body = message
|
48
48
|
end
|
data/lib/stackify_apm/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stackify-ruby-apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.14.
|
4
|
+
version: 1.14.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stackify
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|