appoptics_apm 4.2.2 → 4.2.3

Sign up to get free protection for your applications and to get access to all the features.
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