stackify-ruby-apm 0.9.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 +7 -0
- data/.gitignore +76 -0
- data/.rspec +3 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +68 -0
- data/README.md +23 -0
- data/Rakefile +6 -0
- data/lib/stackify-ruby-apm.rb +4 -0
- data/lib/stackify/agent.rb +186 -0
- data/lib/stackify/config.rb +221 -0
- data/lib/stackify/context.rb +24 -0
- data/lib/stackify/context/request.rb +12 -0
- data/lib/stackify/context/request/socket.rb +21 -0
- data/lib/stackify/context/request/url.rb +44 -0
- data/lib/stackify/context/response.rb +24 -0
- data/lib/stackify/context_builder.rb +81 -0
- data/lib/stackify/error.rb +24 -0
- data/lib/stackify/error/exception.rb +36 -0
- data/lib/stackify/error/log.rb +25 -0
- data/lib/stackify/error_builder.rb +65 -0
- data/lib/stackify/instrumenter.rb +118 -0
- data/lib/stackify/internal_error.rb +5 -0
- data/lib/stackify/log.rb +51 -0
- data/lib/stackify/logger.rb +10 -0
- data/lib/stackify/middleware.rb +78 -0
- data/lib/stackify/naively_hashable.rb +25 -0
- data/lib/stackify/normalizers.rb +71 -0
- data/lib/stackify/normalizers/action_controller.rb +24 -0
- data/lib/stackify/normalizers/action_mailer.rb +23 -0
- data/lib/stackify/normalizers/action_view.rb +72 -0
- data/lib/stackify/normalizers/active_record.rb +71 -0
- data/lib/stackify/railtie.rb +50 -0
- data/lib/stackify/root_info.rb +58 -0
- data/lib/stackify/serializers.rb +27 -0
- data/lib/stackify/serializers/errors.rb +45 -0
- data/lib/stackify/serializers/transactions.rb +71 -0
- data/lib/stackify/span.rb +71 -0
- data/lib/stackify/span/context.rb +26 -0
- data/lib/stackify/spies.rb +89 -0
- data/lib/stackify/spies/action_dispatch.rb +26 -0
- data/lib/stackify/spies/httpclient.rb +47 -0
- data/lib/stackify/spies/mongo.rb +66 -0
- data/lib/stackify/spies/net_http.rb +47 -0
- data/lib/stackify/spies/sinatra.rb +50 -0
- data/lib/stackify/spies/tilt.rb +28 -0
- data/lib/stackify/stacktrace.rb +19 -0
- data/lib/stackify/stacktrace/frame.rb +50 -0
- data/lib/stackify/stacktrace_builder.rb +101 -0
- data/lib/stackify/subscriber.rb +113 -0
- data/lib/stackify/trace_logger.rb +66 -0
- data/lib/stackify/transaction.rb +123 -0
- data/lib/stackify/util.rb +23 -0
- data/lib/stackify/util/dig.rb +31 -0
- data/lib/stackify/util/inflector.rb +91 -0
- data/lib/stackify/util/inspector.rb +59 -0
- data/lib/stackify/util/lru_cache.rb +49 -0
- data/lib/stackify/version.rb +4 -0
- data/lib/stackify/worker.rb +119 -0
- data/lib/stackify_ruby_apm.rb +130 -0
- data/stackify-ruby-apm.gemspec +30 -0
- metadata +187 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4f5b0114ca432b384986bef0196ff170ddc28d29
|
4
|
+
data.tar.gz: 8c5850539e077d39f1b0542a9bc4c80a9d5c21cf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 51f466a4778791cb024cb072a38e590cf8f07e09a7e202be694d6bb6a97be1ea501ccb79a057c68c538e1a18186b8a375b894d8133845eb6c44608d6ec3a6681
|
7
|
+
data.tar.gz: a858da77af22d0f32415377fdd454effb880fccb7ebf2e82d2045c1da1d9d451634a5405539cae2ebcb040db701b659296828428e06c6b44f72129a3836dd29c
|
data/.gitignore
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/_yardoc/
|
4
|
+
/coverage/
|
5
|
+
/doc/
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/tmp/
|
9
|
+
|
10
|
+
# rspec failure tracking
|
11
|
+
.rspec_status
|
12
|
+
|
13
|
+
# Ignore bundler config.
|
14
|
+
/.bundle
|
15
|
+
|
16
|
+
# Ignore all logfiles and tempfiles.
|
17
|
+
/log/*
|
18
|
+
/tmp/*
|
19
|
+
!/log/.keep
|
20
|
+
!/tmp/.keep
|
21
|
+
|
22
|
+
# Ignore bundler config.
|
23
|
+
/.bundle
|
24
|
+
|
25
|
+
# Deps
|
26
|
+
node_modules
|
27
|
+
|
28
|
+
# IDE
|
29
|
+
.idea
|
30
|
+
|
31
|
+
# VS Code
|
32
|
+
.vscode
|
33
|
+
.vs
|
34
|
+
|
35
|
+
# Unnecessary since this will be a plugin
|
36
|
+
package-lock.json
|
37
|
+
|
38
|
+
# Folder config file
|
39
|
+
Desktop.ini
|
40
|
+
|
41
|
+
# Windows shortcuts
|
42
|
+
*.lnk
|
43
|
+
|
44
|
+
### OSX ###
|
45
|
+
/**/.DS_Store
|
46
|
+
/.DS_Store
|
47
|
+
.AppleDouble
|
48
|
+
.LSOverride
|
49
|
+
|
50
|
+
# Thumbnails
|
51
|
+
._*
|
52
|
+
|
53
|
+
# Files that might appear on external disk
|
54
|
+
.Spotlight-V100
|
55
|
+
.Trashes
|
56
|
+
|
57
|
+
### Linux ###
|
58
|
+
*~
|
59
|
+
|
60
|
+
# Windows image file caches
|
61
|
+
Thumbs.db
|
62
|
+
ehthumbs.db
|
63
|
+
|
64
|
+
# Ignore .byebug_history, .rspec, brakeman.html
|
65
|
+
.byebug_history
|
66
|
+
.rspec
|
67
|
+
brakeman.html
|
68
|
+
|
69
|
+
|
70
|
+
# Gem
|
71
|
+
*.gem
|
72
|
+
|
73
|
+
#bin
|
74
|
+
bin
|
75
|
+
bin/*
|
76
|
+
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
stackify-ruby-apm (0.9.0)
|
5
|
+
concurrent-ruby (~> 1.0)
|
6
|
+
delegate_matcher (~> 0.4)
|
7
|
+
webmock (~> 3.4)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.5.2)
|
13
|
+
public_suffix (>= 2.0.2, < 4.0)
|
14
|
+
concurrent-ruby (1.1.3)
|
15
|
+
crack (0.4.3)
|
16
|
+
safe_yaml (~> 1.0.0)
|
17
|
+
delegate_matcher (0.4.3)
|
18
|
+
proc_extensions (~> 0.2)
|
19
|
+
diff-lcs (1.3)
|
20
|
+
file-tail (1.2.0)
|
21
|
+
tins (~> 1.0)
|
22
|
+
hashdiff (0.3.7)
|
23
|
+
proc_extensions (0.2)
|
24
|
+
sourcify (~> 0.5)
|
25
|
+
public_suffix (3.0.3)
|
26
|
+
rake (10.5.0)
|
27
|
+
rspec (3.8.0)
|
28
|
+
rspec-core (~> 3.8.0)
|
29
|
+
rspec-expectations (~> 3.8.0)
|
30
|
+
rspec-mocks (~> 3.8.0)
|
31
|
+
rspec-core (3.8.0)
|
32
|
+
rspec-support (~> 3.8.0)
|
33
|
+
rspec-expectations (3.8.2)
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
+
rspec-support (~> 3.8.0)
|
36
|
+
rspec-mocks (3.8.0)
|
37
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
38
|
+
rspec-support (~> 3.8.0)
|
39
|
+
rspec-support (3.8.0)
|
40
|
+
ruby2ruby (2.4.1)
|
41
|
+
ruby_parser (~> 3.1)
|
42
|
+
sexp_processor (~> 4.6)
|
43
|
+
ruby_parser (3.11.0)
|
44
|
+
sexp_processor (~> 4.9)
|
45
|
+
safe_yaml (1.0.4)
|
46
|
+
sexp_processor (4.11.0)
|
47
|
+
sourcify (0.5.0)
|
48
|
+
file-tail (>= 1.0.5)
|
49
|
+
ruby2ruby (>= 1.2.5)
|
50
|
+
ruby_parser (>= 2.0.5)
|
51
|
+
sexp_processor (>= 3.0.5)
|
52
|
+
tins (1.19.0)
|
53
|
+
webmock (3.4.2)
|
54
|
+
addressable (>= 2.3.6)
|
55
|
+
crack (>= 0.3.2)
|
56
|
+
hashdiff
|
57
|
+
|
58
|
+
PLATFORMS
|
59
|
+
ruby
|
60
|
+
|
61
|
+
DEPENDENCIES
|
62
|
+
bundler (~> 1.16)
|
63
|
+
rake (~> 10.0)
|
64
|
+
rspec (~> 3.0)
|
65
|
+
stackify-ruby-apm!
|
66
|
+
|
67
|
+
BUNDLED WITH
|
68
|
+
1.16.4
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
# Stackify Ruby APM
|
3
|
+
|
4
|
+
## Installation Guide
|
5
|
+
|
6
|
+
1. Install **Stackify Linux Agent**.
|
7
|
+
|
8
|
+
2. Check that your setup meets our system requirements.
|
9
|
+
* Ruby version 2.5+
|
10
|
+
* Framework
|
11
|
+
* Ruby on Rails 5.2+
|
12
|
+
* Operating System
|
13
|
+
* Linux
|
14
|
+
|
15
|
+
3. Add `gem 'stackify-ruby-apm'` to your `Gemfile`.
|
16
|
+
|
17
|
+
4. In the root folder of your Rails app create a file `config/stackify_apm.yml` and then add this configuration
|
18
|
+
```yaml
|
19
|
+
application_name: 'Ruby Application'
|
20
|
+
environment_name: 'Production'
|
21
|
+
```
|
22
|
+
5. Build/Deploy your application:
|
23
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# The Agent interacts with the Web Application and Profiler.
|
4
|
+
# It is also responsible in requesting the instrumenter to build the transactions and spans.
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'stackify/naively_hashable'
|
8
|
+
require 'stackify/context_builder'
|
9
|
+
require 'stackify/error_builder'
|
10
|
+
require 'stackify/stacktrace_builder'
|
11
|
+
require 'stackify/error'
|
12
|
+
require 'stackify/trace_logger'
|
13
|
+
require 'stackify/spies'
|
14
|
+
require 'stackify/serializers'
|
15
|
+
require 'stackify/worker'
|
16
|
+
|
17
|
+
module StackifyRubyAPM
|
18
|
+
class Agent
|
19
|
+
include Log
|
20
|
+
|
21
|
+
LOCK = Mutex.new
|
22
|
+
|
23
|
+
def self.instance # rubocop:disable Style/TrivialAccessors
|
24
|
+
@instance
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.start(config)
|
28
|
+
return @instance if @instance
|
29
|
+
config = Config.new(config) unless config.is_a?(Config)
|
30
|
+
LOCK.synchronize do
|
31
|
+
return @instance if @instance
|
32
|
+
@instance = new(config).start
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.stop
|
37
|
+
LOCK.synchronize do
|
38
|
+
return unless @instance
|
39
|
+
|
40
|
+
@instance.stop
|
41
|
+
@instance = nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def stop
|
46
|
+
@instrumenter.stop
|
47
|
+
kill_worker
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.running?
|
52
|
+
!!@instance
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize(config)
|
56
|
+
# puts '@stackify_ruby [Agent] [lib/agent.rb] initialize()'
|
57
|
+
@config = config
|
58
|
+
@trace_logger = TraceLogger.new(config)
|
59
|
+
@messages = Queue.new
|
60
|
+
@pending_transactions = Queue.new
|
61
|
+
@instrumenter = Instrumenter.new(self)
|
62
|
+
@context_builder = ContextBuilder.new(self)
|
63
|
+
@error_builder = ErrorBuilder.new(self)
|
64
|
+
@stacktrace_builder = StacktraceBuilder.new(self)
|
65
|
+
end
|
66
|
+
|
67
|
+
attr_reader :config,
|
68
|
+
:messages,
|
69
|
+
:pending_transactions,
|
70
|
+
:instrumenter,
|
71
|
+
:context_builder,
|
72
|
+
:stacktrace_builder,
|
73
|
+
:trace_logger,
|
74
|
+
:error_builder
|
75
|
+
|
76
|
+
def start
|
77
|
+
# puts '@stackify_ruby [Agent] [lib/agent.rb] start()'
|
78
|
+
# puts '@stackify_ruby [Agent] [lib/agent.rb] Environment: ' + @config.environment_name
|
79
|
+
# puts '@stackify_ruby [Agent] [lib/agent.rb] Application Name: ' + @config.application_name
|
80
|
+
# @instrumenter.start
|
81
|
+
debug 'Loaded spies:'
|
82
|
+
config.enabled_spies.each do |lib|
|
83
|
+
debug lib.inspect
|
84
|
+
require "stackify/spies/#{lib}"
|
85
|
+
end
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
# queues
|
90
|
+
|
91
|
+
# Stores transaction in queue
|
92
|
+
#
|
93
|
+
def enqueue_transaction(transaction)
|
94
|
+
boot_worker unless worker_running?
|
95
|
+
pending_transactions.push(transaction)
|
96
|
+
return unless should_flush_transactions?
|
97
|
+
|
98
|
+
messages.push(Worker::FlushMsg.new)
|
99
|
+
end
|
100
|
+
|
101
|
+
def should_flush_transactions?
|
102
|
+
return true unless config.flush_interval
|
103
|
+
return true if pending_transactions.length >= config.max_queue_size
|
104
|
+
|
105
|
+
false
|
106
|
+
end
|
107
|
+
|
108
|
+
def enqueue_error(error)
|
109
|
+
boot_worker unless worker_running?
|
110
|
+
|
111
|
+
messages.push(Worker::ErrorMsg.new(error))
|
112
|
+
end
|
113
|
+
|
114
|
+
# Instrumentation
|
115
|
+
#
|
116
|
+
def current_transaction
|
117
|
+
instrumenter.current_transaction
|
118
|
+
end
|
119
|
+
|
120
|
+
# Loads transaction
|
121
|
+
#
|
122
|
+
def transaction(*args, &block)
|
123
|
+
instrumenter.transaction(*args, &block)
|
124
|
+
end
|
125
|
+
|
126
|
+
def span(*args, &block)
|
127
|
+
instrumenter.span(*args, &block)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Responsible for building the transaction's context
|
131
|
+
#
|
132
|
+
def build_context(rack_env)
|
133
|
+
@context_builder.build(rack_env)
|
134
|
+
end
|
135
|
+
|
136
|
+
# errors
|
137
|
+
|
138
|
+
def report(exception, handled: true)
|
139
|
+
return if config.filter_exception_types.include?(exception.class.to_s)
|
140
|
+
|
141
|
+
error = @error_builder.build_exception(
|
142
|
+
exception,
|
143
|
+
handled: handled
|
144
|
+
)
|
145
|
+
enqueue_error error
|
146
|
+
end
|
147
|
+
|
148
|
+
def report_message(message, backtrace: nil, **attrs)
|
149
|
+
error = @error_builder.build_log(
|
150
|
+
message,
|
151
|
+
backtrace: backtrace,
|
152
|
+
**attrs
|
153
|
+
)
|
154
|
+
enqueue_error error
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
def boot_worker
|
160
|
+
debug 'Booting worker'
|
161
|
+
|
162
|
+
@worker_thread = Thread.new do
|
163
|
+
Worker.new(
|
164
|
+
config,
|
165
|
+
messages,
|
166
|
+
pending_transactions,
|
167
|
+
trace_logger
|
168
|
+
).run_forever
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def kill_worker
|
173
|
+
messages << Worker::StopMsg.new
|
174
|
+
|
175
|
+
if @worker_thread && !@worker_thread.join(5) # 5 secs
|
176
|
+
raise 'Failed to wait for worker, not all messages sent'
|
177
|
+
end
|
178
|
+
|
179
|
+
@worker_thread = nil
|
180
|
+
end
|
181
|
+
|
182
|
+
def worker_running?
|
183
|
+
@worker_thread && @worker_thread.alive?
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# The Config class sets the APM's default values.
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'logger'
|
7
|
+
require 'yaml'
|
8
|
+
require 'socket'
|
9
|
+
module StackifyRubyAPM
|
10
|
+
# rubocop:disable Metrics/ClassLength
|
11
|
+
# @api private
|
12
|
+
class Config
|
13
|
+
DEFAULTS = {
|
14
|
+
config_file: 'config/stackify_apm.yml',
|
15
|
+
environment_name: ENV['RAILS_ENV'] || ENV['RACK_ENV'],
|
16
|
+
instrument: true,
|
17
|
+
|
18
|
+
log_path: '/usr/local/stackify/stackify-ruby-apm/log/stackify-ruby-apm.log',
|
19
|
+
log_level: Logger::DEBUG,
|
20
|
+
|
21
|
+
log_trace_path: '/usr/local/stackify/stackify-ruby-apm/log/',
|
22
|
+
|
23
|
+
max_queue_size: 500, # Maximum queue length of transactions before sending transactions to the APM.
|
24
|
+
flush_interval: 1, # interval with which transactions should be sent to the APM. Default value: 10 seconds
|
25
|
+
|
26
|
+
filter_exception_types: [],
|
27
|
+
|
28
|
+
http_status: nil,
|
29
|
+
debug_transactions: false,
|
30
|
+
|
31
|
+
source_lines_error_app_frames: 5,
|
32
|
+
source_lines_span_app_frames: 5,
|
33
|
+
source_lines_error_library_frames: 0,
|
34
|
+
source_lines_span_library_frames: 0,
|
35
|
+
span_frames_min_duration: -1, # it will collect stack traces for all spans
|
36
|
+
|
37
|
+
disabled_spies: %w[json],
|
38
|
+
|
39
|
+
view_paths: [],
|
40
|
+
root_path: Dir.pwd
|
41
|
+
}.freeze
|
42
|
+
|
43
|
+
ENV_TO_KEY = {
|
44
|
+
'STACKIFY_APM_ENVIRONMENT_NAME' => 'environment_name',
|
45
|
+
'STACKIFY_APM_INSTRUMENT' => [:bool, 'instrument'],
|
46
|
+
'STACKIFY_APM_HOSTNAME' => 'hostname',
|
47
|
+
'STACKIFY_APM_LOG_PATH' => 'log_path',
|
48
|
+
'STACKIFY_APM_LOG_LEVEL' => [:int, 'log_level'],
|
49
|
+
'STACKIFY_APM_APPLICATION_NAME' => 'application_name',
|
50
|
+
'STACKIFY_APM_SOURCE_LINES_ERROR_APP_FRAMES' => [:int, 'source_lines_error_app_frames'],
|
51
|
+
'STACKIFY_APM_SOURCE_LINES_SPAN_APP_FRAMES' => [:int, 'source_lines_span_app_frames'],
|
52
|
+
'STACKIFY_APM_SOURCE_LINES_ERROR_LIBRARY_FRAMES' => [:int, 'source_lines_error_library_frames'],
|
53
|
+
'STACKIFY_APM_SOURCE_LINES_SPAN_LIBRARY_FRAMES' => [:int, 'source_lines_span_library_frames'],
|
54
|
+
'STACKIFY_APM_SPAN_FRAMES_MIN_DURATION' => [:int, 'span_frames_min_duration'],
|
55
|
+
'STACKIFY_APM_MAX_QUEUE_SIZE' => [:int, 'max_queue_size'],
|
56
|
+
'STACKIFY_APM_FLUSH_INTERVAL' => 'flush_interval',
|
57
|
+
'STACKIFY_APM_DISABLED_SPIES' => [:list, 'disabled_spies']
|
58
|
+
}.freeze
|
59
|
+
|
60
|
+
def initialize(options = {})
|
61
|
+
set_defaults
|
62
|
+
|
63
|
+
set_from_args(options)
|
64
|
+
set_from_config_file
|
65
|
+
set_from_env
|
66
|
+
|
67
|
+
yield self if block_given?
|
68
|
+
|
69
|
+
build_logger if logger.nil? || log_path
|
70
|
+
end
|
71
|
+
|
72
|
+
attr_accessor :config_file
|
73
|
+
attr_accessor :environment_name
|
74
|
+
attr_accessor :instrument
|
75
|
+
attr_accessor :enabled_environments
|
76
|
+
|
77
|
+
attr_accessor :application_name
|
78
|
+
attr_accessor :hostname
|
79
|
+
|
80
|
+
attr_accessor :log_path
|
81
|
+
attr_accessor :log_level
|
82
|
+
attr_accessor :logger
|
83
|
+
|
84
|
+
attr_accessor :log_trace_path
|
85
|
+
attr_accessor :source_lines_error_app_frames
|
86
|
+
attr_accessor :source_lines_span_app_frames
|
87
|
+
attr_accessor :source_lines_error_library_frames
|
88
|
+
attr_accessor :source_lines_span_library_frames
|
89
|
+
attr_accessor :span_frames_min_duration
|
90
|
+
|
91
|
+
attr_accessor :max_queue_size
|
92
|
+
attr_accessor :flush_interval
|
93
|
+
|
94
|
+
attr_accessor :filter_exception_types
|
95
|
+
|
96
|
+
attr_accessor :debug_transactions
|
97
|
+
|
98
|
+
attr_accessor :disabled_spies
|
99
|
+
|
100
|
+
attr_accessor :view_paths
|
101
|
+
attr_accessor :root_path
|
102
|
+
attr_accessor :http_status
|
103
|
+
|
104
|
+
def app=(app)
|
105
|
+
case app_type?(app)
|
106
|
+
when :rails
|
107
|
+
set_rails(app)
|
108
|
+
else
|
109
|
+
# TODO: define custom?
|
110
|
+
self.application_name = 'ruby'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def app_type?(app)
|
115
|
+
if defined?(::Rails) && app.is_a?(Rails::Application)
|
116
|
+
return :rails
|
117
|
+
end
|
118
|
+
nil
|
119
|
+
end
|
120
|
+
|
121
|
+
# rubocop:disable Metrics/MethodLength
|
122
|
+
def available_spies
|
123
|
+
%w[
|
124
|
+
action_dispatch
|
125
|
+
mongo
|
126
|
+
net_http
|
127
|
+
httpclient
|
128
|
+
sinatra
|
129
|
+
tilt
|
130
|
+
]
|
131
|
+
end
|
132
|
+
# rubocop:enable Metrics/MethodLength
|
133
|
+
|
134
|
+
def enabled_spies
|
135
|
+
available_spies - disabled_spies
|
136
|
+
end
|
137
|
+
|
138
|
+
def check_lastlog_needs_new(path)
|
139
|
+
latest_file = Dir.glob("#{path}*").grep(/([#])\w+/).max_by {|f| File.mtime(f)}
|
140
|
+
new_flagger = false
|
141
|
+
|
142
|
+
if latest_file.nil?
|
143
|
+
new_flagger = true
|
144
|
+
else
|
145
|
+
current_kb_size = ((File.size(latest_file)) / 1000).to_f
|
146
|
+
|
147
|
+
#50000KB = 50MB
|
148
|
+
if current_kb_size > 50000.0
|
149
|
+
new_flagger = true
|
150
|
+
end
|
151
|
+
end
|
152
|
+
result = {
|
153
|
+
'latest_file' => latest_file,
|
154
|
+
'new_flagger' => new_flagger
|
155
|
+
}
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
def assign(options)
|
162
|
+
options.each do |key, value|
|
163
|
+
send("#{key}=", value)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def set_defaults
|
168
|
+
assign(DEFAULTS)
|
169
|
+
end
|
170
|
+
|
171
|
+
# rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
172
|
+
def set_from_env
|
173
|
+
ENV_TO_KEY.each do |env_key, key|
|
174
|
+
next unless (value = ENV[env_key])
|
175
|
+
|
176
|
+
type, key = key if key.is_a? Array
|
177
|
+
|
178
|
+
value =
|
179
|
+
case type
|
180
|
+
when :int then value.to_i
|
181
|
+
when :float then value.to_f
|
182
|
+
when :bool then !%w[0 false].include?(value.strip.downcase)
|
183
|
+
when :list then value.split(/[ ,]/)
|
184
|
+
else value
|
185
|
+
end
|
186
|
+
|
187
|
+
send("#{key}=", value)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
191
|
+
|
192
|
+
def set_from_args(options)
|
193
|
+
assign(options)
|
194
|
+
end
|
195
|
+
|
196
|
+
def set_from_config_file
|
197
|
+
return unless File.exist?(config_file)
|
198
|
+
assign(YAML.load_file(config_file) || {})
|
199
|
+
end
|
200
|
+
|
201
|
+
def set_rails(app) # rubocop:disable Metrics/AbcSize
|
202
|
+
self.application_name ||= format_name(application_name || app.class.parent_name)
|
203
|
+
self.logger ||= Rails.logger
|
204
|
+
|
205
|
+
self.root_path = Rails.root.to_s
|
206
|
+
self.view_paths = app.config.paths['app/views'].existent
|
207
|
+
end
|
208
|
+
|
209
|
+
def build_logger
|
210
|
+
logger = Logger.new(log_path == '-' ? $stdout : log_path)
|
211
|
+
logger.level = log_level
|
212
|
+
|
213
|
+
self.logger = logger
|
214
|
+
end
|
215
|
+
|
216
|
+
def format_name(str)
|
217
|
+
str.gsub('::', '_')
|
218
|
+
end
|
219
|
+
end
|
220
|
+
# rubocop:enable Metrics/ClassLength
|
221
|
+
end
|