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