appoptics_apm_mnfst 4.5.2

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 (104) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +5 -0
  3. data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +16 -0
  4. data/.gitignore +29 -0
  5. data/.rubocop.yml +8 -0
  6. data/.travis.yml +121 -0
  7. data/.yardopts +4 -0
  8. data/CHANGELOG.md +769 -0
  9. data/CONFIG.md +33 -0
  10. data/Gemfile +29 -0
  11. data/LICENSE +193 -0
  12. data/README.md +393 -0
  13. data/Rakefile +230 -0
  14. data/appoptics_apm.gemspec +61 -0
  15. data/bin/appoptics_apm_config +15 -0
  16. data/build_gem.sh +15 -0
  17. data/build_gem_upload_to_packagecloud.sh +20 -0
  18. data/examples/SDK/01_basic_tracing.rb +67 -0
  19. data/examples/carrying_context.rb +220 -0
  20. data/ext/oboe_metal/extconf.rb +114 -0
  21. data/ext/oboe_metal/lib/.keep +0 -0
  22. data/ext/oboe_metal/noop/noop.c +7 -0
  23. data/ext/oboe_metal/src/VERSION +1 -0
  24. data/init.rb +4 -0
  25. data/lib/appoptics_apm.rb +76 -0
  26. data/lib/appoptics_apm/api.rb +20 -0
  27. data/lib/appoptics_apm/api/layerinit.rb +41 -0
  28. data/lib/appoptics_apm/api/logging.rb +375 -0
  29. data/lib/appoptics_apm/api/memcache.rb +37 -0
  30. data/lib/appoptics_apm/api/metrics.rb +55 -0
  31. data/lib/appoptics_apm/api/profiling.rb +203 -0
  32. data/lib/appoptics_apm/api/tracing.rb +53 -0
  33. data/lib/appoptics_apm/api/util.rb +122 -0
  34. data/lib/appoptics_apm/base.rb +230 -0
  35. data/lib/appoptics_apm/config.rb +254 -0
  36. data/lib/appoptics_apm/frameworks/grape.rb +97 -0
  37. data/lib/appoptics_apm/frameworks/padrino.rb +108 -0
  38. data/lib/appoptics_apm/frameworks/rails.rb +94 -0
  39. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -0
  40. data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +55 -0
  41. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  42. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  43. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  44. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
  45. data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
  46. data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
  47. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  48. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +29 -0
  49. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +31 -0
  50. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +119 -0
  51. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +108 -0
  52. data/lib/appoptics_apm/frameworks/sinatra.rb +125 -0
  53. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  54. data/lib/appoptics_apm/inst/bunny-consumer.rb +89 -0
  55. data/lib/appoptics_apm/inst/curb.rb +330 -0
  56. data/lib/appoptics_apm/inst/dalli.rb +85 -0
  57. data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
  58. data/lib/appoptics_apm/inst/em-http-request.rb +101 -0
  59. data/lib/appoptics_apm/inst/excon.rb +125 -0
  60. data/lib/appoptics_apm/inst/faraday.rb +94 -0
  61. data/lib/appoptics_apm/inst/grpc_client.rb +162 -0
  62. data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
  63. data/lib/appoptics_apm/inst/http.rb +73 -0
  64. data/lib/appoptics_apm/inst/httpclient.rb +174 -0
  65. data/lib/appoptics_apm/inst/memcached.rb +86 -0
  66. data/lib/appoptics_apm/inst/mongo.rb +246 -0
  67. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  68. data/lib/appoptics_apm/inst/moped.rb +466 -0
  69. data/lib/appoptics_apm/inst/rack.rb +199 -0
  70. data/lib/appoptics_apm/inst/redis.rb +275 -0
  71. data/lib/appoptics_apm/inst/resque.rb +151 -0
  72. data/lib/appoptics_apm/inst/rest-client.rb +48 -0
  73. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  74. data/lib/appoptics_apm/inst/sidekiq-client.rb +55 -0
  75. data/lib/appoptics_apm/inst/sidekiq-worker.rb +65 -0
  76. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  77. data/lib/appoptics_apm/inst/typhoeus.rb +108 -0
  78. data/lib/appoptics_apm/instrumentation.rb +22 -0
  79. data/lib/appoptics_apm/legacy_method_profiling.rb +90 -0
  80. data/lib/appoptics_apm/loading.rb +65 -0
  81. data/lib/appoptics_apm/logger.rb +42 -0
  82. data/lib/appoptics_apm/method_profiling.rb +33 -0
  83. data/lib/appoptics_apm/noop/README.md +9 -0
  84. data/lib/appoptics_apm/noop/context.rb +26 -0
  85. data/lib/appoptics_apm/noop/metadata.rb +22 -0
  86. data/lib/appoptics_apm/ruby.rb +35 -0
  87. data/lib/appoptics_apm/sdk/custom_metrics.rb +92 -0
  88. data/lib/appoptics_apm/sdk/tracing.rb +315 -0
  89. data/lib/appoptics_apm/support.rb +119 -0
  90. data/lib/appoptics_apm/test.rb +94 -0
  91. data/lib/appoptics_apm/thread_local.rb +26 -0
  92. data/lib/appoptics_apm/util.rb +319 -0
  93. data/lib/appoptics_apm/version.rb +15 -0
  94. data/lib/appoptics_apm/xtrace.rb +103 -0
  95. data/lib/joboe_metal.rb +212 -0
  96. data/lib/oboe.rb +7 -0
  97. data/lib/oboe/README +2 -0
  98. data/lib/oboe/backward_compatibility.rb +80 -0
  99. data/lib/oboe/inst/rack.rb +11 -0
  100. data/lib/oboe_metal.rb +198 -0
  101. data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
  102. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +265 -0
  103. data/yardoc_frontpage.md +26 -0
  104. metadata +266 -0
