appoptics_apm 4.2.2 → 4.2.3

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -3
  3. data/Gemfile +0 -2
  4. data/README.md +119 -95
  5. data/examples/SDK/01_basic_tracing.rb +67 -0
  6. data/ext/oboe_metal/src/VERSION +1 -1
  7. data/lib/appoptics_apm/api.rb +10 -9
  8. data/lib/appoptics_apm/api/layerinit.rb +1 -1
  9. data/lib/appoptics_apm/api/logging.rb +41 -14
  10. data/lib/appoptics_apm/api/metrics.rb +34 -0
  11. data/lib/appoptics_apm/api/profiling.rb +5 -0
  12. data/lib/appoptics_apm/api/tracing.rb +33 -148
  13. data/lib/appoptics_apm/api/util.rb +3 -9
  14. data/lib/appoptics_apm/base.rb +11 -12
  15. data/lib/appoptics_apm/frameworks/padrino/templates.rb +1 -1
  16. data/lib/appoptics_apm/frameworks/rails.rb +1 -1
  17. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +1 -1
  18. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +1 -1
  19. data/lib/appoptics_apm/inst/bunny-consumer.rb +1 -2
  20. data/lib/appoptics_apm/inst/delayed_job.rb +4 -4
  21. data/lib/appoptics_apm/inst/em-http-request.rb +1 -1
  22. data/lib/appoptics_apm/inst/rack.rb +1 -0
  23. data/lib/appoptics_apm/inst/redis.rb +1 -1
  24. data/lib/appoptics_apm/inst/resque.rb +1 -1
  25. data/lib/appoptics_apm/inst/sidekiq-worker.rb +1 -3
  26. data/lib/appoptics_apm/loading.rb +3 -4
  27. data/lib/appoptics_apm/logger.rb +1 -1
  28. data/lib/appoptics_apm/sdk.rb +317 -0
  29. data/lib/appoptics_apm/support.rb +0 -17
  30. data/lib/appoptics_apm/test.rb +1 -1
  31. data/lib/appoptics_apm/util.rb +4 -3
  32. data/lib/appoptics_apm/version.rb +1 -1
  33. data/lib/appoptics_apm/xtrace.rb +3 -3
  34. data/lib/joboe_metal.rb +2 -4
  35. data/lib/oboe_metal.rb +5 -5
  36. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +5 -4
  37. data/run_tests_docker.rb +6 -0
  38. metadata +5 -9
  39. data/examples/DNT.md +0 -35
  40. data/examples/instrumenting_metal_controller.rb +0 -8
  41. data/examples/puma_on_heroku_config.rb +0 -17
  42. data/examples/tracing_async_threads.rb +0 -124
  43. data/examples/tracing_background_jobs.rb +0 -53
  44. data/examples/tracing_forked_processes.rb +0 -99
  45. data/examples/unicorn_on_heroku_config.rb +0 -28
@@ -83,23 +83,6 @@ module AppOpticsAPM
83
83
  AppOpticsAPM.logger.warn 'No ActiveRecord'
84
84
  end
85
85
 
86
- # TODO we don't have libs in /usr/lib anymore, is this still needed???
87
- # AppOpticsAPM.logger.warn '********************************************************'
88
- # AppOpticsAPM.logger.warn '* AppOpticsAPM Libraries'
89
- # AppOpticsAPM.logger.warn '********************************************************'
90
- # files = []
91
- # ['/usr/lib/liboboe*', '/usr/lib64/liboboe*'].each do |d|
92
- # files = Dir.glob(d)
93
- # break if !files.empty?
94
- # end
95
- # if files.empty?
96
- # AppOpticsAPM.logger.warn 'Error: No liboboe libs!'
97
- # else
98
- # files.each { |f|
99
- # AppOpticsAPM.logger.warn f
100
- # }
101
- # end
102
-
103
86
  AppOpticsAPM.logger.warn '********************************************************'
