stackify-ruby-apm 1.0.1 → 1.1.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +38 -0
- data/.ruby-version +1 -0
- data/Gemfile +17 -11
- data/Gemfile.lock +98 -95
- data/Rakefile +7 -5
- data/docker/stackify-ruby +8 -0
- data/docker/stackify-ruby-rvm +10 -0
- data/docker/stackify-ruby-test +28 -0
- data/lib/{stackify → stackify_apm}/agent.rb +42 -33
- data/lib/{stackify → stackify_apm}/config.rb +56 -39
- data/lib/{stackify → stackify_apm}/context.rb +5 -6
- data/lib/{stackify → stackify_apm}/context/request.rb +0 -0
- data/lib/{stackify → stackify_apm}/context/request/socket.rb +0 -0
- data/lib/{stackify → stackify_apm}/context/request/url.rb +2 -6
- data/lib/stackify_apm/context/response.rb +33 -0
- data/lib/{stackify → stackify_apm}/context_builder.rb +2 -5
- data/lib/{stackify → stackify_apm}/error.rb +7 -6
- data/lib/stackify_apm/error/exception.rb +37 -0
- data/lib/stackify_apm/error/log.rb +24 -0
- data/lib/stackify_apm/error_builder.rb +61 -0
- data/lib/stackify_apm/helper/database_helper.rb +27 -0
- data/lib/{stackify → stackify_apm}/instrumenter.rb +12 -19
- data/lib/{stackify → stackify_apm}/internal_error.rb +0 -0
- data/lib/{stackify → stackify_apm}/log.rb +0 -0
- data/lib/{stackify → stackify_apm}/logger/log_device.rb +22 -11
- data/lib/{stackify → stackify_apm}/logger/logger_high_version.rb +1 -6
- data/lib/{stackify → stackify_apm}/logger/logger_lower_version.rb +2 -1
- data/lib/stackify_apm/middleware.rb +70 -0
- data/lib/{stackify → stackify_apm}/naively_hashable.rb +1 -3
- data/lib/{stackify → stackify_apm}/normalizers.rb +3 -2
- data/lib/{stackify → stackify_apm}/normalizers/action_controller.rb +0 -0
- data/lib/{stackify → stackify_apm}/normalizers/action_mailer.rb +0 -0
- data/lib/{stackify → stackify_apm}/normalizers/action_view.rb +0 -0
- data/lib/{stackify → stackify_apm}/normalizers/active_record.rb +3 -25
- data/lib/{stackify → stackify_apm}/railtie.rb +5 -7
- data/lib/{stackify → stackify_apm}/root_info.rb +2 -6
- data/lib/{stackify → stackify_apm}/serializers.rb +3 -2
- data/lib/{stackify → stackify_apm}/serializers/errors.rb +7 -10
- data/lib/{stackify → stackify_apm}/serializers/transactions.rb +11 -18
- data/lib/{stackify → stackify_apm}/span.rb +8 -9
- data/lib/{stackify → stackify_apm}/span/context.rb +3 -1
- data/lib/{stackify → stackify_apm}/spies.rb +3 -2
- data/lib/{stackify → stackify_apm}/spies/action_dispatch.rb +3 -4
- data/lib/stackify_apm/spies/curb.rb +49 -0
- data/lib/stackify_apm/spies/curb/easy.rb +157 -0
- data/lib/stackify_apm/spies/curb/multi.rb +43 -0
- data/lib/{stackify → stackify_apm}/spies/httpclient.rb +10 -8
- data/lib/{stackify → stackify_apm}/spies/httprb.rb +7 -9
- data/lib/{stackify → stackify_apm}/spies/mongo.rb +5 -3
- data/lib/{stackify → stackify_apm}/spies/net_http.rb +4 -5
- data/lib/{stackify → stackify_apm}/spies/redis.rb +19 -18
- data/lib/stackify_apm/spies/sequel.rb +65 -0
- data/lib/{stackify → stackify_apm}/spies/sinatra.rb +7 -10
- data/lib/stackify_apm/spies/sinatra_activerecord/mysql_adapter.rb +201 -0
- data/lib/stackify_apm/spies/sinatra_activerecord/postgresql_adapter.rb +94 -0
- data/lib/stackify_apm/spies/sinatra_activerecord/sqlite_adapter.rb +46 -0
- data/lib/stackify_apm/spies/stackify_logger.rb +60 -0
- data/lib/{stackify → stackify_apm}/spies/tilt.rb +3 -3
- data/lib/stackify_apm/stacktrace.rb +18 -0
- data/lib/stackify_apm/stacktrace/frame.rb +47 -0
- data/lib/{stackify → stackify_apm}/stacktrace_builder.rb +10 -11
- data/lib/{stackify → stackify_apm}/subscriber.rb +20 -14
- data/lib/{stackify → stackify_apm}/trace_logger.rb +10 -16
- data/lib/stackify_apm/transaction.rb +127 -0
- data/lib/{stackify → stackify_apm}/util.rb +3 -1
- data/lib/{stackify → stackify_apm}/util/dig.rb +1 -1
- data/lib/{stackify → stackify_apm}/util/inflector.rb +0 -0
- data/lib/{stackify → stackify_apm}/util/inspector.rb +1 -3
- data/lib/stackify_apm/util/lru_cache.rb +49 -0
- data/lib/stackify_apm/util/trace_log_watcher.rb +37 -0
- data/lib/stackify_apm/version.rb +6 -0
- data/lib/{stackify → stackify_apm}/worker.rb +8 -7
- data/lib/stackify_ruby_apm.rb +18 -15
- data/run-test-docker.sh +50 -0
- data/run-test.sh +1 -3
- data/stackify-ruby-apm.gemspec +14 -11
- metadata +86 -59
- data/lib/stackify/context/response.rb +0 -37
- data/lib/stackify/error/exception.rb +0 -36
- data/lib/stackify/error/log.rb +0 -25
- data/lib/stackify/error_builder.rb +0 -65
- data/lib/stackify/middleware.rb +0 -74
- data/lib/stackify/spies/sinatra_activerecord/mysql_adapter.rb +0 -177
- data/lib/stackify/spies/sinatra_activerecord/postgresql_adapter.rb +0 -96
- data/lib/stackify/spies/sinatra_activerecord/sqlite_adapter.rb +0 -48
- data/lib/stackify/stacktrace.rb +0 -19
- data/lib/stackify/stacktrace/frame.rb +0 -50
- data/lib/stackify/transaction.rb +0 -132
- data/lib/stackify/util/lru_cache.rb +0 -49
- data/lib/stackify/version.rb +0 -4
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
# Monkey patch for the Sinatra::Base class which is responsible for handling requests.
|
|
4
|
-
#
|
|
5
4
|
|
|
6
5
|
module StackifyRubyAPM
|
|
7
6
|
# @api private
|
|
8
7
|
module Spies
|
|
9
8
|
# @api private
|
|
10
9
|
class SinatraSpy
|
|
11
|
-
# rubocop:disable Metrics/MethodLength
|
|
12
10
|
def install
|
|
13
11
|
::Sinatra::Base.class_eval do
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
alias_method 'dispatch_without_apm!', 'dispatch!'
|
|
13
|
+
alias_method 'compile_template_without_apm', 'compile_template'
|
|
16
14
|
|
|
17
|
-
# Sets transaction name from Sinatra env's route name
|
|
15
|
+
# Sets transaction name from Sinatra env's route name
|
|
18
16
|
#
|
|
19
17
|
def dispatch!(*args, &block)
|
|
20
18
|
dispatch_without_apm!(*args, &block).tap do
|
|
@@ -25,7 +23,7 @@ module StackifyRubyAPM
|
|
|
25
23
|
end
|
|
26
24
|
end
|
|
27
25
|
|
|
28
|
-
# Tilt engine template
|
|
26
|
+
# Tilt engine template
|
|
29
27
|
#
|
|
30
28
|
def compile_template(engine, data, opts, *args, &block)
|
|
31
29
|
opts[:__stackify_apm_template_name] =
|
|
@@ -38,15 +36,14 @@ module StackifyRubyAPM
|
|
|
38
36
|
end
|
|
39
37
|
end
|
|
40
38
|
end
|
|
41
|
-
# rubocop:enable Metrics/MethodLength
|
|
42
39
|
end
|
|
43
40
|
|
|
44
|
-
# Registers Sinatra spy, go to: /
|
|
41
|
+
# Registers Sinatra spy, go to: /stackify_apm/spies.rb
|
|
45
42
|
#
|
|
46
43
|
register 'Sinatra::Base', 'sinatra/base', SinatraSpy.new
|
|
47
44
|
|
|
48
45
|
# Tilt template helper & span creator
|
|
49
46
|
#
|
|
50
|
-
require '
|
|
47
|
+
require 'stackify_apm/spies/tilt'
|
|
51
48
|
end
|
|
52
49
|
end
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Spies for active record when sinatra framework is used and active_record is being extended. (mysql adapter)
|
|
4
|
+
|
|
5
|
+
module StackifyRubyAPM
|
|
6
|
+
# @api private
|
|
7
|
+
module Spies
|
|
8
|
+
# @api private
|
|
9
|
+
class MysqlAdapterSpy
|
|
10
|
+
TYPE = 'db.sinatra_active_record.sql'.freeze
|
|
11
|
+
|
|
12
|
+
if ActiveRecord::VERSION::MAJOR.to_i >= 5
|
|
13
|
+
def install
|
|
14
|
+
ActiveRecord::ConnectionAdapters::MySQL::DatabaseStatements.class_eval do
|
|
15
|
+
alias_method 'exec_query_without_apm', 'exec_query'
|
|
16
|
+
alias_method 'exec_delete_without_apm', 'exec_delete'
|
|
17
|
+
alias_method 'exec_update_without_apm', 'exec_update'
|
|
18
|
+
|
|
19
|
+
def exec_update(sql, name = nil, binds = [])
|
|
20
|
+
result = nil
|
|
21
|
+
|
|
22
|
+
unless StackifyRubyAPM.current_transaction
|
|
23
|
+
exec_update_without_apm(sql, name, binds)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
ctx = Span::Context.new(
|
|
27
|
+
CATEGORY: 'Database',
|
|
28
|
+
SUBCATEGORY: 'Execute',
|
|
29
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
30
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
31
|
+
SQL: sql,
|
|
32
|
+
PROVIDER: 'mysql'
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
result = exec_update_without_apm(sql, name, binds)
|
|
36
|
+
|
|
37
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
38
|
+
return result
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def exec_delete(sql, name = nil, binds = [])
|
|
43
|
+
result = nil
|
|
44
|
+
|
|
45
|
+
unless StackifyRubyAPM.current_transaction
|
|
46
|
+
exec_delete_without_apm(sql, name, binds)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
ctx = Span::Context.new(
|
|
50
|
+
CATEGORY: 'Database',
|
|
51
|
+
SUBCATEGORY: 'Execute',
|
|
52
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
53
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
54
|
+
SQL: sql,
|
|
55
|
+
PROVIDER: 'mysql'
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
result = exec_delete_without_apm(sql, name, binds)
|
|
59
|
+
|
|
60
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
61
|
+
return result
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
|
66
|
+
def exec_query(sql, name = 'SQL', binds = [], prepare: false)
|
|
67
|
+
result = nil
|
|
68
|
+
|
|
69
|
+
unless StackifyRubyAPM.current_transaction
|
|
70
|
+
exec_query_without_apm(sql, name, binds)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
ctx = Span::Context.new(
|
|
74
|
+
CATEGORY: 'Database',
|
|
75
|
+
SUBCATEGORY: 'Execute',
|
|
76
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
77
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
78
|
+
SQL: sql,
|
|
79
|
+
PROVIDER: 'mysql'
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
result = exec_query_without_apm(sql, name, binds)
|
|
83
|
+
|
|
84
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
85
|
+
return result
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
else
|
|
92
|
+
def install
|
|
93
|
+
ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do
|
|
94
|
+
alias_method 'exec_query_without_apm', 'exec_query'
|
|
95
|
+
alias_method 'exec_delete_without_apm', 'exec_delete'
|
|
96
|
+
alias_method 'exec_update_without_apm', 'exec_update'
|
|
97
|
+
alias_method 'exec_insert_without_apm', 'exec_insert'
|
|
98
|
+
|
|
99
|
+
def exec_query(sql, name = 'SQL', binds = [], _prepare: false)
|
|
100
|
+
result = nil
|
|
101
|
+
|
|
102
|
+
unless StackifyRubyAPM.current_transaction
|
|
103
|
+
exec_query_without_apm(sql, name, binds)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
ctx = Span::Context.new(
|
|
107
|
+
CATEGORY: 'Database',
|
|
108
|
+
SUBCATEGORY: 'Execute',
|
|
109
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
110
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
111
|
+
SQL: sql,
|
|
112
|
+
PROVIDER: 'mysql'
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
result = exec_query_without_apm(sql, name, binds)
|
|
116
|
+
|
|
117
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
118
|
+
return result
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def exec_delete(sql, name = nil, binds = [])
|
|
123
|
+
result = nil
|
|
124
|
+
|
|
125
|
+
unless StackifyRubyAPM.current_transaction
|
|
126
|
+
exec_delete_without_apm(sql, name, binds)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
ctx = Span::Context.new(
|
|
130
|
+
CATEGORY: 'Database',
|
|
131
|
+
SUBCATEGORY: 'Execute',
|
|
132
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
133
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
134
|
+
SQL: sql,
|
|
135
|
+
PROVIDER: 'mysql'
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
result = exec_delete_without_apm(sql, name, binds)
|
|
139
|
+
|
|
140
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
141
|
+
return result
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def exec_update(sql, name, binds)
|
|
146
|
+
result = nil
|
|
147
|
+
|
|
148
|
+
unless StackifyRubyAPM.current_transaction
|
|
149
|
+
exec_update_without_apm(sql, name, binds)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
ctx = Span::Context.new(
|
|
153
|
+
CATEGORY: 'Database',
|
|
154
|
+
SUBCATEGORY: 'Execute',
|
|
155
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
156
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
157
|
+
SQL: sql,
|
|
158
|
+
PROVIDER: 'mysql'
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
result = exec_update_without_apm(sql, name, binds)
|
|
162
|
+
|
|
163
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
164
|
+
return result
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def exec_insert(sql, name, binds, _pk = nil, _sequence_name = nil)
|
|
169
|
+
result = nil
|
|
170
|
+
|
|
171
|
+
unless StackifyRubyAPM.current_transaction
|
|
172
|
+
exec_insert_without_apm(sql, name, binds, _pk = nil, _sequence_name = nil)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
ctx = Span::Context.new(
|
|
176
|
+
CATEGORY: 'Database',
|
|
177
|
+
SUBCATEGORY: 'Execute',
|
|
178
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
179
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
180
|
+
SQL: sql,
|
|
181
|
+
PROVIDER: 'mysql'
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
result = exec_insert_without_apm(sql, name, binds, _pk = nil, _sequence_name = nil)
|
|
185
|
+
|
|
186
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
187
|
+
return result
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
if ActiveRecord::VERSION::MAJOR.to_i >= 5
|
|
196
|
+
register 'ActiveRecord::ConnectionAdapters::MySQL::DatabaseStatements', 'active_record/connection_adapters/mysql/database_statements', MysqlAdapterSpy.new
|
|
197
|
+
else
|
|
198
|
+
register 'ActiveRecord::ConnectionAdapters::Mysql2Adapter', 'active_record/connection_adapters/mysql2_adapter', MysqlAdapterSpy.new
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Spies for active record when sinatra framework is used and active_record is being extended. (mysql adapter)
|
|
4
|
+
|
|
5
|
+
module StackifyRubyAPM
|
|
6
|
+
# @api private
|
|
7
|
+
module Spies
|
|
8
|
+
# @api private
|
|
9
|
+
class PostgresqlAdapterSpy
|
|
10
|
+
TYPE = 'db.sinatra_active_record.sql'.freeze
|
|
11
|
+
|
|
12
|
+
def install
|
|
13
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements.class_eval do
|
|
14
|
+
alias_method 'exec_query_without_apm', 'exec_query'
|
|
15
|
+
alias_method 'exec_delete_without_apm', 'exec_delete'
|
|
16
|
+
alias_method 'exec_update_without_apm', 'exec_update'
|
|
17
|
+
|
|
18
|
+
def exec_update(sql, name = nil, binds = [])
|
|
19
|
+
result = nil
|
|
20
|
+
|
|
21
|
+
unless StackifyRubyAPM.current_transaction
|
|
22
|
+
exec_update_without_apm(sql, name, binds)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
ctx = Span::Context.new(
|
|
26
|
+
CATEGORY: 'Database',
|
|
27
|
+
SUBCATEGORY: 'Execute',
|
|
28
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
29
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
30
|
+
SQL: sql,
|
|
31
|
+
PROVIDER: 'postgresql'
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
result = exec_update_without_apm(sql, name, binds)
|
|
35
|
+
|
|
36
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
37
|
+
return result
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def exec_delete(sql, name = nil, binds = [])
|
|
42
|
+
result = nil
|
|
43
|
+
|
|
44
|
+
unless StackifyRubyAPM.current_transaction
|
|
45
|
+
exec_delete_without_apm(sql, name, binds)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
ctx = Span::Context.new(
|
|
49
|
+
CATEGORY: 'Database',
|
|
50
|
+
SUBCATEGORY: 'Execute',
|
|
51
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
52
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
53
|
+
SQL: sql,
|
|
54
|
+
PROVIDER: 'postgresql'
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
result = exec_delete_without_apm(sql, name, binds)
|
|
58
|
+
|
|
59
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
60
|
+
return result
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
|
65
|
+
def exec_query(sql, name = 'SQL', binds = [], prepare: false)
|
|
66
|
+
result = nil
|
|
67
|
+
|
|
68
|
+
unless StackifyRubyAPM.current_transaction
|
|
69
|
+
exec_query_without_apm(sql, name, binds)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
ctx = Span::Context.new(
|
|
73
|
+
CATEGORY: 'Database',
|
|
74
|
+
SUBCATEGORY: 'Execute',
|
|
75
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
76
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
77
|
+
SQL: sql,
|
|
78
|
+
PROVIDER: 'postgresql'
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
result = exec_query_without_apm(sql, name, binds)
|
|
82
|
+
|
|
83
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
84
|
+
return result
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
register 'ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements', 'active_record/connection_adapters/postgresql/database_statements', PostgresqlAdapterSpy.new
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Spies for active record when sinatra framework is used and active_record is being extended. (mysql adapter)
|
|
4
|
+
|
|
5
|
+
module StackifyRubyAPM
|
|
6
|
+
# @api private
|
|
7
|
+
module Spies
|
|
8
|
+
# @api private
|
|
9
|
+
class SqliteAdapterSpy
|
|
10
|
+
TYPE = 'db.sinatra_active_record.sql'.freeze
|
|
11
|
+
|
|
12
|
+
def install
|
|
13
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.class_eval do
|
|
14
|
+
alias_method 'exec_query_without_apm', 'exec_query'
|
|
15
|
+
|
|
16
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
|
17
|
+
def exec_query(sql, name = 'SQL', binds = [], prepare: false)
|
|
18
|
+
result = nil
|
|
19
|
+
|
|
20
|
+
unless StackifyRubyAPM.current_transaction
|
|
21
|
+
exec_query_without_apm(sql, name, binds)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
ctx = Span::Context.new(
|
|
25
|
+
CATEGORY: 'Database',
|
|
26
|
+
SUBCATEGORY: 'Execute',
|
|
27
|
+
COMPONENT_CATEGORY: 'DB Query',
|
|
28
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
|
29
|
+
SQL: sql,
|
|
30
|
+
PROVIDER: 'generic'
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
result = exec_query_without_apm(sql, name, binds)
|
|
34
|
+
|
|
35
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
|
36
|
+
return result
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
register 'ActiveRecord::ConnectionAdapters::SQLite3Adapter', 'active_record/connection_adapters/sqlite3_adapter', SqliteAdapterSpy.new
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Monkeypatch for the MsgObject to set the value id for Logging / Trace Linking
|
|
2
|
+
#
|
|
3
|
+
module StackifyRubyAPM
|
|
4
|
+
# @api private
|
|
5
|
+
module Spies
|
|
6
|
+
# @api private
|
|
7
|
+
class StackifyLoggerSpy
|
|
8
|
+
if defined? Stackify
|
|
9
|
+
::Stackify::LoggerClient.class_eval do
|
|
10
|
+
require 'securerandom'
|
|
11
|
+
alias_method 'log_message_task_without_apm', 'log_message_task'
|
|
12
|
+
alias_method 'log_exception_task_without_apm', 'log_exception_task'
|
|
13
|
+
# set trans_id parameter on log message to be passed unto MsgObject
|
|
14
|
+
def log_message_task(level, msg, call_trace)
|
|
15
|
+
return log_message_task_without_apm(level, msg, call_trace) unless StackifyRubyAPM.current_transaction
|
|
16
|
+
|
|
17
|
+
trans_id = StackifyRubyAPM.current_transaction.id
|
|
18
|
+
log_uuid = SecureRandom.uuid
|
|
19
|
+
|
|
20
|
+
# build span context
|
|
21
|
+
ctx = Span::Context.new(
|
|
22
|
+
CATEGORY: 'Stackify',
|
|
23
|
+
SUBCATEGORY: 'Log',
|
|
24
|
+
ID: log_uuid # matching the MsgObject id
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# create log span
|
|
28
|
+
StackifyRubyAPM.span(msg, 'stackify.log', context: ctx) do
|
|
29
|
+
log_message_task_without_apm(level, msg, call_trace, trans_id, log_uuid)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# set trans_id parameter on log exception to be passed unto MsgObject
|
|
34
|
+
def log_exception_task(level, ex)
|
|
35
|
+
return log_exception_task_without_apm(level, ex) unless StackifyRubyAPM.current_transaction
|
|
36
|
+
|
|
37
|
+
trans_id = StackifyRubyAPM.agent.current_transaction.id
|
|
38
|
+
log_uuid = SecureRandom.uuid
|
|
39
|
+
|
|
40
|
+
# build span context
|
|
41
|
+
ctx = Span::Context.new(
|
|
42
|
+
CATEGORY: 'Stackify',
|
|
43
|
+
SUBCATEGORY: 'Log',
|
|
44
|
+
ID: log_uuid # matching the MsgObject id
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# create log span
|
|
48
|
+
StackifyRubyAPM.span(ex.message, 'stackify.log', context: ctx) do
|
|
49
|
+
log_exception_task_without_apm(level, ex, trans_id, log_uuid)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Registers StackifyLogger spy, go to: /stackify_apm/spies.rb
|
|
57
|
+
#
|
|
58
|
+
register 'StackifyLogger', 'stackifylogger', StackifyLoggerSpy.new if defined? Stackify
|
|
59
|
+
end
|
|
60
|
+
end
|