@@ -0,0 +1,97 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+ #
4
+ class GrapeError < StandardError; end
5
+
6
+ module AppOpticsAPM
7
+ module Grape
8
+ module API
9
+ def self.extended(klass)
10
+ AppOpticsAPM::Util.class_method_alias(klass, :inherited, ::Grape::API)
11
+ end
12
+
13
+ def inherited_with_appoptics(subclass)
14
+ inherited_without_appoptics(subclass)
15
+
16
+ subclass.use AppOpticsAPM::Rack
17
+ end
18
+ end
19
+
20
+ module Endpoint
21
+ def self.included(klass)
22
+ AppOpticsAPM::Util.method_alias(klass, :run, ::Grape::Endpoint)
23
+ end
24
+
25
+ def run_with_appoptics(*args)
26
+ # Report Controller/Action and Transaction as best possible
27
+ report_kvs = {}
28
+
29
+ report_kvs[:Controller] = options[:for].to_s
30
+ report_kvs[:Action] =
31
+ if route&.pattern
32
+ route.options ? "#{route.options[:method]}#{route.pattern.origin}" : route.pattern.origin
33
+ else
34
+ args.empty? ? env['PATH_INFO'] : args[0]['PATH_INFO']
35
+ end
36
+ report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:grape][:collect_backtraces]
37
+
38
+ env['appoptics_apm.controller'] = report_kvs[:Controller]
39
+ env['appoptics_apm.action'] = report_kvs[:Action]
40
+
41
+ AppOpticsAPM::API.log_entry('grape', report_kvs)
42
+
43
+ run_without_appoptics(*args)
44
+ ensure
45
+ AppOpticsAPM::API.log_exit('grape')
46
+ end
47
+ end
48
+
49
+ module Middleware
50
+ module Error
51
+ def self.included(klass)
52
+ AppOpticsAPM::Util.method_alias(klass, :error_response, ::Grape::Middleware::Error)
53
+ end
54
+
55
+ def error_response_with_appoptics(error = {})
56
+ status, headers, body = error_response_without_appoptics(error)
57
+
58
+ xtrace = AppOpticsAPM::Context.toString
59
+
60
+ if AppOpticsAPM.tracing?
61
+
62
+ # Since Grape uses throw/catch and not Exceptions, we have to create an exception here
63
+ exception = GrapeError.new(error[:message] ? error[:message] : "No message given.")
64
+ exception.set_backtrace(AppOpticsAPM::API.backtrace)
65
+
66
+ AppOpticsAPM::API.log_exception('rack', exception)
67
+
68
+ # Since calls to error() are handled similar to abort in Grape. We
69
+ # manually log the rack exit here since the original code won't
70
+ # be returned to
71
+ xtrace = AppOpticsAPM::API.log_end('rack', :Status => status)
72
+ end
73
+
74
+ if headers && AppOpticsAPM::XTrace.valid?(xtrace)
75
+ unless defined?(JRUBY_VERSION) && AppOpticsAPM.is_continued_trace?
76
+ headers['X-Trace'] = xtrace if headers.is_a?(Hash)
77
+ end
78
+ end
79
+
80
+ [status, headers, body]
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ if AppOpticsAPM::Config[:grape][:enabled] && defined?(Grape)
88
+ require 'appoptics_apm/inst/rack'
89
+
90
+ AppOpticsAPM.logger.info "[appoptics_apm/loading] Instrumenting Grape" if AppOpticsAPM::Config[:verbose]
91
+
92
+ AppOpticsAPM::Inst.load_instrumentation
93
+
94
+ AppOpticsAPM::Util.send_extend(Grape::API, AppOpticsAPM::Grape::API)
95
+ AppOpticsAPM::Util.send_include(Grape::Endpoint, AppOpticsAPM::Grape::Endpoint)
96
+ AppOpticsAPM::Util.send_include(Grape::Middleware::Error, AppOpticsAPM::Grape::Middleware::Error)
97
+ end
@@ -0,0 +1,108 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module AppOpticsAPM
5
+ module PadrinoInst
6
+ module Routing
7
+ def self.included(klass)
8
+ AppOpticsAPM::Util.method_alias(klass, :dispatch!, ::Padrino::Routing)
9
+ end
10
+
11
+ def dispatch_with_appoptics
12
+
13
+ AppOpticsAPM::API.log_entry('padrino', {})
14
+ report_kvs = {}
15
+
16
+ result = dispatch_without_appoptics
17
+
18
+ # Report Controller/Action and Transaction as best possible
19
+ controller = (request.controller && !request.controller.empty?) ? request.controller : nil
20
+ report_kvs[:Controller] = controller || self.class
21
+ report_kvs[:Action] = request.route_obj ? request.route_obj.path : request.action
22
+ env['appoptics_apm.controller'] = report_kvs[:Controller]
23
+ env['appoptics_apm.action'] = report_kvs[:Action]
24
+
25
+ result
26
+ rescue => e
27
+ AppOpticsAPM::API.log_exception('padrino', e)
28
+ raise e
29
+ ensure
30
+ report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:padrino][:collect_backtraces]
31
+ AppOpticsAPM::API.log_exit('padrino', report_kvs)
32
+ end
33
+ end
34
+
35
+ module Rendering
36
+ def self.included(klass)
37
+ AppOpticsAPM::Util.method_alias(klass, :render, ::Padrino::Rendering)
38
+ end
39
+
40
+ # TODO add test coverage, currently there are no tests for this
41
+ def render_with_appoptics(engine, data = nil, options = {}, locals = {}, &block)
42
+ if AppOpticsAPM.tracing?
43
+ report_kvs = {}
44
+
45
+ if data
46
+ report_kvs[:engine] = engine
47
+ report_kvs[:template] = data
48
+ else
49
+ report_kvs[:template] = engine
50
+ end
51
+
52
+ if AppOpticsAPM.tracing_layer_op?(:render)
53
+ # For recursive calls to :render (for sub-partials and layouts),
54
+ # use method profiling.
55
+ begin
56
+ report_kvs[:FunctionName] = :render
57
+ report_kvs[:Class] = :Rendering
58
+ report_kvs[:Module] = :Padrino
59
+ report_kvs[:File] = __FILE__
60
+ report_kvs[:LineNumber] = __LINE__
61
+ rescue StandardError => e
62
+ AppOpticsAPM.logger.debug "[appoptics_apm/padrino] #{e.message}"
63
+ AppOpticsAPM.logger.debug e.backtrace.join(', ')
64
+ end
65
+
66
+ AppOpticsAPM::API.profile(report_kvs[:template], report_kvs, false) do
67
+ render_without_appoptics(engine, data, options, locals, &block)
68
+ end
69
+ else
70
+ # Fall back to the raw tracing API so we can pass KVs
71
+ # back on exit (a limitation of the AppOpticsAPM::API.trace
72
+ # block method) This removes the need for an info
73
+ # event to send additonal KVs
74
+ AppOpticsAPM::API.log_entry(:render, {}, :render)
75
+
76
+ begin
77
+ render_without_appoptics(engine, data, options, locals, &block)
78
+ ensure
79
+ report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:padrino][:collect_backtraces]
80
+ AppOpticsAPM::API.log_exit(:render, report_kvs)
81
+ end
82
+ end
83
+ else
84
+ render_without_appoptics(engine, data, options, locals, &block)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ if defined?(Padrino) && AppopticsAPM::Config[:padrino][:enabled]
92
+ # This instrumentation is a superset of the Sinatra instrumentation similar
93
+ # to how Padrino is a superset of Sinatra itself.
94
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting Padrino' if AppOpticsAPM::Config[:verbose]
95
+
96
+ Padrino.after_load do
97
+ AppOpticsAPM.logger = Padrino.logger if Padrino.respond_to?(:logger)
98
+ AppOpticsAPM::Inst.load_instrumentation
99
+
100
+ AppOpticsAPM::Util.send_include(Padrino::Routing::InstanceMethods, AppOpticsAPM::PadrinoInst::Routing)
101
+ if defined?(Padrino::Rendering)
102
+ AppOpticsAPM::Util.send_include(Padrino::Rendering::InstanceMethods, AppOpticsAPM::PadrinoInst::Rendering)
103
+ end
104
+
105
+ # Report __Init after fork when in Heroku
106
+ AppOpticsAPM::API.report_init unless AppOpticsAPM.heroku?
107
+ end
108
+ end
@@ -0,0 +1,94 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module AppOpticsAPM
5
+ module Rails
6
+ module Helpers
7
+ extend ActiveSupport::Concern if defined?(::Rails) and ::Rails::VERSION::MAJOR > 2
8
+
9
+ # Deprecated
10
+ # no usages
11
+ def appoptics_rum_header
12
+ AppOpticsAPM.logger.warn '[appoptics_apm/warn] Note that appoptics_rum_header is deprecated. It is now a no-op and should be removed from your application code.'
13
+ return ''
14
+ end
15
+ alias_method :oboe_rum_header, :appoptics_rum_header
16
+
17
+ # Deprecated
18
+ def appoptics_rum_footer
19
+ AppOpticsAPM.logger.warn '[appoptics_apm/warn] Note that appoptics_rum_footer is deprecated. It is now a no-op and should be removed from your application code.'
20
+ return ''
21
+ end
22
+ alias_method :oboe_rum_footer, :appoptics_rum_footer
23
+ end # Helpers
24
+
25
+ def self.load_initializer
26
+ # Force load the AppOpticsAPM Rails initializer if there is one
27
+ # Prefer appoptics_apm.rb but give priority to the legacy tracelytics.rb if it exists
28
+ if ::Rails::VERSION::MAJOR > 2
29
+ rails_root = ::Rails.root.to_s
30
+ else
31
+ rails_root = RAILS_ROOT.to_s
32
+ end
33
+
34
+ #
35
+ # We've been through 3 initializer names. Try each one.
36
+ #
37
+ if File.exist?("#{rails_root}/config/initializers/tracelytics.rb")
38
+ tr_initializer = "#{rails_root}/config/initializers/tracelytics.rb"
39
+ elsif File.exist?("#{rails_root}/config/initializers/oboe.rb")
40
+ tr_initializer = "#{rails_root}/config/initializers/oboe.rb"
41
+ else
42
+ tr_initializer = "#{rails_root}/config/initializers/appoptics_apm.rb"
43
+ end
44
+ require tr_initializer if File.exist?(tr_initializer)
45
+ end
46
+
47
+ def self.load_instrumentation
48
+ # Load the Rails specific instrumentation
49
+ require 'appoptics_apm/frameworks/rails/inst/action_controller'
50
+ require 'appoptics_apm/frameworks/rails/inst/action_view'
51
+ require 'appoptics_apm/frameworks/rails/inst/action_view_30'
52
+ require 'appoptics_apm/frameworks/rails/inst/active_record'
53
+
54
+ AppOpticsAPM.logger.info "[appoptics_apm/rails] AppOpticsAPM gem #{AppOpticsAPM::Version::STRING} successfully loaded."
55
+ end
56
+
57
+ def self.include_helpers
58
+ # TBD: This would make the helpers available to controllers which is occasionally desired.
59
+ # ActiveSupport.on_load(:action_controller) do
60
+ # include AppOpticsAPM::Rails::Helpers
61
+ # end
62
+ ActiveSupport.on_load(:action_view) do
63
+ include AppOpticsAPM::Rails::Helpers
64
+ end
65
+ end
66
+ end # Rails
67
+ end # AppOpticsAPM
68
+
69
+ if defined?(::Rails)
70
+ require 'appoptics_apm/inst/rack'
71
+
72
+ module AppOpticsAPM
73
+ class Railtie < ::Rails::Railtie
74
+ initializer 'appoptics_apm.helpers' do
75
+ AppOpticsAPM::Rails.include_helpers
76
+ end
77
+
78
+ initializer 'appoptics_apm.rack' do |app|
79
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting rack' if AppOpticsAPM::Config[:verbose]
80
+ app.config.middleware.insert 0, AppOpticsAPM::Rack
81
+ end
82
+
83
+ config.after_initialize do
84
+ AppOpticsAPM.logger = ::Rails.logger if ::Rails.logger && !ENV.key?('APPOPTICS_GEM_TEST')
85
+
86
+ AppOpticsAPM::Inst.load_instrumentation
87
+ AppOpticsAPM::Rails.load_instrumentation
88
+
89
+ # Report __Init after fork when in Heroku
90
+ AppOpticsAPM::API.report_init unless AppOpticsAPM.heroku?
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,104 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module AppOpticsAPM
5
+ module Inst
6
+ #
7
+ # RailsBase
8
+ #
9
+ # This module contains the instrumentation code common to
10
+ # many Rails versions.
11
+ #
12
+ module RailsBase
13
+
14
+ #
15
+ # has_handler?
16
+ #
17
+ # Determins if <tt>exception</tt> has a registered
18
+ # handler via <tt>rescue_from</tt>
19
+ #
20
+ def has_handler?(exception)
21
+ # Don't log exceptions if they have a rescue handler set
22
+ has_handler = false
23
+ rescue_handlers.detect do |klass_name, _handler|
24
+ # Rescue handlers can be specified as strings or constant names
25
+ klass = self.class.const_get(klass_name) rescue nil
26
+ klass ||= klass_name.constantize rescue nil
27
+ has_handler = exception.is_a?(klass) if klass
28
+ end
29
+ has_handler
30
+ rescue => e
31
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] Error searching Rails handlers: #{e.message}"
32
+ return false
33
+ end
34
+
35
+ #
36
+ # log_rails_error?
37
+ #
38
+ # Determins whether we should log a raised exception to the
39
+ # AppOptics dashboard. This is determined by whether the exception
40
+ # has a rescue handler setup and the value of
41
+ # AppOpticsAPM::Config[:report_rescued_errors]
42
+ #
43
+ def log_rails_error?(exception)
44
+ # As it's perculating up through the layers... make sure that
45
+ # we only report it once.
46
+ return false if exception.instance_variable_get(:@exn_logged)
47
+
48
+ return false if has_handler?(exception) && !AppOpticsAPM::Config[:report_rescued_errors]
49
+
50
+ true
51
+ end
52
+
53
+ ##
54
+ # This method does the logging if we are tracing
55
+ # it `wraps` around the call to the original method
56
+ #
57
+ # This can't use the SDK trace() method because of the log_rails_error?(e) condition
58
+ def trace(layer)
59
+ return yield unless AppOpticsAPM.tracing?
60
+ begin
61
+ AppOpticsAPM::API.log_entry(layer)
62
+ yield
63
+ rescue Exception => e
64
+ AppOpticsAPM::API.log_exception(layer, e) if log_rails_error?(e)
65
+ raise
66
+ ensure
67
+ AppOpticsAPM::API.log_exit(layer)
68
+ end
69
+ end
70
+
71
+
72
+ #
73
+ # render_with_appoptics
74
+ #
75
+ # Our render wrapper that calls 'add_logging', which will log if we are tracing
76
+ #
77
+ def render_with_appoptics(*args, &blk)
78
+ trace('actionview') do
79
+ render_without_appoptics(*args, &blk)
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ # ActionController::Base
87
+ if defined?(ActionController::Base) && AppOpticsAPM::Config[:action_controller][:enabled]
88
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting actioncontroller' if AppOpticsAPM::Config[:verbose]
89
+ require "appoptics_apm/frameworks/rails/inst/action_controller#{Rails::VERSION::MAJOR}"
90
+ if Rails::VERSION::MAJOR >= 5
91
+ ActionController::Base.send(:prepend, ::AppOpticsAPM::Inst::ActionController)
92
+ else
93
+ AppOpticsAPM::Util.send_include(::ActionController::Base, AppOpticsAPM::Inst::ActionController)
94
+ end
95
+ end
96
+
97
+ # ActionController::API - Rails 5+ or via the rails-api gem
98
+ if defined?(ActionController::API) && AppOpticsAPM::Config[:action_controller_api][:enabled]
99
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting actioncontroller api' if AppOpticsAPM::Config[:verbose]
100
+ require "appoptics_apm/frameworks/rails/inst/action_controller_api"
101
+ ActionController::API.send(:prepend, ::AppOpticsAPM::Inst::ActionControllerAPI)
102
+ end
103
+
104
+ # vim:set expandtab:tabstop=2
@@ -0,0 +1,55 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module AppOpticsAPM
5
+ module Inst
6
+ #
7
+ # ActionController
8
+ #
9
+ # This modules contains the instrumentation code specific
10
+ # to Rails v3
11
+ #
12
+ module ActionController
13
+ include AppOpticsAPM::Inst::RailsBase
14
+
15
+ def self.included(base)
16
+ base.class_eval do
17
+ alias_method_chain :process, :appoptics
18
+ alias_method_chain :process_action, :appoptics
19
+ alias_method_chain :render, :appoptics
20
+ end
21
+ end
22
+
23
+ def process_with_appoptics(*args)
24
+ request.env['appoptics_apm.controller'] = self.class.name
25
+ request.env['appoptics_apm.action'] = self.action_name
26
+
27
+ trace('rails') do
28
+ process_without_appoptics(*args)
29
+ end
30
+ end
31
+
32
+ def process_action_with_appoptics(*args)
33
+ kvs = {
34
+ :Controller => self.class.name,
35
+ :Action => action_name,
36
+ }
37
+ request.env['appoptics_apm.controller'] = kvs[:Controller]
38
+ request.env['appoptics_apm.action'] = kvs[:Action]
39
+
40
+ return process_action_without_appoptics(*args) unless AppOpticsAPM.tracing?
41
+ begin
42
+ kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:action_controller][:collect_backtraces]
43
+ AppOpticsAPM::API.log(nil, 'info', kvs)
44
+
45
+ process_action_without_appoptics(*args)
46
+ rescue Exception
47
+ kvs[:Status] = 500
48
+ kvs.delete(:Backtrace)
49
+ AppOpticsAPM::API.log(nil, 'info', kvs)
50
+ raise
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end