104
87
  AppOpticsAPM.logger.warn '* AppOpticsAPM::Config Values'
105
88
  AppOpticsAPM.logger.warn '********************************************************'
@@ -16,7 +16,7 @@ module AppOpticsAPM
16
16
  # Load all of the test workers
17
17
  pattern = File.join(File.dirname(__FILE__), '../../test/jobs/**/', '*.rb')
18
18
  Dir.glob(pattern) do |f|
19
- AppOpticsAPM.logger.debug "Loading test job file: #{File.basename(f)}"
19
+ AppOpticsAPM.logger.debug "[appoptics_apm/test] Loading test job file: #{File.basename(f)}"
20
20
  require f
21
21
  end
22
22
  end
@@ -262,9 +262,10 @@ module AppOpticsAPM
262
262
  platform_info['Force'] = true
263
263
  platform_info['Ruby.Platform.Version'] = RUBY_PLATFORM
264
264
  platform_info['Ruby.Version'] = RUBY_VERSION
265
- platform_info['Ruby.AppOpticsAPM.Version'] = ::AppOpticsAPM::Version::STRING
266
- # Should this be the oboe version, separate from the Ruby library's version?
267
- platform_info['Ruby.Oboe.Version'] = ::AppOpticsAPM::Version::STRING
265
+ platform_info['Ruby.AppOpticsAPM.Version'] = ::AppOpticsAPM::Version::STRING
266
+
267
+ clib_version_file = File.join(Gem::Specification.find_by_name('appoptics_apm').gem_dir, 'ext', 'oboe_metal', 'src', 'VERSION')
268
+ platform_info['Ruby.clib.Version'] = File.read(clib_version_file).chomp
268
269
  platform_info['RubyHeroku.AppOpticsAPM.Version'] = ::AppOpticsAPMHeroku::Version::STRING if defined?(::AppOpticsAPMHeroku)
269
270
  platform_info['Ruby.TraceMode.Version'] = ::AppOpticsAPM::Config[:tracing_mode]
270
271
 
@@ -8,7 +8,7 @@ module AppOpticsAPM
8
8
  module Version
9
9
  MAJOR = 4
10
10
  MINOR = 2
11
- PATCH = 2
11
+ PATCH = 3
12
12
 
13
13
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
14
14
  end
@@ -24,7 +24,7 @@ module AppOpticsAPM
24
24
 
25
25
  true
26
26
  rescue StandardError => e
27
- AppOpticsAPM.logger.debug e.message
27
+ AppOpticsAPM.logger.debug "[appoptics_apm/xtrace] #{e.message}"
28
28
  AppOpticsAPM.logger.debug e.backtrace
29
29
  false
30
30
  end
@@ -51,7 +51,7 @@ module AppOpticsAPM
51
51
 
52
52
  xtrace[2..41]
53
53
  rescue StandardError => e
54
- AppOpticsAPM.logger.debug e.message
54
+ AppOpticsAPM.logger.debug "[appoptics_apm/xtrace] #{e.message}"
55
55
  AppOpticsAPM.logger.debug e.backtrace
56
56
  return nil
57
57
  end
@@ -66,7 +66,7 @@ module AppOpticsAPM
66
66
 
67
67
  xtrace[42..57]
68
68
  rescue StandardError => e
69
- AppOpticsAPM.logger.debug e.message
69
+ AppOpticsAPM.logger.debug "[appoptics_apm/xtrace] #{e.message}"
70
70
  AppOpticsAPM.logger.debug e.backtrace
71
71
  return nil
72
72
  end
@@ -150,13 +150,11 @@ module AppOpticsAPM
150
150
 
151
151
  # Validation to make Joboe happy. Assure that we have the KVs and that they
152
152
  # are not empty strings.
153
- opts[:layer] = nil if opts[:layer].is_a?(String) && opts[:layer].empty?
154
153
  opts[:xtrace] = nil if opts[:xtrace].is_a?(String) && opts[:xtrace].empty?
