stackify-ruby-apm 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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