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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 37478c40a16c8636f4589a15e63db8d1b2eb0eae
4
- data.tar.gz: 2f2ac3b316e00963c42593680e638ecfc1792e3b
2
+ SHA256:
3
+ metadata.gz: c4b87b6581745b8485f7ddb38f17cb6eab85244a950e7d67cecfe0e97cdbd0bc
4
+ data.tar.gz: dce765afa7ceb92b523c448cd9b1b10efc1b6c5bb0f2f92842dc6af3c1934b27
5
5
  SHA512:
6
- metadata.gz: f695fc74e9f23d799709c32faab13b8c8c56e2f7da34b6968a5f085daf964927d3c98ffcadc49be6ab181fb66a872a4ec97d121468f01ed205c449e0d0873abc
7
- data.tar.gz: 730addb2cda57f6555d4965656cfeb1e753e32e7886e13cc1714c8b97b094664c4d0702a5494dc49ea7c266de6c101b25c4927a82ed652822890a581e45550b0
6
+ metadata.gz: d9b446519730872b09136e9b80e546a68dce40abf52fbb0e5ac139244c6ed3c7fa8ef45eb855714d8e11924886d0b972aa04332cec6342339c65772f5b7aec0f
7
+ data.tar.gz: 80df368e2ed2c868348ba5e7e9b24dfa2498d6f0cb703d568fbf8310879d06fee5ac59187a70747f04c040d4d54df2b8925faa856dc5a01b036375f21edacfbe
data/.gitignore CHANGED
@@ -1,5 +1,5 @@
1
1
  oboe*.gem
2
- Gemfile.lock
2
+ *.lock
3
3
  gemfiles/*.lock
4
4
  .ruby-version
5
5
  *~
@@ -27,3 +27,7 @@ coverage
27
27
  doc
28
28
  .*byebug*
29
29
  gemfiles/vendor*
30
+ scrap.rb
31
+ scarp_gemfile
32
+ .irbrc
33
+ *.code-workspace
@@ -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.8/swig-3.0.8.tar.gz
102
- - tar xzf swig-3.0.8.tar.gz
103
- - pushd swig-3.0.8
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
- - export OBOE_VERSION=5.1.1
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. Traces are written to /tmp/trace_output.bson. | `false`
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
- t.ruby_opts << ['-J-javaagent:/usr/local/tracelytics/tracelyticsagent.jar']
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 "Stop all containers that were started for testing and debugging"
79
- task "docker_down" do
80
- Dir.chdir('test/run_tests')
81
- exec('docker-compose down')
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 "Fetch extension dependency files"
85
- task :fetch_ext_deps do
86
- swig_version = %x{swig -version} rescue ''
87
- swig_version = swig_version.scan(/swig version [34]/i)
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
- # The c-lib version is different from the gem version
97
- oboe_version = ENV['OBOE_VERSION'] || 'latest'
98
- oboe_s3_dir = "https://s3-us-west-2.amazonaws.com/rc-files-t2/c-lib/#{oboe_version}"
99
- ext_src_dir = File.expand_path('ext/oboe_metal/src')
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
- # oboe and bson header files
112
- FileUtils.mkdir_p(File.join(ext_src_dir, 'bson'))
113
- %w(oboe.h oboe.hpp oboe_debug.h oboe.i bson/bson.h bson/platform_hacks.h).each do |filename|
114
- # %w(oboe.h oboe_debug.h bson/bson.h bson/platform_hacks.h).each do |filename|
115
- remote_file = File.join(oboe_s3_dir, 'include', filename)
116
- local_file = File.join(ext_src_dir, filename)
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
- FileUtils.cd(ext_src_dir) do
126
- system('swig -c++ -ruby -module oboe_metal oboe.i')
127
- FileUtils.rm('oboe.i')
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.'
@@ -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.0.0'
57
+ s.required_ruby_version = '>= 2.4.0'
58
58
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
59
59
  end
@@ -1 +1 @@
1
- 5.1.1
1
+ 6.0.0
@@ -49,6 +49,7 @@ begin
49
49
  if AppOpticsAPM.loaded
50
50
  require 'appoptics_apm/instrumentation'
51
51
  require 'appoptics_apm/support/transaction_metrics'
52
+ require 'appoptics_apm/support/x_trace_options'
52
53
 
53
54
  # Frameworks
54
55
  require 'appoptics_apm/frameworks/rails'
@@ -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, :excon, :faraday, :grpc_client, :grpc_server, :grape,
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, :em_http_request, :faraday, :httpclient, :nethttp, :rest_client, :typhoeus]
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 THIS ANYMORE, ALL TRACING COMMUNICATION TO OBOE
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
- # Make sure that the mode is stored as a symbol
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, settings)
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, settings)
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_\-]{71}$/) && ENV['APPOPTICS_COLLECTOR'] != "sslcollector:12222"
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
- AO_TRACING_DECISIONS_NULL_OUT = 1
13
- AO_TRACING_DECISIONS_NO_CONFIG = 2
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 :do_metrics, :do_sample
25
- attr_reader :do_propagate, :rate, :source
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 = nil, xtrace = '')
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] if AppOpticsAPM::Config[:sample_rate]&. >= 0
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, return_code = AppOpticsAPM::Context.getDecisions(*args)
58
+ metrics, sample, @rate, @source, @type, @auth, @status_msg, @auth_msg, @status =
59
+ AppOpticsAPM::Context.getDecisions(*args)
54
60
 
55
- if return_code > AO_TRACING_DECISIONS_OK
56
- AppOpticsAPM.logger.warn "[appoptics-apm/sample] Problem getting the sampling decisions, code: #{return_code}"
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 = 8 # feature,
11
- PATCH = 4 # fix => BFF
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 tracing on or off
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 traceId should be included in application logs.
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 traceId in log messages.
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 traceId of sampled requests
77
- # :traced include the traceId for all traced requests
78
- # :always always add a traceId, it will be '0000000000000000000000000000000000000000-0'
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 domain to transaction name
93
+ # Prepend Domain to Transaction Name
85
94
  #
86
- # If this is set to `true` transaction names will be composed as `my.host.com/controller.action` instead of
87
- # `controller.action`. This configuration applies to all transaction names, whether deduced by the instrumentation
88
- # or implicitly set.
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
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'rails', '~> 6.0.0'
4
+ gem 'puma'
5
+ gem 'pg'
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.8.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-10 00:00:00.000000000 Z
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.0.0
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.11
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