155
154
 
156
- opts[:layer] ||= nil
157
155
  opts[:xtrace] ||= nil
158
156
 
159
- sr_cfg = Java::ComTracelyticsJoboe::LayerUtil.shouldTraceRequest(opts[:layer], { 'X-Trace' => opts[:xtrace] })
157
+ sr_cfg = Java::ComTracelyticsJoboe::LayerUtil.shouldTraceRequest(APPOPTICS_STR_BLANK, { 'X-Trace' => opts[:xtrace] })
160
158
 
161
159
  # Store the returned SampleRateConfig into AppOpticsAPM::Config
162
160
  if sr_cfg
@@ -179,7 +177,7 @@ module AppOpticsAPM
179
177
  end
180
178
 
181
179
  def set_tracing_mode(_mode)
182
- AppOpticsAPM.logger.warn 'When using JRuby set the tracing mode in /usr/local/tracelytics/javaagent.json instead'
180
+ AppOpticsAPM.logger.warn '[appoptics_apm/joboe] When using JRuby set the tracing mode in /usr/local/tracelytics/javaagent.json instead'
183
181
  end
184
182
 
185
183
  def set_sample_rate(_rate)
@@ -134,10 +134,10 @@ module AppOpticsAPM
134
134
  return false unless AppOpticsAPM.loaded
135
135
 
136
136
  # Assure defaults since SWIG enforces Strings
137
- layer = opts[:layer] ? opts[:layer].to_s.strip.freeze : APPOPTICS_STR_BLANK
138
137
  xtrace = opts[:xtrace] ? opts[:xtrace].to_s.strip : APPOPTICS_STR_BLANK
139
138
 
140
- rv = AppOpticsAPM::Context.sampleRequest(layer, xtrace)
139
+ # the first arg has changed to be the service name, blank means to use the default (from the service key)
140
+ rv = AppOpticsAPM::Context.sampleRequest(APPOPTICS_STR_BLANK, xtrace)
141
141
 
142
142
  if rv == 0
143
143
  AppOpticsAPM.sample_rate = -1
@@ -162,14 +162,14 @@ module AppOpticsAPM
162
162
 
163
163
  case value
164
164
  when :never
165
- AppOpticsAPM::Context.setTracingMode(OBOE_TRACE_NEVER)
165
+ AppOpticsAPM::Context.setTracingMode(APPOPTICS_TRACE_NEVER)
166
166
 
167
167
  when :always
168
- AppOpticsAPM::Context.setTracingMode(OBOE_TRACE_ALWAYS)
168
+ AppOpticsAPM::Context.setTracingMode(APPOPTICS_TRACE_ALWAYS)
169
169
 
170
170
  else
171
171
  AppOpticsAPM.logger.fatal "[oboe/error] Invalid tracing mode set: #{mode}"
172
- AppOpticsAPM::Context.setTracingMode(OBOE_TRACE_NEVER)
172
+ AppOpticsAPM::Context.setTracingMode(APPOPTICS_TRACE_NEVER)
173
173
  end
174
174
  end
175
175
 
@@ -43,12 +43,13 @@ if defined?(AppOpticsAPM::Config)
43
43
  AppOpticsAPM::Config[:sanitize_sql_opts] = Regexp::IGNORECASE
44
44
 
45
45
  #
46
- # Do Not Trace
47
- # These two values allow you to configure specific URL patterns to
48
- # never be traced. By default, this is set to common static file
46
+ # Do Not Trace - DNT
47
+ # 'dnt_regexp' and 'dnt_opts' allow you to configure specific URL patterns
48
+ # to never be traced. By default, this is set to common static file
49
49
  # extensions but you may want to customize this list for your needs.
50
+ # Examples of such files may be images, javascript, pdfs, and text files.
50
51
  #
