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,48 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
# Spies for active record when sinatra framework is used and active_record is being extended. (mysql adapter)
|
|
3
|
-
#
|
|
4
|
-
module StackifyRubyAPM
|
|
5
|
-
# @api private
|
|
6
|
-
module Spies
|
|
7
|
-
# @api private
|
|
8
|
-
class SqliteAdapterSpy
|
|
9
|
-
TYPE = 'db.sinatra_active_record.sql'.freeze
|
|
10
|
-
|
|
11
|
-
# rubocop:disable Metrics/MethodLength
|
|
12
|
-
def install
|
|
13
|
-
ActiveRecord::ConnectionAdapters::SQLite3Adapter.class_eval do
|
|
14
|
-
alias exec_query_without_apm exec_query
|
|
15
|
-
|
|
16
|
-
|
|
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: "sqlite"
|
|
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
|
-
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
# rubocop:enable Metrics/MethodLength
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
register 'ActiveRecord::ConnectionAdapters::SQLite3Adapter', 'active_record/connection_adapters/sqlite3_adapter', SqliteAdapterSpy.new
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
data/lib/stackify/stacktrace.rb
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
#
|
|
3
|
-
# This module starts creation for frames
|
|
4
|
-
#
|
|
5
|
-
module StackifyRubyAPM
|
|
6
|
-
# @api private
|
|
7
|
-
class Stacktrace
|
|
8
|
-
attr_accessor :frames
|
|
9
|
-
|
|
10
|
-
def length
|
|
11
|
-
frames.length
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def to_a
|
|
15
|
-
frames.map(&:to_h)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module StackifyRubyAPM
|
|
4
|
-
class Stacktrace
|
|
5
|
-
# @api private
|
|
6
|
-
class Frame
|
|
7
|
-
include NaivelyHashable
|
|
8
|
-
|
|
9
|
-
attr_accessor(
|
|
10
|
-
:abs_path,
|
|
11
|
-
:filename,
|
|
12
|
-
:function,
|
|
13
|
-
:vars,
|
|
14
|
-
:pre_context,
|
|
15
|
-
:context_line,
|
|
16
|
-
:post_context,
|
|
17
|
-
:library_frame,
|
|
18
|
-
:lineno,
|
|
19
|
-
:module,
|
|
20
|
-
:Method,
|
|
21
|
-
:colno
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
# rubocop:disable Metrics/AbcSize
|
|
25
|
-
def build_context(context_line_count)
|
|
26
|
-
return unless abs_path && context_line_count > 0
|
|
27
|
-
|
|
28
|
-
padding = (context_line_count - 1) / 2
|
|
29
|
-
from = lineno - padding - 1
|
|
30
|
-
from = 0 if from < 0
|
|
31
|
-
to = lineno + padding - 1
|
|
32
|
-
file_lines = read_lines(abs_path, from..to)
|
|
33
|
-
|
|
34
|
-
self.context_line = file_lines[padding]
|
|
35
|
-
self.pre_context = file_lines.first(padding)
|
|
36
|
-
self.post_context = file_lines.last(padding)
|
|
37
|
-
end
|
|
38
|
-
# rubocop:enable Metrics/AbcSize
|
|
39
|
-
|
|
40
|
-
private
|
|
41
|
-
|
|
42
|
-
def read_lines(path, range)
|
|
43
|
-
File.readlines(path)[range]
|
|
44
|
-
rescue Errno::ENOENT
|
|
45
|
-
[]
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
data/lib/stackify/transaction.rb
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
#
|
|
3
|
-
# This class creates and initializes a new transaction.
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
module StackifyRubyAPM
|
|
7
|
-
require 'securerandom'
|
|
8
|
-
# @api private
|
|
9
|
-
class Transaction
|
|
10
|
-
DEFAULT_TYPE = 'custom'.freeze
|
|
11
|
-
|
|
12
|
-
# rubocop:disable Metrics/MethodLength
|
|
13
|
-
def initialize instrumenter, name = nil, type = nil, context: nil
|
|
14
|
-
# puts "Loads transaction new initialize instrumenter, name = nil, type = nil, context: nil"
|
|
15
|
-
@id = SecureRandom.uuid
|
|
16
|
-
@instrumenter = instrumenter
|
|
17
|
-
@name = name
|
|
18
|
-
@type = type || DEFAULT_TYPE
|
|
19
|
-
@timestamp = (Time.now).to_f * 1000
|
|
20
|
-
|
|
21
|
-
@spans = []
|
|
22
|
-
@span_id_ticker = -1
|
|
23
|
-
@dropped_spans = 0
|
|
24
|
-
|
|
25
|
-
@notifications = [] # for AS::Notifications
|
|
26
|
-
@context = context || Context.new
|
|
27
|
-
@exceptions = []
|
|
28
|
-
|
|
29
|
-
yield self if block_given?
|
|
30
|
-
end
|
|
31
|
-
# rubocop:enable Metrics/MethodLength
|
|
32
|
-
|
|
33
|
-
attr_accessor :name, :type, :http_status
|
|
34
|
-
attr_reader :id, :context, :duration, :dropped_spans,
|
|
35
|
-
:timestamp, :spans, :result, :notifications, :instrumenter, :exceptions
|
|
36
|
-
|
|
37
|
-
def add_exception exception
|
|
38
|
-
@exceptions << exception
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def release
|
|
42
|
-
@instrumenter.current_transaction = nil
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def done result = nil
|
|
46
|
-
@duration = (Time.now).to_f * 1000
|
|
47
|
-
@result = result
|
|
48
|
-
@http_status = result
|
|
49
|
-
|
|
50
|
-
self
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def done?
|
|
54
|
-
!!@duration
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def submit result = nil, status: nil, headers: {}
|
|
58
|
-
done result unless duration
|
|
59
|
-
if status
|
|
60
|
-
context.response = Context::Response.new(status, headers: headers)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
release
|
|
64
|
-
@instrumenter.submit_transaction self
|
|
65
|
-
|
|
66
|
-
self
|
|
67
|
-
end
|
|
68
|
-
# This method is being used in unit testing
|
|
69
|
-
def running_spans
|
|
70
|
-
spans.select(&:running?)
|
|
71
|
-
end
|
|
72
|
-
# rubocop:disable Metrics/MethodLength
|
|
73
|
-
def span name, type = nil, backtrace: nil, context: nil
|
|
74
|
-
span = build_and_start_span(name, type, context, backtrace)
|
|
75
|
-
return span unless block_given?
|
|
76
|
-
|
|
77
|
-
begin
|
|
78
|
-
result = yield span
|
|
79
|
-
ensure
|
|
80
|
-
span.done
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
result
|
|
84
|
-
end
|
|
85
|
-
# rubocop:enable Metrics/MethodLength
|
|
86
|
-
|
|
87
|
-
def current_span
|
|
88
|
-
spans.reverse.lazy.find(&:running?)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def inspect
|
|
92
|
-
"<StackifyRubyAPM::Transaction id:#{id}" \
|
|
93
|
-
" name:#{name.inspect}" \
|
|
94
|
-
" type:#{type.inspect}" \
|
|
95
|
-
'>'
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
private
|
|
99
|
-
|
|
100
|
-
def next_span_id
|
|
101
|
-
@span_id_ticker += 1
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def next_span name, type, context
|
|
105
|
-
Span.new(
|
|
106
|
-
self,
|
|
107
|
-
next_span_id,
|
|
108
|
-
name,
|
|
109
|
-
type,
|
|
110
|
-
parent_id: current_span.nil? ? -1 : current_span.id,
|
|
111
|
-
context: context,
|
|
112
|
-
http_status: @http_status
|
|
113
|
-
)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def span_frames_min_duration?
|
|
117
|
-
@instrumenter.agent.config.span_frames_min_duration != 0
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def build_and_start_span name, type, context, backtrace
|
|
121
|
-
span = next_span(name, type, context)
|
|
122
|
-
spans << span
|
|
123
|
-
|
|
124
|
-
if backtrace && span_frames_min_duration?
|
|
125
|
-
span.original_backtrace = backtrace
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
span.start
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
end
|
|
132
|
-
end
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module StackifyRubyAPM
|
|
4
|
-
module Util
|
|
5
|
-
# @api private
|
|
6
|
-
class LruCache
|
|
7
|
-
def initialize(max_size = 512, &block)
|
|
8
|
-
@max_size = max_size
|
|
9
|
-
@data = Hash.new(&block)
|
|
10
|
-
@mutex = Mutex.new
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def [](key)
|
|
14
|
-
@mutex.synchronize do
|
|
15
|
-
val = @data[key]
|
|
16
|
-
return unless val
|
|
17
|
-
add(key, val)
|
|
18
|
-
val
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def []=(key, val)
|
|
23
|
-
@mutex.synchronize do
|
|
24
|
-
add(key, val)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def length
|
|
29
|
-
@data.length
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def to_a
|
|
33
|
-
@data.to_a
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
def add(key, val)
|
|
39
|
-
@data.delete(key)
|
|
40
|
-
@data[key] = val
|
|
41
|
-
|
|
42
|
-
return unless @data.length > @max_size
|
|
43
|
-
|
|
44
|
-
@data.delete(@data.first[0])
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
data/lib/stackify/version.rb
DELETED