appoptics_apm 4.8.4 → 4.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 +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
|