51
- # dnt_regexp and dnt_opts is passed to Regexp.new to create
52
+ # 'dnt_regexp' and 'dnt_opts' is passed to Regexp.new to create
52
53
  # a regular expression object. That is then used to match against
53
54
  # the incoming request path.
54
55
  #
@@ -8,6 +8,12 @@
8
8
  # `docker build -f Dockerfile_test -t ruby_appoptics_apm .`
9
9
  # (docker-compose will build it too if missing)
10
10
 
11
+
12
+ # remove rbenv .ruby_version file that may be stuck on a different ruby version
13
+ # because we mounted this directory in a docker container
14
+ require 'fileutils'
15
+ FileUtils.rm_f('.ruby_version')
16
+
11
17
  require 'yaml'
12
18
  travis = YAML.load_file('.travis.yml')
13
19
 
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.2.2
4
+ version: 4.2.3
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: 2018-06-11 00:00:00.000000000 Z
13
+ date: 2018-07-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -133,14 +133,8 @@ files:
133
133
  - build_gems.sh
134
134
  - config/initializers/.keep
135
135
  - docker-compose.yml
136
- - examples/DNT.md
136
+ - examples/SDK/01_basic_tracing.rb
137
137
  - examples/carrying_context.rb
138
- - examples/instrumenting_metal_controller.rb
139
- - examples/puma_on_heroku_config.rb
140
- - examples/tracing_async_threads.rb
141
- - examples/tracing_background_jobs.rb
142
- - examples/tracing_forked_processes.rb
143
- - examples/unicorn_on_heroku_config.rb
144
138
  - ext/oboe_metal/extconf.rb
145
139
  - ext/oboe_metal/lib/.keep
146
140
  - ext/oboe_metal/noop/noop.c
@@ -158,6 +152,7 @@ files:
158
152
  - lib/appoptics_apm/api/layerinit.rb
159
153
  - lib/appoptics_apm/api/logging.rb
160
154
  - lib/appoptics_apm/api/memcache.rb
155
+ - lib/appoptics_apm/api/metrics.rb
161
156
  - lib/appoptics_apm/api/profiling.rb
162
157
  - lib/appoptics_apm/api/tracing.rb
163
158
  - lib/appoptics_apm/api/util.rb
@@ -215,6 +210,7 @@ files:
215
210
  - lib/appoptics_apm/noop/README.md
216
211
  - lib/appoptics_apm/noop/context.rb
217
212
  - lib/appoptics_apm/ruby.rb
213
+ - lib/appoptics_apm/sdk.rb
218
214
  - lib/appoptics_apm/support.rb
219
215
  - lib/appoptics_apm/test.rb
220
216
  - lib/appoptics_apm/thread_local.rb
