appoptics_apm-zearn 4.13.1

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 (145) 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/.github/workflows/build_and_release_gem.yml +103 -0
  5. data/.github/workflows/build_for_packagecloud.yml +70 -0
  6. data/.github/workflows/docker-images.yml +47 -0
  7. data/.github/workflows/run_cpluplus_tests.yml +73 -0
  8. data/.github/workflows/run_tests.yml +168 -0
  9. data/.github/workflows/scripts/test_install.rb +23 -0
  10. data/.github/workflows/swig/swig-v4.0.2.tar.gz +0 -0
  11. data/.github/workflows/test_on_4_linux.yml +159 -0
  12. data/.gitignore +36 -0
  13. data/.rubocop.yml +29 -0
  14. data/.travis.yml +130 -0
  15. data/.yardopts +6 -0
  16. data/CHANGELOG.md +769 -0
  17. data/CONFIG.md +33 -0
  18. data/Gemfile +14 -0
  19. data/LICENSE +202 -0
  20. data/README.md +393 -0
  21. data/appoptics_apm.gemspec +70 -0
  22. data/bin/appoptics_apm_config +15 -0
  23. data/examples/prepend.rb +13 -0
  24. data/examples/sdk_examples.rb +158 -0
  25. data/ext/oboe_metal/README.md +69 -0
  26. data/ext/oboe_metal/extconf.rb +151 -0
  27. data/ext/oboe_metal/lib/.keep +0 -0
  28. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256 +1 -0
  29. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256 +1 -0
  30. data/ext/oboe_metal/noop/noop.c +8 -0
  31. data/ext/oboe_metal/src/README.md +6 -0
  32. data/ext/oboe_metal/src/VERSION +2 -0
  33. data/ext/oboe_metal/src/bson/bson.h +220 -0
  34. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  35. data/ext/oboe_metal/src/frames.cc +246 -0
  36. data/ext/oboe_metal/src/frames.h +40 -0
  37. data/ext/oboe_metal/src/init_appoptics_apm.cc +21 -0
  38. data/ext/oboe_metal/src/logging.cc +95 -0
  39. data/ext/oboe_metal/src/logging.h +35 -0
  40. data/ext/oboe_metal/src/oboe.h +1156 -0
  41. data/ext/oboe_metal/src/oboe_api.cpp +652 -0
  42. data/ext/oboe_metal/src/oboe_api.hpp +431 -0
  43. data/ext/oboe_metal/src/oboe_debug.h +59 -0
  44. data/ext/oboe_metal/src/oboe_swig_wrap.cc +7329 -0
  45. data/ext/oboe_metal/src/profiling.cc +435 -0
  46. data/ext/oboe_metal/src/profiling.h +78 -0
  47. data/ext/oboe_metal/test/CMakeLists.txt +53 -0
  48. data/ext/oboe_metal/test/FindGMock.cmake +43 -0
  49. data/ext/oboe_metal/test/README.md +56 -0
  50. data/ext/oboe_metal/test/frames_test.cc +164 -0
  51. data/ext/oboe_metal/test/profiling_test.cc +93 -0
  52. data/ext/oboe_metal/test/ruby_inc_dir.rb +8 -0
  53. data/ext/oboe_metal/test/ruby_prefix.rb +8 -0
  54. data/ext/oboe_metal/test/ruby_test_helper.rb +67 -0
  55. data/ext/oboe_metal/test/test.h +11 -0
  56. data/ext/oboe_metal/test/test_main.cc +32 -0
  57. data/init.rb +4 -0
  58. data/lib/appoptics_apm/api/layerinit.rb +41 -0
  59. data/lib/appoptics_apm/api/logging.rb +381 -0
  60. data/lib/appoptics_apm/api/memcache.rb +37 -0
  61. data/lib/appoptics_apm/api/metrics.rb +63 -0
  62. data/lib/appoptics_apm/api/tracing.rb +57 -0
  63. data/lib/appoptics_apm/api/util.rb +120 -0
  64. data/lib/appoptics_apm/api.rb +21 -0
  65. data/lib/appoptics_apm/base.rb +231 -0
  66. data/lib/appoptics_apm/config.rb +299 -0
  67. data/lib/appoptics_apm/frameworks/grape.rb +98 -0
  68. data/lib/appoptics_apm/frameworks/padrino.rb +78 -0
  69. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -0
  70. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  71. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  72. data/lib/appoptics_apm/frameworks/rails/inst/action_controller6.rb +50 -0
  73. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  74. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +88 -0
  75. data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
  76. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  77. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +29 -0
  78. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +31 -0
  79. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +119 -0
  80. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +114 -0
  81. data/lib/appoptics_apm/frameworks/rails/inst/logger_formatters.rb +27 -0
  82. data/lib/appoptics_apm/frameworks/rails.rb +100 -0
  83. data/lib/appoptics_apm/frameworks/sinatra.rb +96 -0
  84. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  85. data/lib/appoptics_apm/inst/bunny-consumer.rb +89 -0
  86. data/lib/appoptics_apm/inst/curb.rb +332 -0
  87. data/lib/appoptics_apm/inst/dalli.rb +85 -0
  88. data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
  89. data/lib/appoptics_apm/inst/em-http-request.rb +101 -0
  90. data/lib/appoptics_apm/inst/excon.rb +125 -0
  91. data/lib/appoptics_apm/inst/faraday.rb +106 -0
  92. data/lib/appoptics_apm/inst/graphql.rb +240 -0
  93. data/lib/appoptics_apm/inst/grpc_client.rb +159 -0
  94. data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
  95. data/lib/appoptics_apm/inst/http.rb +81 -0
  96. data/lib/appoptics_apm/inst/httpclient.rb +174 -0
  97. data/lib/appoptics_apm/inst/logger_formatter.rb +50 -0
  98. data/lib/appoptics_apm/inst/logging_log_event.rb +28 -0
  99. data/lib/appoptics_apm/inst/lumberjack_formatter.rb +13 -0
  100. data/lib/appoptics_apm/inst/memcached.rb +86 -0
  101. data/lib/appoptics_apm/inst/mongo.rb +246 -0
  102. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  103. data/lib/appoptics_apm/inst/moped.rb +466 -0
  104. data/lib/appoptics_apm/inst/rack.rb +182 -0
  105. data/lib/appoptics_apm/inst/rack_cache.rb +35 -0
  106. data/lib/appoptics_apm/inst/redis.rb +274 -0
  107. data/lib/appoptics_apm/inst/resque.rb +151 -0
  108. data/lib/appoptics_apm/inst/rest-client.rb +48 -0
  109. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  110. data/lib/appoptics_apm/inst/sidekiq-client.rb +55 -0
  111. data/lib/appoptics_apm/inst/sidekiq-worker.rb +66 -0
  112. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  113. data/lib/appoptics_apm/inst/typhoeus.rb +108 -0
  114. data/lib/appoptics_apm/instrumentation.rb +22 -0
  115. data/lib/appoptics_apm/loading.rb +65 -0
  116. data/lib/appoptics_apm/logger.rb +14 -0
  117. data/lib/appoptics_apm/noop/README.md +9 -0
  118. data/lib/appoptics_apm/noop/context.rb +27 -0
  119. data/lib/appoptics_apm/noop/metadata.rb +25 -0
  120. data/lib/appoptics_apm/noop/profiling.rb +21 -0
  121. data/lib/appoptics_apm/oboe_init_options.rb +211 -0
  122. data/lib/appoptics_apm/ruby.rb +35 -0
  123. data/lib/appoptics_apm/sdk/current_trace.rb +77 -0
  124. data/lib/appoptics_apm/sdk/custom_metrics.rb +94 -0
  125. data/lib/appoptics_apm/sdk/logging.rb +37 -0
  126. data/lib/appoptics_apm/sdk/tracing.rb +434 -0
  127. data/lib/appoptics_apm/support/profiling.rb +18 -0
  128. data/lib/appoptics_apm/support/transaction_metrics.rb +67 -0
  129. data/lib/appoptics_apm/support/transaction_settings.rb +219 -0
  130. data/lib/appoptics_apm/support/x_trace_options.rb +110 -0
  131. data/lib/appoptics_apm/support_report.rb +119 -0
  132. data/lib/appoptics_apm/test.rb +95 -0
  133. data/lib/appoptics_apm/thread_local.rb +26 -0
  134. data/lib/appoptics_apm/util.rb +326 -0
  135. data/lib/appoptics_apm/version.rb +16 -0
  136. data/lib/appoptics_apm/xtrace.rb +115 -0
  137. data/lib/appoptics_apm.rb +77 -0
  138. data/lib/joboe_metal.rb +212 -0
  139. data/lib/oboe.rb +7 -0
  140. data/lib/oboe_metal.rb +172 -0
  141. data/lib/rails/generators/appoptics_apm/install_generator.rb +47 -0
  142. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +425 -0
  143. data/log/.keep +0 -0
  144. data/yardoc_frontpage.md +26 -0
  145. metadata +231 -0
