appoptics_apm 4.8.4 → 4.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +5 -1
- data/.travis.yml +5 -5
- data/CONFIG.md +1 -1
- data/Rakefile +56 -54
- data/appoptics_apm.gemspec +1 -1
- data/ext/oboe_metal/src/VERSION +1 -1
- data/lib/appoptics_apm.rb +1 -0
- data/lib/appoptics_apm/config.rb +11 -4
- data/lib/appoptics_apm/inst/rack.rb +11 -11
- data/lib/appoptics_apm/oboe_init_options.rb +13 -3
- data/lib/appoptics_apm/support/transaction_settings.rb +40 -15
- data/lib/appoptics_apm/support/x_trace_options.rb +110 -0
- data/lib/appoptics_apm/version.rb +2 -2
- data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +37 -12
- data/scrap_gemfile +5 -0
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c4b87b6581745b8485f7ddb38f17cb6eab85244a950e7d67cecfe0e97cdbd0bc
|
4
|
+
data.tar.gz: dce765afa7ceb92b523c448cd9b1b10efc1b6c5bb0f2f92842dc6af3c1934b27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9b446519730872b09136e9b80e546a68dce40abf52fbb0e5ac139244c6ed3c7fa8ef45eb855714d8e11924886d0b972aa04332cec6342339c65772f5b7aec0f
|
7
|
+
data.tar.gz: 80df368e2ed2c868348ba5e7e9b24dfa2498d6f0cb703d568fbf8310879d06fee5ac59187a70747f04c040d4d54df2b8925faa856dc5a01b036375f21edacfbe
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -98,9 +98,9 @@ matrix:
|
|
98
98
|
# - sudo service cassandra start
|
99
99
|
|
100
100
|
install:
|
101
|
-
- curl -LO http://kent.dl.sourceforge.net/project/swig/swig/swig-3.0.
|
102
|
-
- tar xzf swig-3.0.
|
103
|
-
- pushd swig-3.0.
|
101
|
+
- curl -LO http://kent.dl.sourceforge.net/project/swig/swig/swig-3.0.12/swig-3.0.12.tar.gz
|
102
|
+
- tar xzf swig-3.0.12.tar.gz
|
103
|
+
- pushd swig-3.0.12
|
104
104
|
- ./configure && make && sudo make install
|
105
105
|
- popd
|
106
106
|
|
@@ -111,8 +111,8 @@ before_script:
|
|
111
111
|
- export APPOPTICS_REPORTER_FILE_SINGLE=false
|
112
112
|
- export APPOPTICS_TOKEN_BUCKET_CAPACITY=1000
|
113
113
|
- export APPOPTICS_TOKEN_BUCKET_RATE=1000
|
114
|
-
|
115
|
-
- bundle --jobs=3 --retry=3
|
114
|
+
|
115
|
+
- bundle update --jobs=3 --retry=3
|
116
116
|
- bundle exec rake clean fetch compile
|
117
117
|
- psql -c 'create database travis_ci_test;' -U postgres
|
118
118
|
- mysql -e 'create database travis_ci_test;'
|
data/CONFIG.md
CHANGED
@@ -17,7 +17,7 @@ Name | Description | Default
|
|
17
17
|
|
18
18
|
Name | Description | Default
|
19
19
|
---- | ----------- | -------
|
20
|
-
`APPOPTICS_GEM_TEST` | puts the gem in test mode
|
20
|
+
`APPOPTICS_GEM_TEST` | puts the gem in test mode to avoid restarting certain background services used in testing. `false`
|
21
21
|
`DBTYPE` | For tests on Ruby on Rails, specifies the database type to test against. `postgres`, `mysql` and `mysql2` are valid options. | `postgres`
|
22
22
|
`APPOPTICS_CASSANDRA_SERVER` | specifies the Cassandra server to test against. | `127.0.0.1:9160`
|
23
23
|
`APPOPTICS_MONGO_SERVER` | specifies the Mongo server to test against. | `127.0.0.1:27017`
|
data/Rakefile
CHANGED
@@ -59,76 +59,77 @@ Rake::TestTask.new do |t|
|
|
59
59
|
end
|
60
60
|
|
61
61
|
if defined?(JRUBY_VERSION)
|
62
|
-
|
62
|
+
t.ruby_opts << ['-J-javaagent:/usr/local/tracelytics/tracelyticsagent.jar']
|
63
|
+
end
|
63
64
|
end
|
64
|
-
end
|
65
|
-
|
66
|
-
desc "Run all test suites defined by travis"
|
67
|
-
task "docker_tests" do
|
68
|
-
Dir.chdir('test/run_tests')
|
69
|
-
exec('docker-compose run --rm ruby_appoptics /code/ruby-appoptics/test/run_tests/ruby_setup.sh test --remove-orphans')
|
70
|
-
end
|
71
65
|
|
72
|
-
desc "Start docker container for testing and debugging"
|
73
|
-
task "docker" do
|
74
|
-
Dir.chdir('test/run_tests')
|
75
|
-
exec('docker-compose run --rm ruby_appoptics /code/ruby-appoptics/test/run_tests/ruby_setup.sh bash --remove-orphans')
|
76
|
-
end
|
77
66
|
|
78
|
-
desc "
|
79
|
-
task "
|
80
|
-
|
81
|
-
|
82
|
-
end
|
67
|
+
desc "Run all test suites defined by travis"
|
68
|
+
task "docker_tests" do
|
69
|
+
Dir.chdir('test/run_tests')
|
70
|
+
exec('docker-compose run ruby_appoptics /code/ruby-appoptics/test/run_tests/ruby_setup.sh test --remove-orphans')
|
71
|
+
end
|
83
72
|
|
84
|
-
desc "
|
85
|
-
task
|
86
|
-
|
87
|
-
|
88
|
-
if swig_version.empty?
|
89
|
-
$stderr.puts '== ERROR ================================================================='
|
90
|
-
$stderr.puts "Could not find required swig version >= 3.0.8, found #{swig_version.inspect}"
|
91
|
-
$stderr.puts 'Please install swig ">= 3.0.8" and try again.'
|
92
|
-
$stderr.puts '=========================================================================='
|
93
|
-
raise
|
73
|
+
desc "Start docker container for testing and debugging"
|
74
|
+
task "docker" do
|
75
|
+
Dir.chdir('test/run_tests')
|
76
|
+
exec('docker-compose run ruby_appoptics /code/ruby-appoptics/test/run_tests/ruby_setup.sh bash --remove-orphans')
|
94
77
|
end
|
95
78
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
# VERSION is used by extconf.rb to download the correct liboboe when installing the gem
|
102
|
-
remote_file = File.join(oboe_s3_dir, 'VERSION')
|
103
|
-
local_file = File.join(ext_src_dir, 'VERSION')
|
104
|
-
puts "fetching #{remote_file} to #{local_file}"
|
105
|
-
open(remote_file, 'rb') do |rf|
|
106
|
-
content = rf.read
|
107
|
-
File.open(local_file, 'wb') { |f| f.puts content }
|
108
|
-
puts "!!!!!!! C-Lib VERSION: #{content.strip} !!!!!!!!"
|
79
|
+
desc "Stop all containers that were started for testing and debugging"
|
80
|
+
task "docker_down" do
|
81
|
+
Dir.chdir('test/run_tests')
|
82
|
+
exec('docker-compose down')
|
109
83
|
end
|
110
84
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
85
|
+
desc "Fetch extension dependency files"
|
86
|
+
task :fetch_ext_deps do
|
87
|
+
swig_version = %x{swig -version} rescue ''
|
88
|
+
swig_version = swig_version.scan(/swig version [34].0.\d*/i)
|
89
|
+
if swig_version.empty?
|
90
|
+
$stderr.puts '== ERROR ================================================================='
|
91
|
+
$stderr.puts "Could not find required swig version >3.0.8, found #{swig_version.inspect}"
|
92
|
+
$stderr.puts 'Please install swig "~ 3.0.12" and try again.'
|
93
|
+
$stderr.puts '=========================================================================='
|
94
|
+
raise
|
95
|
+
end
|
117
96
|
|
97
|
+
# The c-lib version is different from the gem version
|
98
|
+
oboe_version = ENV['OBOE_VERSION'] || 'latest'
|
99
|
+
oboe_s3_dir = "https://s3-us-west-2.amazonaws.com/rc-files-t2/c-lib/#{oboe_version}"
|
100
|
+
ext_src_dir = File.expand_path('ext/oboe_metal/src')
|
101
|
+
|
102
|
+
# VERSION is used by extconf.rb to download the correct liboboe when installing the gem
|
103
|
+
remote_file = File.join(oboe_s3_dir, 'VERSION')
|
104
|
+
local_file = File.join(ext_src_dir, 'VERSION')
|
118
105
|
puts "fetching #{remote_file} to #{local_file}"
|
119
106
|
open(remote_file, 'rb') do |rf|
|
120
107
|
content = rf.read
|
121
108
|
File.open(local_file, 'wb') { |f| f.puts content }
|
109
|
+
puts "!!!!!!! C-Lib VERSION: #{content.strip} !!!!!!!!"
|
122
110
|
end
|
123
|
-
end
|
124
111
|
|
125
|
-
|
126
|
-
|
127
|
-
|
112
|
+
# oboe and bson header files
|
113
|
+
FileUtils.mkdir_p(File.join(ext_src_dir, 'bson'))
|
114
|
+
%w(oboe.h oboe.hpp oboe_debug.h oboe.i bson/bson.h bson/platform_hacks.h).each do |filename|
|
115
|
+
# %w(oboe.h oboe_debug.h bson/bson.h bson/platform_hacks.h).each do |filename|
|
116
|
+
remote_file = File.join(oboe_s3_dir, 'include', filename)
|
117
|
+
local_file = File.join(ext_src_dir, filename)
|
118
|
+
|
119
|
+
puts "fetching #{remote_file} to #{local_file}"
|
120
|
+
open(remote_file, 'rb') do |rf|
|
121
|
+
content = rf.read
|
122
|
+
File.open(local_file, 'wb') { |f| f.puts content }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
FileUtils.cd(ext_src_dir) do
|
127
|
+
system('swig -c++ -ruby -module oboe_metal oboe.i')
|
128
|
+
FileUtils.rm('oboe.i')
|
129
|
+
end
|
128
130
|
end
|
129
|
-
end
|
130
131
|
|
131
|
-
task :fetch => :fetch_ext_deps
|
132
|
+
task :fetch => :fetch_ext_deps
|
132
133
|
|
133
134
|
desc "Build the gem's c extension"
|
134
135
|
task :compile do
|
@@ -141,7 +142,7 @@ task :compile do
|
|
141
142
|
so_file = File.expand_path('ext/oboe_metal/oboe_metal.so')
|
142
143
|
|
143
144
|
Dir.chdir ext_dir
|
144
|
-
ENV['APPOPTICS_FROM_S3'] = 'true'
|
145
|
+
# ENV['APPOPTICS_FROM_S3'] = 'true'
|
145
146
|
cmd = [Gem.ruby, 'extconf.rb']
|
146
147
|
sh cmd.join(' ')
|
147
148
|
sh '/usr/bin/env make'
|
@@ -179,6 +180,7 @@ task :clean do
|
|
179
180
|
Dir.chdir ext_dir
|
180
181
|
sh '/usr/bin/env make clean' if File.exist? 'Makefile'
|
181
182
|
|
183
|
+
FileUtils.rm_f "src/oboe_wrap.cxx"
|
182
184
|
Dir.chdir pwd
|
183
185
|
else
|
184
186
|
puts '== Nothing to do under JRuby.'
|
data/appoptics_apm.gemspec
CHANGED
@@ -54,6 +54,6 @@ Automatic tracing and metrics for Ruby applications. Get started at appoptics.co
|
|
54
54
|
s.add_development_dependency('benchmark-ips', '>= 2.7.2')
|
55
55
|
end
|
56
56
|
|
57
|
-
s.required_ruby_version = '>= 2.
|
57
|
+
s.required_ruby_version = '>= 2.4.0'
|
58
58
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
59
59
|
end
|
data/ext/oboe_metal/src/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
6.0.0
|
data/lib/appoptics_apm.rb
CHANGED
data/lib/appoptics_apm/config.rb
CHANGED
@@ -16,13 +16,16 @@ module AppOpticsAPM
|
|
16
16
|
@@instrumentation = [:action_controller, :action_controller_api, :action_view,
|
17
17
|
:active_record, :bunnyclient, :bunnyconsumer, :cassandra, :curb,
|
18
18
|
:dalli, :delayed_jobclient, :delayed_jobworker,
|
19
|
-
:em_http_request,
|
19
|
+
# :em_http_request,
|
20
|
+
:excon, :faraday, :grpc_client, :grpc_server, :grape,
|
20
21
|
:httpclient, :nethttp, :memcached, :mongo, :moped, :padrino, :rack, :redis,
|
21
22
|
:resqueclient, :resqueworker, :rest_client,
|
22
23
|
:sequel, :sidekiqclient, :sidekiqworker, :sinatra, :typhoeus]
|
23
24
|
|
24
25
|
# Subgrouping of instrumentation
|
25
|
-
@@http_clients = [:curb, :excon,
|
26
|
+
@@http_clients = [:curb, :excon,
|
27
|
+
# :em_http_request,
|
28
|
+
:faraday, :httpclient, :nethttp, :rest_client, :typhoeus]
|
26
29
|
|
27
30
|
##
|
28
31
|
# load_config_file
|
@@ -240,11 +243,15 @@ module AppOpticsAPM
|
|
240
243
|
end
|
241
244
|
|
242
245
|
elsif key == :tracing_mode
|
243
|
-
# CAN'T DO
|
246
|
+
# CAN'T DO `set_tracing_mode` ANYMORE, ALL TRACING COMMUNICATION TO OBOE
|
244
247
|
# IS NOW HANDLED BY TransactionSettings
|
245
248
|
# AppOpticsAPM.set_tracing_mode(value.to_sym) if AppOpticsAPM.loaded
|
246
249
|
|
247
|
-
|
250
|
+
# Make sure that the mode is stored as a symbol
|
251
|
+
@@config[key.to_sym] = value.to_sym
|
252
|
+
|
253
|
+
elsif key == :trigger_tracing_mode
|
254
|
+
# Make sure that the mode is stored as a symbol
|
248
255
|
@@config[key.to_sym] = value.to_sym
|
249
256
|
end
|
250
257
|
end
|
@@ -27,30 +27,30 @@ if AppOpticsAPM.loaded
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def call(env)
|
30
|
-
incoming = AppOpticsAPM::Context.isValid
|
31
30
|
|
32
31
|
# In the case of nested Ruby apps such as Grape inside of Rails
|
33
32
|
# or Grape inside of Grape, each app has it's own instance
|
34
33
|
# of rack middleware. We want to avoid tracing rack more than once
|
35
34
|
return @app.call(env) if AppOpticsAPM.tracing? && AppOpticsAPM.layer == :rack
|
36
35
|
|
36
|
+
incoming = AppOpticsAPM::Context.isValid
|
37
37
|
AppOpticsAPM.transaction_name = nil
|
38
38
|
|
39
39
|
url = env['PATH_INFO']
|
40
|
+
options = AppOpticsAPM::XTraceOptions.new(env['HTTP_X_TRACE_OPTIONS'], env['HTTP_X_TRACE_OPTIONS_SIGNATURE'])
|
40
41
|
xtrace = AppOpticsAPM::XTrace.valid?(env['HTTP_X_TRACE']) ? (env['HTTP_X_TRACE']) : nil
|
41
|
-
|
42
|
-
settings = AppOpticsAPM::TransactionSettings.new(url, xtrace)
|
43
|
-
|
44
|
-
# AppOpticsAPM.logger.warn "%%% FILTER: #{settings} %%%"
|
42
|
+
settings = AppOpticsAPM::TransactionSettings.new(url, xtrace, options)
|
45
43
|
|
46
44
|
response =
|
47
45
|
propagate_xtrace(env, settings, xtrace) do
|
48
|
-
sample(env, settings) do
|
46
|
+
sample(env, settings, options) do
|
49
47
|
AppOpticsAPM::TransactionMetrics.metrics(env, settings) do
|
50
48
|
@app.call(env)
|
51
49
|
end
|
52
50
|
end
|
53
51
|
end || [500, {}, nil]
|
52
|
+
options.add_response_header(response[1], settings)
|
53
|
+
|
54
54
|
AppOpticsAPM::Context.clear unless incoming
|
55
55
|
response
|
56
56
|
rescue
|
@@ -66,7 +66,7 @@ if AppOpticsAPM.loaded
|
|
66
66
|
|
67
67
|
private
|
68
68
|
|
69
|
-
def collect(env
|
69
|
+
def collect(env)
|
70
70
|
req = ::Rack::Request.new(env)
|
71
71
|
report_kvs = {}
|
72
72
|
|
@@ -84,8 +84,6 @@ if AppOpticsAPM.loaded
|
|
84
84
|
|
85
85
|
report_kvs[:URL] = AppOpticsAPM::Config[:rack][:log_args] ? ::CGI.unescape(req.fullpath) : ::CGI.unescape(req.path)
|
86
86
|
report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:rack][:collect_backtraces]
|
87
|
-
report_kvs[:SampleRate] = settings.rate
|
88
|
-
report_kvs[:SampleSource] = settings.source
|
89
87
|
|
90
88
|
# Report any request queue'ing headers. Report as 'Request-Start' or the summed Queue-Time
|
91
89
|
report_kvs[:'Request-Start'] = env['HTTP_X_REQUEST_START'] if env.key?('HTTP_X_REQUEST_START')
|
@@ -126,11 +124,13 @@ if AppOpticsAPM.loaded
|
|
126
124
|
[status, headers, response]
|
127
125
|
end
|
128
126
|
|
129
|
-
def sample(env, settings)
|
127
|
+
def sample(env, settings, options)
|
130
128
|
xtrace = env['HTTP_X_TRACE']
|
131
129
|
if settings.do_sample
|
132
130
|
begin
|
133
|
-
report_kvs = collect(env
|
131
|
+
report_kvs = collect(env)
|
132
|
+
settings.add_kvs(report_kvs)
|
133
|
+
options&.add_kvs(report_kvs, settings)
|
134
134
|
|
135
135
|
AppOpticsAPM::API.log_start(:rack, xtrace, report_kvs, settings)
|
136
136
|
|
@@ -8,7 +8,7 @@ module AppOpticsAPM
|
|
8
8
|
class OboeInitOptions
|
9
9
|
include Singleton
|
10
10
|
|
11
|
-
attr_reader :reporter, :host, :service_name # exposing these mainly for testing
|
11
|
+
attr_reader :reporter, :host, :service_name, :ec2_md_timeout # exposing these mainly for testing
|
12
12
|
|
13
13
|
# TODO decide if these globals are useful when testing
|
14
14
|
# OBOE_HOSTNAME_ALIAS = 0
|
@@ -69,6 +69,8 @@ module AppOpticsAPM
|
|
69
69
|
@token_bucket_rate = (ENV['APPOPTICS_TOKEN_BUCKET_RATE'] || -1).to_i
|
70
70
|
# use single files in file reporter for each event
|
71
71
|
@file_single = (ENV['APPOPTICS_REPORTER_FILE_SINGLE'].to_s.downcase == 'true') ? 1 : 0
|
72
|
+
# timeout for ec2 metadata
|
73
|
+
@ec2_md_timeout = read_and_validate_ec2_md_timeout
|
72
74
|
end
|
73
75
|
|
74
76
|
def re_init # for testing with changed ENV vars
|
@@ -94,7 +96,8 @@ module AppOpticsAPM
|
|
94
96
|
@histogram_precision,
|
95
97
|
@token_bucket_capacity,
|
96
98
|
@token_bucket_rate,
|
97
|
-
@file_single
|
99
|
+
@file_single,
|
100
|
+
@ec2_md_timeout
|
98
101
|
]
|
99
102
|
end
|
100
103
|
|
@@ -150,7 +153,7 @@ module AppOpticsAPM
|
|
150
153
|
end
|
151
154
|
|
152
155
|
def validate_token(token)
|
153
|
-
if (token !~ /^[0-9a-fA-F]{64}|[0-9a-zA-Z_
|
156
|
+
if (token !~ /^[0-9a-fA-F]{64}|[0-9a-zA-Z_-]{71}$/) && ENV['APPOPTICS_COLLECTOR'] != "sslcollector:12222"
|
154
157
|
masked = "#{token[0..3]}...#{token[-4..-1]}"
|
155
158
|
AppOpticsAPM.logger.error "[appoptics_apm/oboe_options] APPOPTICS_SERVICE_KEY problem. API Token in wrong format. Masked token: #{masked}"
|
156
159
|
return false
|
@@ -178,6 +181,13 @@ module AppOpticsAPM
|
|
178
181
|
@service_name = service_name # instance variable used in testing
|
179
182
|
true
|
180
183
|
end
|
184
|
+
|
185
|
+
def read_and_validate_ec2_md_timeout
|
186
|
+
timeout = (ENV['APPOPTICS_EC2_METADATA_TIMEOUT'] || AppOpticsAPM::Config[:ec2_metadata_timeout])
|
187
|
+
return 1000 unless timeout.is_a?(Integer) || timeout =~ /^\d+$/
|
188
|
+
timeout = timeout.to_i
|
189
|
+
return timeout.between?(0, 3000) ? timeout : 1000
|
190
|
+
end
|
181
191
|
end
|
182
192
|
end
|
183
193
|
|
@@ -6,14 +6,9 @@ AO_TRACING_ENABLED = 1
|
|
6
6
|
AO_TRACING_DISABLED = 0
|
7
7
|
AO_TRACING_UNSET = -1
|
8
8
|
|
9
|
-
AO_TRACING_DECISIONS_TRACING_DISABLED = -2
|
10
|
-
AO_TRACING_DECISIONS_XTRACE_NOT_SAMPLED = -1
|
11
9
|
AO_TRACING_DECISIONS_OK = 0
|
12
|
-
|
13
|
-
|
14
|
-
AO_TRACING_DECISIONS_REPORTER_NOT_READY = 3
|
15
|
-
AO_TRACING_DECISIONS_NO_VALID_SETTINGS = 4
|
16
|
-
AO_TRACING_DECISIONS_QUEUE_FULL = 5
|
10
|
+
|
11
|
+
OBOE_SETTINGS_UNSET = -1
|
17
12
|
|
18
13
|
module AppOpticsAPM
|
19
14
|
##
|
@@ -21,13 +16,15 @@ module AppOpticsAPM
|
|
21
16
|
#
|
22
17
|
class TransactionSettings
|
23
18
|
|
24
|
-
attr_accessor :
|
25
|
-
attr_reader :do_propagate, :rate, :
|
19
|
+
attr_accessor :do_sample, :do_metrics
|
20
|
+
attr_reader :auth_msg, :do_propagate, :status_msg, :type, :source, :rate, :xtrace
|
21
|
+
#, :status
|
26
22
|
|
27
|
-
def initialize(url =
|
23
|
+
def initialize(url = '', xtrace = '', options = nil)
|
28
24
|
@do_metrics = false
|
29
25
|
@do_sample = false
|
30
26
|
@do_propagate = true
|
27
|
+
@xtrace = xtrace || ''
|
31
28
|
tracing_mode = AO_TRACING_ENABLED
|
32
29
|
|
33
30
|
if AppOpticsAPM::Context.isValid
|
@@ -46,14 +43,23 @@ module AppOpticsAPM
|
|
46
43
|
tracing_mode = AO_TRACING_DISABLED
|
47
44
|
end
|
48
45
|
|
49
|
-
args = [xtrace
|
46
|
+
args = [@xtrace]
|
50
47
|
args << tracing_mode
|
51
|
-
args << AppOpticsAPM::Config[:sample_rate]
|
48
|
+
args << (AppOpticsAPM::Config[:sample_rate] || OBOE_SETTINGS_UNSET)
|
49
|
+
|
50
|
+
if options && (options.options || options.signature)
|
51
|
+
args << (options.trigger_trace ? 1 : 0)
|
52
|
+
args << (trigger_tracing_mode_disabled? ? 0 : 1)
|
53
|
+
args << options.options
|
54
|
+
args << options.signature
|
55
|
+
args << options.timestamp
|
56
|
+
end
|
52
57
|
|
53
|
-
metrics, sample, @rate, @source,
|
58
|
+
metrics, sample, @rate, @source, @type, @auth, @status_msg, @auth_msg, @status =
|
59
|
+
AppOpticsAPM::Context.getDecisions(*args)
|
54
60
|
|
55
|
-
if
|
56
|
-
AppOpticsAPM.logger.warn "[appoptics-apm/sample] Problem getting the sampling decisions
|
61
|
+
if @status > AO_TRACING_DECISIONS_OK
|
62
|
+
AppOpticsAPM.logger.warn "[appoptics-apm/sample] Problem getting the sampling decisions: #{@status_msg} code: #{@status}"
|
57
63
|
end
|
58
64
|
|
59
65
|
@do_metrics = metrics > 0
|
@@ -64,6 +70,20 @@ module AppOpticsAPM
|
|
64
70
|
"do_propagate: #{do_propagate}, do_sample: #{do_sample}, do_metrics: #{do_metrics} rate: #{rate}, source: #{source}"
|
65
71
|
end
|
66
72
|
|
73
|
+
def add_kvs(kvs)
|
74
|
+
kvs[:SampleRate] = @rate
|
75
|
+
kvs[:SampleSource] = @source
|
76
|
+
end
|
77
|
+
|
78
|
+
def triggered_trace?
|
79
|
+
@type == 1
|
80
|
+
end
|
81
|
+
|
82
|
+
def auth_ok?
|
83
|
+
# @auth is undefined if initialize is called with an existing context
|
84
|
+
!@auth || @auth < 1
|
85
|
+
end
|
86
|
+
|
67
87
|
private
|
68
88
|
|
69
89
|
##
|
@@ -103,6 +123,11 @@ module AppOpticsAPM
|
|
103
123
|
false
|
104
124
|
end
|
105
125
|
|
126
|
+
def trigger_tracing_mode_disabled?
|
127
|
+
AppOpticsAPM::Config[:trigger_tracing_mode] &&
|
128
|
+
AppOpticsAPM::Config[:trigger_tracing_mode] == :disabled
|
129
|
+
end
|
130
|
+
|
106
131
|
##
|
107
132
|
# asset?
|
108
133
|
#
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# Copyright (c) 2019 SolarWinds, LLC.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
|
5
|
+
module AppOpticsAPM
|
6
|
+
class XTraceOptions
|
7
|
+
|
8
|
+
attr_reader :options, :signature, :trigger_trace, :timestamp
|
9
|
+
attr_reader :pd_keys, :custom_kvs, :ignored # used in tests
|
10
|
+
##
|
11
|
+
# Params:
|
12
|
+
# +options+ : An X-Trace-Options @options string
|
13
|
+
# +signature+ : hmac signature to pass on for verification
|
14
|
+
#
|
15
|
+
# populates:
|
16
|
+
# - @force_trace (true|false)
|
17
|
+
# - @app_id (as given by Pingdom)
|
18
|
+
# - @probe_id (as given by Pingdom)
|
19
|
+
# - @loc (2 characters given by Pingdom)
|
20
|
+
# - @custom_kvs (hash)
|
21
|
+
# - @ignored (array)
|
22
|
+
#
|
23
|
+
# split it up by ';' separator
|
24
|
+
# kv assignment by '='
|
25
|
+
# currently valid keys:
|
26
|
+
# - force_trace (valid: 0,1) unless we use just a kv
|
27
|
+
# - application_id (format defined by pingdom (no validation))
|
28
|
+
# - probe_id
|
29
|
+
# - custom_* (';=' not allowed in key), value (validate max. length)
|
30
|
+
# - ts (unix timestamp)
|
31
|
+
# - other keys will be reported in the response options as ignored
|
32
|
+
|
33
|
+
def initialize(options, signature = nil)
|
34
|
+
@options = options.dup
|
35
|
+
@signature = signature.dup
|
36
|
+
@trigger_trace = false
|
37
|
+
@custom_kvs = {}
|
38
|
+
@pd_keys = nil
|
39
|
+
@ignored = []
|
40
|
+
@timestamp = 0
|
41
|
+
|
42
|
+
options&.split(/;+/)&.each do |val|
|
43
|
+
k = val.split('=', 2)
|
44
|
+
|
45
|
+
next unless k[0] # it can be nil, eg when the header starts with ';'
|
46
|
+
|
47
|
+
k[0]&.strip!
|
48
|
+
case k[0]
|
49
|
+
when 'trigger-trace'
|
50
|
+
if k[1]
|
51
|
+
@ignored << 'trigger-trace'
|
52
|
+
else
|
53
|
+
@trigger_trace = true
|
54
|
+
end
|
55
|
+
when 'pd-keys'
|
56
|
+
if @pd_keys
|
57
|
+
AppOpticsAPM.logger.info "[appoptics_apm/x-trace-options] Duplicate key: #{k[0]}"
|
58
|
+
else
|
59
|
+
@pd_keys = k[1].strip
|
60
|
+
end
|
61
|
+
when /^custom-[^\s]*$/
|
62
|
+
if @custom_kvs[k[0]]
|
63
|
+
AppOpticsAPM.logger.info "[appoptics_apm/x-trace-options] Duplicate key: #{k[0]}"
|
64
|
+
else
|
65
|
+
@custom_kvs[k[0]] = k[1].strip
|
66
|
+
end
|
67
|
+
when 'ts'
|
68
|
+
if @timestamp > 0
|
69
|
+
AppOpticsAPM.logger.info "[appoptics_apm/x-trace-options] Duplicate key: #{k[0]}"
|
70
|
+
else
|
71
|
+
@timestamp = k[1].to_i
|
72
|
+
end
|
73
|
+
else
|
74
|
+
@ignored << k[0]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
unless @ignored.empty?
|
78
|
+
msg = "[appoptics_apm/x-trace-options] Some keys were ignored: #{@ignored.join(',' )}"
|
79
|
+
AppOpticsAPM.logger.info(msg)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def add_kvs(kvs, settings)
|
84
|
+
return unless settings.auth_ok?
|
85
|
+
|
86
|
+
@custom_kvs.each { |k,v| kvs[k] = v } unless @custom_kvs.empty?
|
87
|
+
kvs['PDKeys'] = @pd_keys if @pd_keys
|
88
|
+
kvs['TriggeredTrace'] = true if settings.triggered_trace?
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_response_header(headers, settings)
|
92
|
+
return unless options
|
93
|
+
|
94
|
+
response = []
|
95
|
+
response << "auth=#{settings.auth_msg}" if @signature
|
96
|
+
if settings.auth_ok?
|
97
|
+
if @trigger_trace
|
98
|
+
trigger_msg = !settings.xtrace.empty? && settings.type == 0 ? 'ignored' : settings.status_msg
|
99
|
+
else
|
100
|
+
trigger_msg = 'not-requested'
|
101
|
+
end
|
102
|
+
response << "trigger-trace=#{trigger_msg}"
|
103
|
+
response << "ignored=#{@ignored.join(',')}" unless @ignored.empty?
|
104
|
+
end
|
105
|
+
|
106
|
+
headers['X-Trace-Options-Response'] = response.join(';')
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
@@ -7,8 +7,8 @@ module AppOpticsAPM
|
|
7
7
|
# appoptics_apm.gemspec during gem build process
|
8
8
|
module Version
|
9
9
|
MAJOR = 4 # breaking,
|
10
|
-
MINOR =
|
11
|
-
PATCH =
|
10
|
+
MINOR = 9 # feature,
|
11
|
+
PATCH = 0 # fix => BFF
|
12
12
|
|
13
13
|
STRING = [MAJOR, MINOR, PATCH].compact.join('.')
|
14
14
|
end
|
@@ -50,7 +50,7 @@ if defined?(AppOpticsAPM::Config)
|
|
50
50
|
AppOpticsAPM::Config[:verbose] = false
|
51
51
|
|
52
52
|
#
|
53
|
-
# Turn
|
53
|
+
# Turn Tracing on or off
|
54
54
|
#
|
55
55
|
# By default tracing is set to :enabled, the other option is :disabled.
|
56
56
|
# :enabled means that sampling will be done according to the current
|
@@ -61,31 +61,41 @@ if defined?(AppOpticsAPM::Config)
|
|
61
61
|
#
|
62
62
|
AppOpticsAPM::Config[:tracing_mode] = :enabled
|
63
63
|
|
64
|
+
#
|
65
|
+
# Turn Trigger Tracing on or off
|
66
|
+
#
|
67
|
+
# By default trigger tracing is :enabled, the other option is :disabled.
|
68
|
+
# It allows to use the X-Trace-Options header to force a request to be
|
69
|
+
# traced (within rate limits set for trigger tracing)
|
70
|
+
#
|
71
|
+
AppOpticsAPM::Config[:trigger_tracing_mode] = :enabled
|
72
|
+
|
64
73
|
#
|
65
74
|
# Trace Context in Logs
|
66
75
|
#
|
67
|
-
# Configure if and when the
|
76
|
+
# Configure if and when the Trace ID should be included in application logs.
|
68
77
|
# Common Ruby and Rails loggers are auto-instrumented, so that they can include
|
69
|
-
# the current
|
78
|
+
# the current Trace ID in log messages.
|
70
79
|
#
|
71
80
|
# The added string will look like: "ao.traceId=7435A9FE510AE4533414D425DADF4E180D2B4E36-0"
|
72
81
|
# It ends in '-1' if the request is sampled and in '-0' otherwise.
|
73
82
|
#
|
74
83
|
# The following options are available:
|
75
84
|
# :never (default)
|
76
|
-
# :sampled only include the
|
77
|
-
# :traced include the
|
78
|
-
# :always always add a
|
85
|
+
# :sampled only include the Trace ID of sampled requests
|
86
|
+
# :traced include the Trace ID for all traced requests
|
87
|
+
# :always always add a Trace ID, it will be '0000000000000000000000000000000000000000-0'
|
79
88
|
# when there is no tracing context.
|
80
89
|
#
|
81
90
|
AppOpticsAPM::Config[:log_traceId] = :never
|
82
91
|
|
83
92
|
#
|
84
|
-
# Prepend
|
93
|
+
# Prepend Domain to Transaction Name
|
85
94
|
#
|
86
|
-
# If this is set to `true` transaction names will be composed as
|
87
|
-
# `controller.action
|
88
|
-
#
|
95
|
+
# If this is set to `true` transaction names will be composed as
|
96
|
+
# `my.host.com/controller.action` instead of `controller.action`.
|
97
|
+
# This configuration applies to all transaction names, whether deduced by the
|
98
|
+
# instrumentation or implicitly set.
|
89
99
|
#
|
90
100
|
AppOpticsAPM::Config[:transaction_name][:prepend_domain] = false
|
91
101
|
|
@@ -195,6 +205,21 @@ if defined?(AppOpticsAPM::Config)
|
|
195
205
|
AppOpticsAPM::Config[:report_rescued_errors] = false
|
196
206
|
#
|
197
207
|
|
208
|
+
#
|
209
|
+
# EC2 Metadata Fetching Timeout
|
210
|
+
#
|
211
|
+
# The timeout can be in the range 0 - 3000 (milliseconds)
|
212
|
+
# Setting to 0 milliseconds effectively disables fetching from
|
213
|
+
# the metadata URL (not waiting), and should only be used if
|
214
|
+
# not running on EC2 / Openstack to minimize agent start up time.
|
215
|
+
#
|
216
|
+
AppOpticsAPM::Config[:ec2_metadata_timeout] = 1000
|
217
|
+
|
218
|
+
|
219
|
+
#############################################
|
220
|
+
## SETTINGS FOR INDIVIDUAL GEMS/FRAMEWORKS ##
|
221
|
+
#############################################
|
222
|
+
|
198
223
|
#
|
199
224
|
# Bunny Controller and Action
|
200
225
|
#
|
@@ -235,7 +260,7 @@ if defined?(AppOpticsAPM::Config)
|
|
235
260
|
AppOpticsAPM::Config[:dalli][:enabled] = true
|
236
261
|
AppOpticsAPM::Config[:delayed_jobclient][:enabled] = true
|
237
262
|
AppOpticsAPM::Config[:delayed_jobworker][:enabled] = true
|
238
|
-
AppOpticsAPM::Config[:em_http_request][:enabled] = false
|
263
|
+
# AppOpticsAPM::Config[:em_http_request][:enabled] = false # not supported anymore
|
239
264
|
AppOpticsAPM::Config[:excon][:enabled] = true
|
240
265
|
AppOpticsAPM::Config[:faraday][:enabled] = true
|
241
266
|
AppOpticsAPM::Config[:grpc_client][:enabled] = true
|
@@ -301,7 +326,7 @@ if defined?(AppOpticsAPM::Config)
|
|
301
326
|
AppOpticsAPM::Config[:dalli][:collect_backtraces] = false
|
302
327
|
AppOpticsAPM::Config[:delayed_jobclient][:collect_backtraces] = false
|
303
328
|
AppOpticsAPM::Config[:delayed_jobworker][:collect_backtraces] = false
|
304
|
-
AppOpticsAPM::Config[:em_http_request][:collect_backtraces] = true
|
329
|
+
# AppOpticsAPM::Config[:em_http_request][:collect_backtraces] = true # not supported anymore
|
305
330
|
AppOpticsAPM::Config[:excon][:collect_backtraces] = true
|
306
331
|
AppOpticsAPM::Config[:faraday][:collect_backtraces] = false
|
307
332
|
AppOpticsAPM::Config[:grape][:collect_backtraces] = true
|
data/scrap_gemfile
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appoptics_apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maia Engeli
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2019-09-
|
13
|
+
date: 2019-09-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -117,6 +117,7 @@ files:
|
|
117
117
|
- ".dockerignore"
|
118
118
|
- ".github/ISSUE_TEMPLATE/bug-or-feature-request.md"
|
119
119
|
- ".gitignore"
|
120
|
+
- ".irbrc"
|
120
121
|
- ".rubocop.yml"
|
121
122
|
- ".travis.yml"
|
122
123
|
- ".yardopts"
|
@@ -218,6 +219,7 @@ files:
|
|
218
219
|
- lib/appoptics_apm/sdk/tracing.rb
|
219
220
|
- lib/appoptics_apm/support/transaction_metrics.rb
|
220
221
|
- lib/appoptics_apm/support/transaction_settings.rb
|
222
|
+
- lib/appoptics_apm/support/x_trace_options.rb
|
221
223
|
- lib/appoptics_apm/support_report.rb
|
222
224
|
- lib/appoptics_apm/test.rb
|
223
225
|
- lib/appoptics_apm/thread_local.rb
|
@@ -232,6 +234,10 @@ files:
|
|
232
234
|
- lib/oboe_metal.rb
|
233
235
|
- lib/rails/generators/appoptics_apm/install_generator.rb
|
234
236
|
- lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb
|
237
|
+
- oboe.code-workspace
|
238
|
+
- scrap.rb
|
239
|
+
- scrap_gemfile
|
240
|
+
- scrap_gemfile.lock
|
235
241
|
- yardoc_frontpage.md
|
236
242
|
homepage: https://www.appoptics.com/
|
237
243
|
licenses:
|
@@ -249,7 +255,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
249
255
|
requirements:
|
250
256
|
- - ">="
|
251
257
|
- !ruby/object:Gem::Version
|
252
|
-
version: 2.
|
258
|
+
version: 2.4.0
|
253
259
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
254
260
|
requirements:
|
255
261
|
- - ">="
|
@@ -257,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
257
263
|
version: '0'
|
258
264
|
requirements: []
|
259
265
|
rubyforge_project:
|
260
|
-
rubygems_version: 2.6.
|
266
|
+
rubygems_version: 2.7.6.2
|
261
267
|
signing_key:
|
262
268
|
specification_version: 4
|
263
269
|
summary: AppOptics APM performance instrumentation gem for Ruby
|