@@ -1,35 +0,0 @@
1
- By default, the AppOpticsAPM gem will not trace routes with extensions
2
- for common static files. Examples of such files may be images,
3
- javascript, pdfs and text files.
4
-
5
- This is done by using the regular expression stored in
6
- `AppOpticsAPM::Config[:dnt_regexp]`:
7
-
8
- .(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|ttf|woff|svg|less)$
9
-
10
- This string is used as a regular expression and is tested against
11
- candidate URLs to be instrumented.
12
-
13
- To replace the pattern in use, you can update this regular expression
14
- string. Here are some examples.
15
-
16
- If you prefer that you want your javascript and CSS files instrumented,
17
- you can update `AppOpticsAPM::Config[:dnt_regexp]` with an updated regexp
18
- pattern (without the "js" and "css" entries):
19
-
20
- .(jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|flv|swf|ttf|woff|svg|less)$
21
-
22
- If you prefer to not instrument all javascript files except for one
23
- named `show.js`, you could put this assignment into your initializer,
24
- rackup file or application.rb (note that this example uses a standard
25
- regexp [negative
26
- look-behind](http://www.regular-expressions.info/lookaround.html) that
27
- isn't supported in Ruby 1.8):
28
-
29
- AppOpticsAPM::Config[:dnt_regexp] = "(\.js$)(?<!show.js)"
30
-
31
- Since this pattern is used with the standard Ruby Regexp class, you can
32
- use any Regexp supported pattern. See the documentation on Ruby Regexp
33
- [here](https://www.omniref.com/ruby/2.2.0/symbols/Regexp?d=380181456&n=0#doc_uncollapsed=true&d=380181456&n=0)
34
- or you can also view the oboe gem [source code documentation for this
35
- feature](https://github.com/tracelytics/ruby-appoptics/blob/master/lib/appoptics/config.rb#L129).
@@ -1,8 +0,0 @@
1
- class MetalController < ActionController::Metal
2
- def index
3
- self.response_body = 'Hello Metal!'
4
- end
5
-
6
- include AppOpticsAPMMethodProfiling
7
- profile_method :index, 'metal-index'
8
- end
@@ -1,17 +0,0 @@
1
- workers Integer(ENV['WEB_CONCURRENCY'] || 2)
2
- threads_count = Integer(ENV['MAX_THREADS'] || 5)
3
- threads threads_count, threads_count
4
-
5
- preload_app!
6
-
7
- rackup DefaultRackup
8
- port ENV['PORT'] || 3000
9
- environment ENV['RACK_ENV'] || 'development'
10
-
11
- on_worker_boot do
12
- ::AppOpticsAPM.reconnect! if defined?(::AppOpticsAPM)
13
- end
14
-
15
- on_worker_shutdown do
16
- ::AppOpticsAPM.disconnect! if defined?(::AppOpticsAPM)
17
- end
@@ -1,124 +0,0 @@
1
- #
2
- # This sample demonstrates how to instrument a main loop that
3
- # retrieves work and spawn threads that do the actual work
4
- #
5
-
6
- require 'math'
7
- require 'oboe'
8
-
9
- AppOpticsAPM::Config[:tracing_mode] = :always
10
- AppOpticsAPM::Config[:verbose] = true
11
-
12
- # The parent process/loop which collects data
13
- Kernel.loop do
14
-
15
- # For each loop, we instrument the work retrieval. These traces
16
- # will show up as layer 'get_the_work'.
17
- AppOpticsAPM::API.start_trace('get_the_work') do
18
- work = get_the_work
19
-
20
- # Loop through work and pass to `do_the_work` method
21
- # that spawns a thread each time
22
- work.each do |j|
23
-
24
- # In the new Thread block, the AppOpticsAPM tracing context isn't there
25
- # so we carry it over manually and pass it to the `start_trace`
26
- # method.
27
-
28
- # In the AppOptics dashboard, this will show up as parent traces
29
- # (layer 'get_the_work') with child traces (layer 'do_the_work').
30
-
31
- tracing_context = AppOpticsAPM::Context.toString
32
-
33
- Thread.new do
34
- result = nil
35
-
36
- AppOpticsAPM::API.start_trace('do_the_work', tracing_context, :Async => 1) do
37
- result = do_the_work(j)
38
- end
39
-
40
- result
41
- end
42
- end
43
- end
44
- sleep 5
45
- end
46
-
47
-
48
- ##
49
- # get_the_work
50
- #
51
- # Method to retrieve work to do
52
- #
53
- def get_the_work
54
- # We'll just return random integers as a
55
- # fake work load
56
- w = []
57
- w << rand(25)
58
- w << rand(25)
59
- w << rand(25)
60
- end
61
-
62
- ##
63
- # do_the_work
64
- #
65
- # The work-horse method
66
- #
67
- def do_the_work(job_to_do)
68
- i = job_to_do
69
- i * Math::PI
70
- end
71
-
72
- ####################################################
73
- # Notes
74
- ####################################################
75
-
76
- # The above code generates a trace for each loop of the parent data collection process.
77
- # Those traces have the layer name of `get_the_work` and will show up in the AppOptics
78
- # dashboard as such.
79
- #
80
- # Then as threads are spawned to process individual bits of work, we carry over the
81
- # `tracing_context` and start a new asynchronous trace using `start_trace`. (An
82
- # asynchronous trace is noted by passing the `Async` Hash key with a value of `1`).
83
- #
84
- # In the AppOptics dashboard, the two traces (parent and child; or one to many) will
85
- # be linked and displayed together as a single trace.
86
-
87
- ####################################################
88
- # Caveats
89
- ####################################################
90
-
91
- # If the main loop is retrieving many jobs (work) to process on each loop then
92
- # linking the traces may not be the best strategy as such large relationships
93
- # are difficult to display correctly in the AppOptics dashboard and provide little
94
- # added value.
95
- #
96
- # If there are more than 8 - 12 threads spawned from each loop, then you may want to consider
97
- # NOT carrying over tracing context into the spawned threads.
98
- #
99
- # In this case, you can simply omit `tracing_context` and passing it to `start_trace` in
100
- # the `Thread.new` block. (lines 32 + 37). Also remove the `{ Async => 1 }` Hash!
101
- #
102
- # This will produce two sets of traces with two the layer names 'get_the_work' +
103
- # 'do_the_work'.
104
- #
105
- # In the AppOptics dashboard, you can then separate or unify these traces into
106
- # independent applications. e.g. job processor, data retrieval, thread worker etc...
107
- #
108
- # An implementation of the work loop without carrying over tracing context would look
109
- # like the following:
110
- #
111
- # work.each do |j|
112
- # Thread.new do
113
- # result = nil
114
- #
115
- # AppOpticsAPM::API.start_trace('do_the_work') do
116
- # result = do_the_work(j)
117
- # end
118
- #
119
- # result
120
- # end
121
- # end
122
- #
123
- # If anything isn't clear, please don't hesitate to reach us at support (support@appoptics.com).
124
- #
@@ -1,53 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
-
4
- Bundler.require
5
-
6
- # Make sure oboe is at the bottom of your Gemfile.
7
- # This is likely redundant but just in case.
8
- require 'oboe'
9
-
10
- # Tracing mode can be 'never' or 'always'
11
- AppOpticsAPM::Config[:tracing_mode] = 'always'
12
-
13
- #
14
- # Update April 9, 2015 - this is done automagically now
15
- # and doesn't have to be called manually
16
- #
17
- # Load library instrumentation to auto-capture stuff we know about...
18
- # e.g. ActiveRecord, Cassandra, Dalli, Redis, Memcache, Mongo
19
- # AppOpticsAPM::Ruby.load
20
-
21
- # Some KVs to report to the dashboard
22
- report_kvs = {}
23
- report_kvs[:command_line_params] = ARGV.to_s
24
- report_kvs[:user_id] = `whoami`
25
-
26
- AppOpticsAPM::API.start_trace('my_background_job', nil, report_kvs) do
27
- #
28
- # Initialization code
29
- #
30
-
31
- tasks = get_all_tasks
32
-
33
- tasks.each do |t|
34
- # Optional: Here we embed another 'trace' to separate actual
35
- # work for each task. In the APPOPTICS dashboard, this will show
36
- # up as a large 'my_background_job' parent layer with many
37
- # child 'task" layers.
38
- AppOpticsAPM::API.trace('task', :task_id => t.id) do
39
- t.perform
40
- end
41
- end
42
- #
43
- # cleanup code
44
- #
45
- end
46
-
47
- # Note that we use 'start_trace' in the outer block and 'trace' for
48
- # any sub-blocks of code we wish to instrument. The arguments for
49
- # both methods vary slightly.
50
- #
51
- # TODO update location of the following doc
52
- # Details in RubyDoc:
53
- # https://www.omniref.com/ruby/gems/oboe/2.7.10.1/symbols/AppOpticsAPM::API::Tracing#tab=Methods