appoptics_apm_mnfst 4.5.2
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/.dockerignore +5 -0
- data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +16 -0
- data/.gitignore +29 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +121 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +769 -0
- data/CONFIG.md +33 -0
- data/Gemfile +29 -0
- data/LICENSE +193 -0
- data/README.md +393 -0
- data/Rakefile +230 -0
- data/appoptics_apm.gemspec +61 -0
- data/bin/appoptics_apm_config +15 -0
- data/build_gem.sh +15 -0
- data/build_gem_upload_to_packagecloud.sh +20 -0
- data/examples/SDK/01_basic_tracing.rb +67 -0
- data/examples/carrying_context.rb +220 -0
- data/ext/oboe_metal/extconf.rb +114 -0
- data/ext/oboe_metal/lib/.keep +0 -0
- data/ext/oboe_metal/noop/noop.c +7 -0
- data/ext/oboe_metal/src/VERSION +1 -0
- data/init.rb +4 -0
- data/lib/appoptics_apm.rb +76 -0
- data/lib/appoptics_apm/api.rb +20 -0
- data/lib/appoptics_apm/api/layerinit.rb +41 -0
- data/lib/appoptics_apm/api/logging.rb +375 -0
- data/lib/appoptics_apm/api/memcache.rb +37 -0
- data/lib/appoptics_apm/api/metrics.rb +55 -0
- data/lib/appoptics_apm/api/profiling.rb +203 -0
- data/lib/appoptics_apm/api/tracing.rb +53 -0
- data/lib/appoptics_apm/api/util.rb +122 -0
- data/lib/appoptics_apm/base.rb +230 -0
- data/lib/appoptics_apm/config.rb +254 -0
- data/lib/appoptics_apm/frameworks/grape.rb +97 -0
- data/lib/appoptics_apm/frameworks/padrino.rb +108 -0
- data/lib/appoptics_apm/frameworks/rails.rb +94 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +55 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +29 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +31 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +119 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +108 -0
- data/lib/appoptics_apm/frameworks/sinatra.rb +125 -0
- data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
- data/lib/appoptics_apm/inst/bunny-consumer.rb +89 -0
- data/lib/appoptics_apm/inst/curb.rb +330 -0
- data/lib/appoptics_apm/inst/dalli.rb +85 -0
- data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
- data/lib/appoptics_apm/inst/em-http-request.rb +101 -0
- data/lib/appoptics_apm/inst/excon.rb +125 -0
- data/lib/appoptics_apm/inst/faraday.rb +94 -0
- data/lib/appoptics_apm/inst/grpc_client.rb +162 -0
- data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
- data/lib/appoptics_apm/inst/http.rb +73 -0
- data/lib/appoptics_apm/inst/httpclient.rb +174 -0
- data/lib/appoptics_apm/inst/memcached.rb +86 -0
- data/lib/appoptics_apm/inst/mongo.rb +246 -0
- data/lib/appoptics_apm/inst/mongo2.rb +225 -0
- data/lib/appoptics_apm/inst/moped.rb +466 -0
- data/lib/appoptics_apm/inst/rack.rb +199 -0
- data/lib/appoptics_apm/inst/redis.rb +275 -0
- data/lib/appoptics_apm/inst/resque.rb +151 -0
- data/lib/appoptics_apm/inst/rest-client.rb +48 -0
- data/lib/appoptics_apm/inst/sequel.rb +178 -0
- data/lib/appoptics_apm/inst/sidekiq-client.rb +55 -0
- data/lib/appoptics_apm/inst/sidekiq-worker.rb +65 -0
- data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
- data/lib/appoptics_apm/inst/typhoeus.rb +108 -0
- data/lib/appoptics_apm/instrumentation.rb +22 -0
- data/lib/appoptics_apm/legacy_method_profiling.rb +90 -0
- data/lib/appoptics_apm/loading.rb +65 -0
- data/lib/appoptics_apm/logger.rb +42 -0
- data/lib/appoptics_apm/method_profiling.rb +33 -0
- data/lib/appoptics_apm/noop/README.md +9 -0
- data/lib/appoptics_apm/noop/context.rb +26 -0
- data/lib/appoptics_apm/noop/metadata.rb +22 -0
- data/lib/appoptics_apm/ruby.rb +35 -0
- data/lib/appoptics_apm/sdk/custom_metrics.rb +92 -0
- data/lib/appoptics_apm/sdk/tracing.rb +315 -0
- data/lib/appoptics_apm/support.rb +119 -0
- data/lib/appoptics_apm/test.rb +94 -0
- data/lib/appoptics_apm/thread_local.rb +26 -0
- data/lib/appoptics_apm/util.rb +319 -0
- data/lib/appoptics_apm/version.rb +15 -0
- data/lib/appoptics_apm/xtrace.rb +103 -0
- data/lib/joboe_metal.rb +212 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe/README +2 -0
- data/lib/oboe/backward_compatibility.rb +80 -0
- data/lib/oboe/inst/rack.rb +11 -0
- data/lib/oboe_metal.rb +198 -0
- data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
- data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +265 -0
- data/yardoc_frontpage.md +26 -0
- metadata +266 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
# Constants from liboboe
|
|
5
|
+
APPOPTICS_TRACE_NEVER = 0
|
|
6
|
+
APPOPTICS_TRACE_ALWAYS = 1
|
|
7
|
+
|
|
8
|
+
# OBOE_SAMPLE_RATE_SOURCE_FILE = 1
|
|
9
|
+
# OBOE_SAMPLE_RATE_SOURCE_DEFAULT = 2
|
|
10
|
+
# OBOE_SAMPLE_RATE_SOURCE_OBOE = 3
|
|
11
|
+
# OBOE_SAMPLE_RATE_SOURCE_LAST_OBOE = 4
|
|
12
|
+
# OBOE_SAMPLE_RATE_SOURCE_DEFAULT_MISCONFIGURED = 5
|
|
13
|
+
# OBOE_SAMPLE_RATE_SOURCE_OBOE_DEFAULT = 6
|
|
14
|
+
|
|
15
|
+
# Masks for bitwise ops
|
|
16
|
+
# ZERO_MASK = 0b0000000000000000000000000000
|
|
17
|
+
|
|
18
|
+
SAMPLE_RATE_MASK = 0b0000111111111111111111111111
|
|
19
|
+
SAMPLE_SOURCE_MASK = 0b1111000000000000000000000000
|
|
20
|
+
|
|
21
|
+
# ZERO_SAMPLE_RATE_MASK = 0b1111000000000000000000000000
|
|
22
|
+
# ZERO_SAMPLE_SOURCE_MASK = 0b0000111111111111111111111111
|
|
23
|
+
|
|
24
|
+
APPOPTICS_STR_BLANK = ''.freeze
|
|
25
|
+
APPOPTICS_STR_LAYER = 'Layer'.freeze
|
|
26
|
+
APPOPTICS_STR_LABEL = 'Label'.freeze
|
|
27
|
+
|
|
28
|
+
# Used in tests to store local trace data
|
|
29
|
+
TRACE_FILE = '/tmp/appoptics_traces.bson'.freeze
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# This module is the base module for the various implementations of AppOpticsAPM reporting.
|
|
33
|
+
# Current variations as of 2014-09-10 are a c-extension, JRuby (using AppOpticsAPM Java
|
|
34
|
+
# instrumentation) and a Heroku c-extension (with embedded tracelyzer)
|
|
35
|
+
module AppOpticsAPMBase
|
|
36
|
+
extend AppOpticsAPM::ThreadLocal
|
|
37
|
+
|
|
38
|
+
attr_accessor :reporter
|
|
39
|
+
attr_accessor :loaded
|
|
40
|
+
thread_local :sample_source
|
|
41
|
+
thread_local :sample_rate
|
|
42
|
+
thread_local :layer
|
|
43
|
+
thread_local :layer_op
|
|
44
|
+
|
|
45
|
+
# transaction_name is used for custom transaction naming
|
|
46
|
+
# It needs to be globally accessible, but is only set by the request processors of the different frameworks
|
|
47
|
+
# and read by rack
|
|
48
|
+
thread_local :transaction_name
|
|
49
|
+
|
|
50
|
+
# Semaphore used during the test suite to test
|
|
51
|
+
# global config options.
|
|
52
|
+
thread_local :config_lock
|
|
53
|
+
|
|
54
|
+
# The following accessors indicate the incoming tracing state received
|
|
55
|
+
# by the rack layer. These are primarily used to identify state
|
|
56
|
+
# between the Ruby and JAppOpticsAPM instrumentation under JRuby.
|
|
57
|
+
#
|
|
58
|
+
# This is because that even though there may be an incoming
|
|
59
|
+
# X-Trace request header, tracing may have already been started
|
|
60
|
+
# by Joboe. Such a scenario occurs when the application is being
|
|
61
|
+
# hosted by a Java container (such as Tomcat or Glassfish) and
|
|
62
|
+
# AppOpticsAPM has already initiated tracing. In this case, we shouldn't
|
|
63
|
+
# pickup the X-Trace context in the X-Trace header and we shouldn't
|
|
64
|
+
# set the outgoing response X-Trace header or clear context.
|
|
65
|
+
# Yeah I know. Yuck.
|
|
66
|
+
|
|
67
|
+
# Occurs only on Jruby. Indicates that Joboe (the java instrumentation)
|
|
68
|
+
# has already started tracing before it hit the JRuby instrumentation.
|
|
69
|
+
# It is used in Rack#call if there is a context when entering rack
|
|
70
|
+
thread_local :has_incoming_context
|
|
71
|
+
|
|
72
|
+
# Indicates the existence of a valid X-Trace request header
|
|
73
|
+
thread_local :has_xtrace_header
|
|
74
|
+
|
|
75
|
+
# This indicates that this trace was continued from
|
|
76
|
+
# an incoming X-Trace request header or in the case
|
|
77
|
+
# of JRuby, a trace already started by JAppOpticsAPM.
|
|
78
|
+
thread_local :is_continued_trace
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
# extended
|
|
82
|
+
#
|
|
83
|
+
# Invoked when this module is extended.
|
|
84
|
+
# e.g. extend AppOpticsAPMBase
|
|
85
|
+
#
|
|
86
|
+
def self.extended(cls)
|
|
87
|
+
cls.loaded = true
|
|
88
|
+
|
|
89
|
+
# This gives us pretty accessors with questions marks at the end
|
|
90
|
+
# e.g. is_continued_trace --> is_continued_trace?
|
|
91
|
+
AppOpticsAPM.methods.select { |m| m =~ /^is_|^has_/ }.each do |c|
|
|
92
|
+
unless c =~ /\?$|=$/
|
|
93
|
+
# AppOpticsAPM.logger.debug "aliasing #{c}? to #{c}"
|
|
94
|
+
alias_method "#{c}?", c
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
##
|
|
100
|
+
# pickup_context
|
|
101
|
+
#
|
|
102
|
+
# for JRUBY
|
|
103
|
+
# Determines whether we should pickup context
|
|
104
|
+
# from an incoming X-Trace request header. The answer
|
|
105
|
+
# is generally yes but there are cases in JRuby under
|
|
106
|
+
# Tomcat (or Glassfish etc.) where tracing may have
|
|
107
|
+
# been already started by the Java instrumentation (Joboe)
|
|
108
|
+
# in which case we don't want to do this.
|
|
109
|
+
#
|
|
110
|
+
def pickup_context?(xtrace)
|
|
111
|
+
return false unless AppOpticsAPM::XTrace.valid?(xtrace)
|
|
112
|
+
|
|
113
|
+
if defined?(JRUBY_VERSION) && AppOpticsAPM.tracing?
|
|
114
|
+
return false
|
|
115
|
+
else
|
|
116
|
+
return true
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
##
|
|
121
|
+
# tracing_layer?
|
|
122
|
+
#
|
|
123
|
+
# Queries the thread local variable about the current
|
|
124
|
+
# layer being traced. This is used in cases of recursive
|
|
125
|
+
# operation tracing or one instrumented operation calling another.
|
|
126
|
+
#
|
|
127
|
+
def tracing_layer?(layer)
|
|
128
|
+
AppOpticsAPM.layer == layer.to_sym
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
##
|
|
132
|
+
# tracing_layer_op?
|
|
133
|
+
#
|
|
134
|
+
# Queries the thread local variable about the current
|
|
135
|
+
# operation being traced. This is used in cases of recursive
|
|
136
|
+
# operation tracing or one instrumented operation calling another.
|
|
137
|
+
#
|
|
138
|
+
# In such cases, we only want to trace the outermost operation.
|
|
139
|
+
#
|
|
140
|
+
def tracing_layer_op?(operation)
|
|
141
|
+
unless AppOpticsAPM.layer_op.nil? || AppOpticsAPM.layer_op.is_a?(Array)
|
|
142
|
+
AppOpticsAPM.logger.error('[appopticsapm/logging] INTERNAL: layer_op should be nil or an array, please report to support@appoptics.com')
|
|
143
|
+
return false
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
return false if AppOpticsAPM.layer_op.nil? || AppOpticsAPM.layer_op.empty? || !operation.respond_to?(:to_sym)
|
|
147
|
+
AppOpticsAPM.layer_op.last == operation.to_sym
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
##
|
|
151
|
+
# Returns true if the tracing_mode is set to always.
|
|
152
|
+
# False otherwise
|
|
153
|
+
#
|
|
154
|
+
def always?
|
|
155
|
+
AppOpticsAPM::Config[:tracing_mode] &&
|
|
156
|
+
AppOpticsAPM::Config[:tracing_mode].to_sym == :always
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
##
|
|
160
|
+
# Returns true if the tracing_mode is set to never.
|
|
161
|
+
# False otherwise
|
|
162
|
+
#
|
|
163
|
+
def never?
|
|
164
|
+
AppOpticsAPM::Config[:tracing_mode] &&
|
|
165
|
+
AppOpticsAPM::Config[:tracing_mode].to_sym == :never
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
##
|
|
169
|
+
# Returns true if we are currently tracing a request
|
|
170
|
+
# False otherwise
|
|
171
|
+
#
|
|
172
|
+
def tracing?
|
|
173
|
+
return false if !AppOpticsAPM.loaded || AppOpticsAPM.never?
|
|
174
|
+
AppOpticsAPM::Context.isSampled
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def heroku?
|
|
178
|
+
ENV.key?('APPOPTICS_URL')
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
##
|
|
182
|
+
# Determines if we are running under a forking webserver
|
|
183
|
+
#
|
|
184
|
+
def forking_webserver?
|
|
185
|
+
if (defined?(::Unicorn) && ($PROGRAM_NAME =~ /unicorn/i)) ||
|
|
186
|
+
(defined?(::Puma) && ($PROGRAM_NAME =~ /puma/i))
|
|
187
|
+
true
|
|
188
|
+
else
|
|
189
|
+
false
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
##
|
|
194
|
+
# Indicates whether a supported framework is in use
|
|
195
|
+
# or not
|
|
196
|
+
#
|
|
197
|
+
def framework?
|
|
198
|
+
defined?(::Rails) || defined?(::Sinatra) || defined?(::Padrino) || defined?(::Grape)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
##
|
|
202
|
+
# These methods should be implemented by the descendants
|
|
203
|
+
# (Oboe_metal, JOboe_metal (JRuby), Heroku_metal)
|
|
204
|
+
#
|
|
205
|
+
def sample?(_opts = {})
|
|
206
|
+
fail 'sample? should be implemented by metal layer.'
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def log(_layer, _label, _options = {})
|
|
210
|
+
fail 'log should be implemented by metal layer.'
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def set_tracing_mode(_mode)
|
|
214
|
+
fail 'set_tracing_mode should be implemented by metal layer.'
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def set_sample_rate(_rate)
|
|
218
|
+
fail 'set_sample_rate should be implemented by metal layer.'
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
module AppOpticsAPM
|
|
223
|
+
extend AppOpticsAPMBase
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Setup an alias so we don't bug users
|
|
227
|
+
# about single letter capitalization
|
|
228
|
+
AppopticsAPM = AppOpticsAPM
|
|
229
|
+
AppOpticsApm = AppOpticsAPM
|
|
230
|
+
AppopticsApm = AppOpticsAPM
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
##
|
|
6
|
+
# This module exposes a nested configuration hash that can be used to
|
|
7
|
+
# configure and/or modify the functionality of the appoptics_apm gem.
|
|
8
|
+
#
|
|
9
|
+
# Use AppOpticsAPM::Config.show to view the entire nested hash.
|
|
10
|
+
#
|
|
11
|
+
module Config
|
|
12
|
+
@@config = {}
|
|
13
|
+
|
|
14
|
+
@@instrumentation = [:action_controller, :action_controller_api, :action_view,
|
|
15
|
+
:active_record, :bunnyclient, :bunnyconsumer, :cassandra, :curb,
|
|
16
|
+
:dalli, :delayed_jobclient, :delayed_jobworker,
|
|
17
|
+
:em_http_request, :excon, :faraday, :grpc_client, :grpc_server, :grape,
|
|
18
|
+
:httpclient, :nethttp, :memcached, :mongo, :moped, :padrino, :rack, :redis,
|
|
19
|
+
:resqueclient, :resqueworker, :rest_client,
|
|
20
|
+
:sequel, :sidekiqclient, :sidekiqworker, :sinatra, :typhoeus]
|
|
21
|
+
|
|
22
|
+
# Subgrouping of instrumentation
|
|
23
|
+
@@http_clients = [:curb, :excon, :em_http_request, :faraday, :httpclient, :nethttp, :rest_client, :typhoeus]
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# load_config_file
|
|
27
|
+
#
|
|
28
|
+
# There are 3 possible locations for the config file:
|
|
29
|
+
# Rails default, ENV['APPOPTICS_APM_CONFIG_RUBY'], or the gem's default
|
|
30
|
+
#
|
|
31
|
+
# Hierarchie:
|
|
32
|
+
# 1 - Rails default: config/initializers/appoptics_apm.rb
|
|
33
|
+
# (also loaded by Rails, but we can't reliably determine if Rails is running)
|
|
34
|
+
# 2 - ENV['APPOPTICS_APM_CONFIG_RUBY']
|
|
35
|
+
# 3 - Gem default: <startup_dir>/appoptics_apm_config.rb
|
|
36
|
+
#
|
|
37
|
+
def self.load_config_file
|
|
38
|
+
config_files = []
|
|
39
|
+
|
|
40
|
+
# Check for the rails config file
|
|
41
|
+
config_file = File.join(Dir.pwd, 'config/initializers/appoptics_apm.rb')
|
|
42
|
+
config_files << config_file if File.exist?(config_file)
|
|
43
|
+
|
|
44
|
+
# Check for file set by env variable
|
|
45
|
+
if ENV.key?('APPOPTICS_APM_CONFIG_RUBY')
|
|
46
|
+
if File.exist?(ENV['APPOPTICS_APM_CONFIG_RUBY']) && !File.directory?(ENV['APPOPTICS_APM_CONFIG_RUBY'])
|
|
47
|
+
config_files << ENV['APPOPTICS_APM_CONFIG_RUBY']
|
|
48
|
+
elsif File.exist?(File.join(ENV['APPOPTICS_APM_CONFIG_RUBY'], 'appoptics_apm_config.rb'))
|
|
49
|
+
config_files << File.join(ENV['APPOPTICS_APM_CONFIG_RUBY'], 'appoptics_apm_config.rb')
|
|
50
|
+
else
|
|
51
|
+
$stderr.puts 'Could not find the configuration file set by the APPOPTICS_APM_CONFIG_RUBY environment variable:'
|
|
52
|
+
$stderr.puts "#{ENV['APPOPTICS_APM_CONFIG_RUBY']}"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Check for default config file
|
|
57
|
+
config_file = File.join(Dir.pwd, 'appoptics_apm_config.rb')
|
|
58
|
+
config_files << config_file if File.exist?(config_file)
|
|
59
|
+
|
|
60
|
+
return if config_files.empty? # we use the defaults from the template in this case
|
|
61
|
+
|
|
62
|
+
if config_files.size > 1
|
|
63
|
+
$stderr.puts 'Found multiple configuration files, using the first one listed:'
|
|
64
|
+
config_files.each { |path| $stderr.puts " #{path}" }
|
|
65
|
+
end
|
|
66
|
+
load(config_files[0])
|
|
67
|
+
check_env_vars
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# There are 4 variables that can be set in the config file or as env vars.
|
|
71
|
+
# Oboe will override vars passed in if it finds an environment variable
|
|
72
|
+
# :debug_level and :verbose need special consideration, because they are used in Ruby
|
|
73
|
+
def self.check_env_vars
|
|
74
|
+
unless (-1..6).include?(AppOpticsAPM::Config[:debug_level])
|
|
75
|
+
AppOpticsAPM::Config[:debug_level] = 3
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# let's find and use the equivalent debug level for ruby
|
|
79
|
+
debug_level = ENV['APPOPTICS_DEBUG_LEVEL'] ? ENV['APPOPTICS_DEBUG_LEVEL'].to_i : AppOpticsAPM::Config[:debug_level]
|
|
80
|
+
if debug_level < 0
|
|
81
|
+
# there should be no logging if APPOPTICS_DEBUG_LEVEL == -1
|
|
82
|
+
# In Ruby level 5 is UNKNOWN and it can log, but level 6 is quiet
|
|
83
|
+
AppOpticsAPM.logger.level = 6
|
|
84
|
+
else
|
|
85
|
+
AppOpticsAPM.logger.level = [4 - debug_level, 0].max
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# the verbose setting is only relevant for ruby, ENV['APPOPTICS_GEM_VERBOSE'] overrides
|
|
89
|
+
if ENV.key?('APPOPTICS_GEM_VERBOSE')
|
|
90
|
+
AppOpticsAPM::Config[:verbose] = ENV['APPOPTICS_GEM_VERBOSE'].downcase == 'true'
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
##
|
|
95
|
+
# print_config
|
|
96
|
+
#
|
|
97
|
+
# print configurations one per line
|
|
98
|
+
# to create an output similar to the content of the config file
|
|
99
|
+
#
|
|
100
|
+
def self.print_config
|
|
101
|
+
AppOpticsAPM.logger.warn "# General configurations"
|
|
102
|
+
non_instrumentation = @@config.keys - @@instrumentation
|
|
103
|
+
non_instrumentation.each do |config|
|
|
104
|
+
AppOpticsAPM.logger.warn "AppOpticsAPM::Config[:#{config}] = #{@@config[config]}"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
AppOpticsAPM.logger.warn "\n# Instrumentation specific configurations"
|
|
108
|
+
AppOpticsAPM.logger.warn "# Enabled/Disabled Instrumentation"
|
|
109
|
+
@@instrumentation.each do |config|
|
|
110
|
+
AppOpticsAPM.logger.warn "AppOpticsAPM::Config[:#{config}][:enabled] = #{@@config[config][:enabled]}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
AppOpticsAPM.logger.warn "\n# Enabled/Disabled Backtrace Collection"
|
|
114
|
+
@@instrumentation.each do |config|
|
|
115
|
+
AppOpticsAPM.logger.warn "AppOpticsAPM::Config[:#{config}][:collect_backtraces] = #{@@config[config][:collect_backtraces]}"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
AppOpticsAPM.logger.warn "\n# Logging of outgoing HTTP query args"
|
|
119
|
+
@@instrumentation.each do |config|
|
|
120
|
+
AppOpticsAPM.logger.warn "AppOpticsAPM::Config[:#{config}][:log_args] = #{@@config[config][:log_args] || false}"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
AppOpticsAPM.logger.warn "\n# Bunny Controller and Action"
|
|
124
|
+
AppOpticsAPM.logger.warn "AppOpticsAPM::Config[:bunnyconsumer][:controller] = #{@@config[:bunnyconsumer][:controller].inspect}"
|
|
125
|
+
AppOpticsAPM.logger.warn "AppOpticsAPM::Config[:bunnyconsumer][:action] = #{@@config[:bunnyconsumer][:action].inspect}"
|
|
126
|
+
nil
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
##
|
|
130
|
+
# initialize
|
|
131
|
+
#
|
|
132
|
+
# Initializer method to set everything up with a default configuration.
|
|
133
|
+
# The defaults are read from the template configuration file.
|
|
134
|
+
#
|
|
135
|
+
# rubocop:disable Metrics/AbcSize
|
|
136
|
+
def self.initialize(_data = {})
|
|
137
|
+
@@instrumentation.each { |k| @@config[k] = {} }
|
|
138
|
+
@@config[:transaction_name] = {}
|
|
139
|
+
|
|
140
|
+
# Always load the template, it has all the keys and defaults defined,
|
|
141
|
+
# no guarantee of completeness in the user's config file
|
|
142
|
+
load(File.join(File.dirname(File.dirname(__FILE__)),
|
|
143
|
+
'rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb'))
|
|
144
|
+
|
|
145
|
+
# to make sure we include the service_key if it is set as an ENV var
|
|
146
|
+
check_env_vars
|
|
147
|
+
end
|
|
148
|
+
# rubocop:enable Metrics/AbcSize
|
|
149
|
+
|
|
150
|
+
def self.update!(data)
|
|
151
|
+
data.each do |key, value|
|
|
152
|
+
self[key] = value
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def self.merge!(data)
|
|
157
|
+
update!(data)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def self.[](key)
|
|
161
|
+
if key == :resque
|
|
162
|
+
AppOpticsAPM.logger.warn '[appoptics_apm/warn] :resque config is deprecated. It is now split into :resqueclient and :resqueworker.'
|
|
163
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/warn] Called from #{Kernel.caller[0]}"
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
@@config[key.to_sym]
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
##
|
|
170
|
+
# []=
|
|
171
|
+
#
|
|
172
|
+
# Config variable assignment method. Here we validate and store the
|
|
173
|
+
# assigned value(s) and trigger any secondary action needed.
|
|
174
|
+
#
|
|
175
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
176
|
+
def self.[]=(key, value)
|
|
177
|
+
@@config[key.to_sym] = value
|
|
178
|
+
|
|
179
|
+
if key == :sampling_rate
|
|
180
|
+
AppOpticsAPM.logger.warn '[appoptics_apm/config] sampling_rate is not a supported setting for AppOpticsAPM::Config. ' \
|
|
181
|
+
'Please use :sample_rate.'
|
|
182
|
+
|
|
183
|
+
elsif key == :sample_rate
|
|
184
|
+
unless value.is_a?(Integer) || value.is_a?(Float)
|
|
185
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/config] :sample_rate must be a number between 0 and 1000000 (1m) " \
|
|
186
|
+
"(provided: #{value}), corrected to 0"
|
|
187
|
+
value = 0
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Validate :sample_rate value
|
|
191
|
+
unless value.between?(0, 1e6)
|
|
192
|
+
value_1 = value
|
|
193
|
+
value = value_1 < 0 ? 0 : 1_000_000
|
|
194
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/config] :sample_rate must be between 0 and 1000000 (1m) " \
|
|
195
|
+
"(provided: #{value_1}), corrected to #{value}"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Assure value is an integer
|
|
199
|
+
@@config[key.to_sym] = value.to_i
|
|
200
|
+
AppOpticsAPM.set_sample_rate(value) if AppOpticsAPM.loaded
|
|
201
|
+
|
|
202
|
+
elsif key == :action_blacklist
|
|
203
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/config] :action_blacklist has been deprecated and no longer functions."
|
|
204
|
+
|
|
205
|
+
elsif key == :resque
|
|
206
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/config] :resque config is deprecated. It is now split into :resqueclient and :resqueworker."
|
|
207
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/config] Called from #{Kernel.caller[0]}"
|
|
208
|
+
|
|
209
|
+
elsif key == :include_url_query_params # DEPRECATED
|
|
210
|
+
# Obey the global flag and update all of the per instrumentation
|
|
211
|
+
# <tt>:log_args</tt> values.
|
|
212
|
+
@@config[:rack][:log_args] = value
|
|
213
|
+
|
|
214
|
+
elsif key == :include_remote_url_params # DEPRECATED
|
|
215
|
+
# Obey the global flag and update all of the per instrumentation
|
|
216
|
+
# <tt>:log_args</tt> values.
|
|
217
|
+
@@http_clients.each do |i|
|
|
218
|
+
@@config[i][:log_args] = value
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# Update liboboe if updating :tracing_mode
|
|
222
|
+
elsif key == :tracing_mode
|
|
223
|
+
AppOpticsAPM.set_tracing_mode(value.to_sym) if AppOpticsAPM.loaded
|
|
224
|
+
|
|
225
|
+
# Make sure that the mode is stored as a symbol
|
|
226
|
+
@@config[key.to_sym] = value.to_sym
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
230
|
+
|
|
231
|
+
def self.method_missing(sym, *args)
|
|
232
|
+
class_var_name = "@@#{sym}"
|
|
233
|
+
|
|
234
|
+
if sym.to_s =~ /(.+)=$/
|
|
235
|
+
self[$1] = args.first
|
|
236
|
+
else
|
|
237
|
+
# Try part of the @@config hash first
|
|
238
|
+
if @@config.key?(sym)
|
|
239
|
+
self[sym]
|
|
240
|
+
|
|
241
|
+
# Then try as a class variable
|
|
242
|
+
elsif self.class_variable_defined?(class_var_name.to_sym)
|
|
243
|
+
self.class_eval(class_var_name)
|
|
244
|
+
|
|
245
|
+
# Congrats - You've won a brand new nil...
|
|
246
|
+
else
|
|
247
|
+
nil
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
AppOpticsAPM::Config.initialize
|