@@ -0,0 +1,114 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module AppOpticsAPM
5
+ module Inst
6
+ module ConnectionAdapters
7
+ module Utils
8
+
9
+ def extract_trace_details(sql, name = nil, binds = [])
10
+ opts = {}
11
+
12
+ begin
13
+ if AppOpticsAPM::Config[:sanitize_sql]
14
+ # Sanitize SQL and don't report binds
15
+ opts[:Query] = AppOpticsAPM::Util.sanitize_sql(sql)
16
+ else
17
+ # Report raw SQL and any binds if they exist
18
+ opts[:Query] = sql.to_s
19
+ if binds && !binds.empty?
20
+ opts[:QueryArgs] = binds.map(&:value)
21
+ end
22
+ end
23
+
24
+ opts[:Name] = name.to_s if name
25
+ if AppOpticsAPM::Config[:active_record] && AppOpticsAPM::Config[:active_record][:collect_backtraces]
26
+ opts[:Backtrace] = AppOpticsAPM::API.backtrace
27
+ end
28
+
29
+ if ActiveRecord::Base.respond_to?(:connection_db_config)
30
+ # Rails 6.1++ deprecates connection_config
31
+ config = ActiveRecord::Base.connection_db_config.configuration_hash
32
+ else
33
+ config = ActiveRecord::Base.connection_config
34
+ end
35
+
36
+ if config
37
+ opts[:Database] = config[:database] if config.key?(:database)
38
+ opts[:RemoteHost] = config[:host] if config.key?(:host)
39
+ adapter_name = config[:adapter]
40
+
41
+ case adapter_name
42
+ when /mysql/i
43
+ opts[:Flavor] = 'mysql'
44
+ when /^postgres|^postgis/i
45
+ opts[:Flavor] = 'postgresql'
46
+ end
47
+ end
48
+ rescue StandardError => e
49
+ AppOpticsAPM.logger.debug "[appoptics_apm/rails] Exception raised capturing ActiveRecord KVs: #{e.inspect}"
50
+ AppOpticsAPM.logger.debug e.backtrace.join('\n')
51
+ end
52
+
53
+ opts
54
+ end
55
+
56
+ # We don't want to trace framework caches. Only instrument SQL that
57
+ # directly hits the database.
58
+ def ignore_payload?(name)
59
+ %w(SCHEMA EXPLAIN CACHE).include?(name.to_s) ||
60
+ (name && name.to_sym == :skip_logging) ||
61
+ name == 'ActiveRecord::SchemaMigration Load'
62
+ end
63
+
64
+ def exec_query_with_appoptics(sql, name = nil, binds = [], prepare: false)
65
+ if AppOpticsAPM.tracing? && !AppOpticsAPM.tracing_layer_op?(:ar_started) && !ignore_payload?(name)
66
+
67
+ opts = extract_trace_details(sql, name, binds)
68
+ AppOpticsAPM::API.trace('activerecord', opts) do
69
+ exec_query_without_appoptics(sql, name, binds)
70
+ end
71
+ else
72
+ exec_query_without_appoptics(sql, name, binds)
73
+ end
74
+ end
75
+
76
+ def exec_insert_with_appoptics(sql, name = nil, binds = [], *args)
77
+ if AppOpticsAPM.tracing? && !ignore_payload?(name)
78
+
79
+ opts = extract_trace_details(sql, name, binds)
80
+ AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
81
+ exec_insert_without_appoptics(sql, name, binds, *args)
82
+ end
83
+ else
84
+ exec_insert_without_appoptics(sql, name, binds, *args)
85
+ end
86
+ end
87
+
88
+ def exec_delete_with_appoptics(sql, name = nil, binds = [])
89
+ if AppOpticsAPM.tracing? && !ignore_payload?(name)
90
+
91
+ opts = extract_trace_details(sql, name, binds)
92
+ AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
93
+ exec_delete_without_appoptics(sql, name, binds)
94
+ end
95
+ else
96
+ exec_delete_without_appoptics(sql, name, binds)
97
+ end
98
+ end
99
+
100
+ def exec_update_with_appoptics(sql, name = nil, binds = [])
101
+ if AppOpticsAPM.tracing? && !ignore_payload?(name)
102
+
103
+ opts = extract_trace_details(sql, name, binds)
104
+ AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
105
+ exec_update_without_appoptics(sql, name, binds)
106
+ end
107
+ else
108
+ exec_update_without_appoptics(sql, name, binds)
109
+ end
110
+ end
111
+ end # Utils
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (c) 2019 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ if AppOpticsAPM.loaded && defined?(ActiveSupport::Logger::SimpleFormatter)
5
+ module ActiveSupport
6
+ class Logger
7
+ class SimpleFormatter
8
+ # even though SimpleFormatter inherits from Logger,
9
+ # this will not append traceId twice,
10
+ # because SimpleFormatter#call does not call super
11
+ prepend AppOpticsAPM::Logger::Formatter
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+
18
+ if AppOpticsAPM.loaded && defined?(ActiveSupport::TaggedLogging::Formatter)
19
+ module ActiveSupport
20
+ module TaggedLogging
21
+ module Formatter
22
+ # TODO figure out ancestors situation
23
+ prepend AppOpticsAPM::Logger::Formatter
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,100 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require_relative '../../../lib/appoptics_apm/inst/logger_formatter'
5
+
6
+ module AppOpticsAPM
7
+ module Rails
8
+ module Helpers
9
+ extend ActiveSupport::Concern if defined?(::Rails) and ::Rails::VERSION::MAJOR > 2
10
+
11
+ # Deprecated
12
+ # no usages
13
+ def appoptics_rum_header
14
+ 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.'
15
+ return ''
16
+ end
17
+ alias_method :oboe_rum_header, :appoptics_rum_header
18
+
19
+ # Deprecated
20
+ def appoptics_rum_footer
21
+ 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.'
22
+ return ''
23
+ end
24
+ alias_method :oboe_rum_footer, :appoptics_rum_footer
25
+ end # Helpers
26
+
27
+ def self.load_initializer
28
+ # Force load the AppOpticsAPM Rails initializer if there is one
29
+ # Prefer appoptics_apm.rb but give priority to the legacy tracelytics.rb if it exists
30
+ if ::Rails::VERSION::MAJOR > 2
31
+ rails_root = ::Rails.root.to_s
32
+ else
33
+ rails_root = RAILS_ROOT.to_s
34
+ end
35
+
36
+ #
37
+ # We've been through 3 initializer names. Try each one.
38
+ #
39
+ if File.exist?("#{rails_root}/config/initializers/tracelytics.rb")
40
+ tr_initializer = "#{rails_root}/config/initializers/tracelytics.rb"
41
+ elsif File.exist?("#{rails_root}/config/initializers/oboe.rb")
42
+ tr_initializer = "#{rails_root}/config/initializers/oboe.rb"
43
+ else
44
+ tr_initializer = "#{rails_root}/config/initializers/appoptics_apm.rb"
45
+ end
46
+ require tr_initializer if File.exist?(tr_initializer)
47
+ end
48
+
49
+ def self.load_instrumentation
50
+ # Load the Rails specific instrumentation
51
+ require 'appoptics_apm/frameworks/rails/inst/action_controller'
52
+ require 'appoptics_apm/frameworks/rails/inst/action_view'
53
+ require 'appoptics_apm/frameworks/rails/inst/active_record'
54
+ require 'appoptics_apm/frameworks/rails/inst/logger_formatters'
55
+
56
+ AppOpticsAPM.logger.info "[appoptics_apm/rails] AppOpticsAPM gem #{AppOpticsAPM::Version::STRING} successfully loaded."
57
+ end
58
+
59
+ def self.include_helpers
60
+ # TBD: This would make the helpers available to controllers which is occasionally desired.
61
+ # ActiveSupport.on_load(:action_controller) do
62
+ # include AppOpticsAPM::Rails::Helpers
63
+ # end
64
+ ActiveSupport.on_load(:action_view) do
65
+ include AppOpticsAPM::Rails::Helpers
66
+ end
67
+ end
68
+ end # Rails
69
+ end # AppOpticsAPM
70
+
71
+ if defined?(::Rails)
72
+ require 'appoptics_apm/inst/rack'
73
+
74
+ module AppOpticsAPM
75
+ class Railtie < ::Rails::Railtie
76
+ initializer 'appoptics_apm.helpers' do
77
+ AppOpticsAPM::Rails.include_helpers
78
+ end
79
+
80
+ initializer 'appoptics_apm.controller', before: 'wicked_pdf.register' do
81
+ AppOpticsAPM::Rails.load_instrumentation
82
+ end
83
+
84
+ initializer 'appoptics_apm.rack' do |app|
85
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting rack' if AppOpticsAPM::Config[:verbose]
86
+ app.config.middleware.insert 0, AppOpticsAPM::Rack
87
+ end
88
+
89
+ config.after_initialize do
90
+ AppOpticsAPM.logger = ::Rails.logger if ::Rails.logger && !ENV.key?('APPOPTICS_GEM_TEST')
91
+
92
+ AppOpticsAPM::Inst.load_instrumentation
93
+ # AppOpticsAPM::Rails.load_instrumentation
94
+
95
+ # Report __Init after fork when in Heroku
96
+ AppOpticsAPM::API.report_init unless AppOpticsAPM.heroku?
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,96 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module AppOpticsAPM
5
+ module Sinatra
6
+ module Base
7
+ def self.included(klass)
8
+ AppOpticsAPM::Util.method_alias(klass, :dispatch!, ::Sinatra::Base)
9
+ AppOpticsAPM::Util.method_alias(klass, :handle_exception!, ::Sinatra::Base)
10
+ end
11
+
12
+ def dispatch_with_appoptics
13
+
14
+ AppOpticsAPM::API.log_entry('sinatra', {})
15
+
16
+ response = dispatch_without_appoptics
17
+
18
+ # Report Controller/Action and transaction as best possible
19
+ report_kvs = {}
20
+ report_kvs[:Controller] = self.class
21
+ report_kvs[:Action] = env['sinatra.route']
22
+ env['appoptics_apm.controller'] = report_kvs[:Controller]
23
+ env['appoptics_apm.action'] = report_kvs[:Action]
24
+
25
+ response
26
+ rescue => e
27
+ AppOpticsAPM::API.log_exception('sinatra', e)
28
+ raise e
29
+ ensure
30
+ report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:sinatra][:collect_backtraces]
31
+ AppOpticsAPM::API.log_exit('sinatra', report_kvs)
32
+ end
33
+
34
+ def handle_exception_with_appoptics(boom)
35
+ AppOpticsAPM::API.log_exception(:sinatra, boom)
36
+ handle_exception_without_appoptics(boom)
37
+ end
38
+
39
+ def appoptics_rum_header
40
+ 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.'
41
+ return ''
42
+ end
43
+ alias_method :oboe_rum_header, :appoptics_rum_header
44
+
45
+ def appoptics_rum_footer
46
+ 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.'
47
+ return ''
48
+ end
49
+ alias_method :oboe_rum_footer, :appoptics_rum_footer
50
+ end
51
+
52
+ module Templates
53
+ def self.included(klass)
54
+ AppOpticsAPM::Util.method_alias(klass, :render, ::Sinatra::Templates)
55
+ end
56
+
57
+ def render_with_appoptics(engine, data, options = {}, locals = {}, &block)
58
+ if AppOpticsAPM.tracing?
59
+ report_kvs = {}
60
+
61
+ report_kvs[:engine] = engine
62
+ report_kvs[:template] = data
63
+
64
+ AppOpticsAPM::SDK.trace(:sinatra_render, report_kvs, :sinatra_render) do
65
+ report_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:sinatra][:collect_backtraces]
66
+ render_without_appoptics(engine, data, options, locals, &block)
67
+ end
68
+ else
69
+ render_without_appoptics(engine, data, options, locals, &block)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ if defined?(Sinatra) && AppOpticsAPM::Config[:sinatra][:enabled]
77
+ require 'appoptics_apm/inst/rack'
78
+
79
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting Sinatra' if AppOpticsAPM::Config[:verbose]
80
+
81
+ AppOpticsAPM::Inst.load_instrumentation
82
+
83
+ Sinatra::Base.use AppOpticsAPM::Rack
84
+
85
+ # When in the gem TEST environment, we load this instrumentation regardless.
86
+ # Otherwise, only when Padrino isn't around.
87
+ unless defined?(Padrino) && !ENV.key?('APPOPTICS_GEM_TEST')
88
+ # Padrino has 'enhanced' routes and rendering so the Sinatra
89
+ # instrumentation won't work anyways. Only load for pure Sinatra apps.
90
+ AppOpticsAPM::Util.send_include(Sinatra::Base, AppOpticsAPM::Sinatra::Base)
91
+ AppOpticsAPM::Util.send_include(Sinatra::Templates, AppOpticsAPM::Sinatra::Templates)
92
+
93
+ # Report __Init after fork when in Heroku
94
+ AppOpticsAPM::API.report_init unless AppOpticsAPM.heroku?
95
+ end
96
+ end
@@ -0,0 +1,148 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module AppOpticsAPM
5
+ module Inst
6
+ module BunnyExchange
7
+ def self.included(klass)
8
+ AppOpticsAPM::Util.method_alias(klass, :delete, ::Bunny::Exchange)
9
+ end
10
+
11
+ def delete_with_appoptics(opts = {})
12
+ # If we're not tracing, just do a fast return.
13
+ return delete_without_appoptics(opts) if !AppOpticsAPM.tracing?
14
+
15
+ begin
16
+ kvs = {}
17
+ kvs[:Spec] = :pushq
18
+ kvs[:Flavor] = :rabbitmq
19
+ kvs[:Op] = :delete
20
+ kvs[:ExchangeType] = @type
21
+ kvs[:RemoteHost] = channel.connection.host
22
+ kvs[:RemotePort] = channel.connection.port.to_i
23
+ kvs[:VirtualHost] = channel.connection.vhost
24
+
25
+ if @name.is_a?(String) && !@name.empty?
26
+ kvs[:ExchangeName] = @name
27
+ else
28
+ kvs[:ExchangeName] = :default
29
+ end
30
+
31
+ AppOpticsAPM::API.log_entry(:'rabbitmq-client')
32
+ delete_without_appoptics(opts)
33
+ rescue => e
34
+ AppOpticsAPM::API.log_exception(:'rabbitmq-client', e)
35
+ raise e
36
+ ensure
37
+ kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:bunnyclient][:collect_backtraces]
38
+ AppOpticsAPM::API.log_exit(:'rabbitmq-client', kvs)
39
+ end
40
+ end
41
+ end
42
+
43
+ module BunnyChannel
44
+ def self.included(klass)
45
+ AppOpticsAPM::Util.method_alias(klass, :basic_publish, ::Bunny::Channel)
46
+ AppOpticsAPM::Util.method_alias(klass, :queue, ::Bunny::Channel)
47
+ AppOpticsAPM::Util.method_alias(klass, :wait_for_confirms, ::Bunny::Channel)
48
+ end
49
+
50
+ def collect_channel_kvs
51
+ kvs = {}
52
+ kvs[:Spec] = :pushq
53
+ kvs[:Flavor] = :rabbitmq
54
+ kvs[:RemoteHost] = @connection.host
55
+ kvs[:RemotePort] = @connection.port.to_i
56
+ kvs[:VirtualHost] = @connection.vhost
57
+ kvs
58
+ rescue => e
59
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
60
+ ensure
61
+ return kvs
62
+ end
63
+
64
+ def basic_publish_with_appoptics(payload, exchange, routing_key, opts = {})
65
+ # If we're not tracing, just do a fast return.
66
+ return basic_publish_without_appoptics(payload, exchange, routing_key, opts) if !AppOpticsAPM.tracing?
67
+
68
+ begin
69
+ kvs = collect_channel_kvs
70
+
71
+ if exchange.respond_to?(:name)
72
+ kvs[:ExchangeName] = exchange.name
73
+ elsif exchange.respond_to?(:empty?) && !exchange.empty?
74
+ kvs[:ExchangeName] = exchange
75
+ else
76
+ kvs[:ExchangeName] = :default
77
+ end
78
+
79
+ kvs[:Queue] = opts[:queue] if opts.key?(:queue)
80
+ kvs[:RoutingKey] = routing_key if routing_key
81
+ kvs[:Op] = :publish
82
+
83
+ AppOpticsAPM::API.log_entry(:'rabbitmq-client')
84
+
85
+ # Pass the tracing context as a header
86
+ opts[:headers] ||= {}
87
+ opts[:headers][:SourceTrace] = AppOpticsAPM::Context.toString if AppOpticsAPM.tracing?
88
+
89
+ basic_publish_without_appoptics(payload, exchange, routing_key, opts)
90
+ rescue => e
91
+ AppOpticsAPM::API.log_exception(:'rabbitmq-client', e)
92
+ raise e
93
+ ensure
94
+ kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:bunnyclient][:collect_backtraces]
95
+ AppOpticsAPM::API.log_exit(:'rabbitmq-client', kvs)
96
+ end
97
+ end
98
+
99
+ def queue_with_appoptics(name = AMQ::Protocol::EMPTY_STRING, opts = {})
100
+ # If we're not tracing, just do a fast return.
101
+ return queue_without_appoptics(name, opts) if !AppOpticsAPM.tracing?
102
+
103
+ begin
104
+ kvs = collect_channel_kvs
105
+ kvs[:Op] = :queue
106
+
107
+ AppOpticsAPM::API.log_entry(:'rabbitmq-client')
108
+
109
+ result = queue_without_appoptics(name, opts)
110
+ kvs[:Queue] = result.name
111
+ result
112
+ rescue => e
113
+ AppOpticsAPM::API.log_exception(:'rabbitmq-client', e)
114
+ raise e
115
+ ensure
116
+ kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:bunnyclient][:collect_backtraces]
117
+ AppOpticsAPM::API.log_exit(:'rabbitmq-client', kvs)
118
+ end
119
+ end
120
+
121
+ def wait_for_confirms_with_appoptics
122
+ # If we're not tracing, just do a fast return.
123
+ return wait_for_confirms_without_appoptics if !AppOpticsAPM.tracing?
124
+
125
+ begin
126
+ kvs = collect_channel_kvs
127
+ kvs[:Op] = :wait_for_confirms
128
+
129
+ AppOpticsAPM::API.log_entry(:'rabbitmq-client')
130
+
131
+ wait_for_confirms_without_appoptics
132
+ rescue => e
133
+ AppOpticsAPM::API.log_exception(:'rabbitmq-client', e)
134
+ raise e
135
+ ensure
136
+ kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:bunnyclient][:collect_backtraces]
137
+ AppOpticsAPM::API.log_exit(:'rabbitmq-client', kvs)
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ if defined?(Bunny) && AppOpticsAPM::Config[:bunnyclient][:enabled]
145
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting bunny client' if AppOpticsAPM::Config[:verbose]
146
+ AppOpticsAPM::Util.send_include(Bunny::Exchange, AppOpticsAPM::Inst::BunnyExchange)
147
+ AppOpticsAPM::Util.send_include(Bunny::Channel, AppOpticsAPM::Inst::BunnyChannel)
148
+ end
@@ -0,0 +1,89 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module AppOpticsAPM
5
+ module Inst
6
+ module BunnyConsumer
7
+ def self.included(klass)
8
+ AppOpticsAPM::Util.method_alias(klass, :call, ::Bunny::Consumer)
9
+ end
10
+
11
+ def collect_consumer_kvs(args)
12
+ kvs = {}
13
+ kvs[:Spec] = :job
14
+ kvs[:Flavor] = :rabbitmq
15
+ kvs[:RemoteHost] = @channel.connection.host
16
+ kvs[:RemotePort] = @channel.connection.port.to_i
17
+ kvs[:VirtualHost] = @channel.connection.vhost
18
+
19
+ mp = args[1]
20
+ kvs[:RoutingKey] = args[0].routing_key if args[0].routing_key
21
+ kvs[:MsgID] = args[1].message_id if mp.message_id
22
+ kvs[:AppID] = args[1].app_id if mp.app_id
23
+ kvs[:Priority] = args[1].priority if mp.priority
24
+
25
+ if @queue.respond_to?(:name)
26
+ kvs[:Queue] = @queue.name
27
+ else
28
+ kvs[:Queue] = @queue
29
+ end
30
+
31
+ # Report configurable Controller/Action KVs
32
+ # See AppOpticsAPM::Config[:bunnyconsumer] in lib/appoptics_apm/config.rb
33
+ # Used for dashboard trace filtering
34
+ controller_key = AppOpticsAPM::Config[:bunnyconsumer][:controller]
35
+ if mp.respond_to?(controller_key)
36
+ value = mp.method(controller_key).call
37
+ kvs[:Controller] = value if value
38
+ end
39
+
40
+ action_key = AppOpticsAPM::Config[:bunnyconsumer][:action]
41
+ if mp.respond_to?(action_key)
42
+ value = mp.method(action_key).call
43
+ kvs[:Action] = value if value
44
+ end
45
+
46
+ if kvs[:Queue]
47
+ kvs[:URL] = "/bunny/#{kvs[:Queue]}"
48
+ else
49
+ kvs[:URL] = "/bunny/consumer"
50
+ end
51
+
52
+ if AppOpticsAPM::Config[:bunnyconsumer][:log_args] && @arguments
53
+ kvs[:Args] = @arguments.to_s
54
+ end
55
+
56
+ kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:bunnyconsumer][:collect_backtraces]
57
+
58
+ kvs
59
+ rescue => e
60
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
61
+ ensure
62
+ return kvs
63
+ end
64
+
65
+ def call_with_appoptics(*args)
66
+ report_kvs = collect_consumer_kvs(args)
67
+
68
+ # If SourceTrace was passed, capture and report it
69
+ headers = args[1][:headers]
70
+
71
+ if headers && headers['SourceTrace']
72
+ report_kvs[:SourceTrace] = headers['SourceTrace']
73
+
74
+ # Remove SourceTrace
75
+ headers.delete('SourceTrace')
76
+ end
77
+
78
+ AppOpticsAPM::SDK.start_trace(:'rabbitmq-consumer', nil, report_kvs) do
79
+ call_without_appoptics(*args)
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ if AppOpticsAPM::Config[:bunnyconsumer][:enabled] && defined?(Bunny)
87
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting bunny consumer' if AppOpticsAPM::Config[:verbose]
88
+ AppOpticsAPM::Util.send_include(Bunny::Consumer, AppOpticsAPM::Inst::BunnyConsumer)
89
+ end