appoptics_apm 4.0.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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +43 -0
- data/.dockerignore +5 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +82 -0
- data/CHANGELOG.md +769 -0
- data/CONFIG.md +33 -0
- data/Dockerfile +41 -0
- data/Dockerfile_test +66 -0
- data/Gemfile +41 -0
- data/LICENSE +193 -0
- data/README.md +351 -0
- data/Rakefile +202 -0
- data/Vagrantfile +67 -0
- data/appoptics_apm.gemspec +55 -0
- data/build_gems.sh +15 -0
- data/docker-compose.yml +73 -0
- data/examples/DNT.md +35 -0
- data/examples/carrying_context.rb +220 -0
- data/examples/instrumenting_metal_controller.rb +8 -0
- data/examples/puma_on_heroku_config.rb +17 -0
- data/examples/tracing_async_threads.rb +124 -0
- data/examples/tracing_background_jobs.rb +53 -0
- data/examples/tracing_forked_processes.rb +99 -0
- data/examples/unicorn_on_heroku_config.rb +28 -0
- data/ext/oboe_metal/extconf.rb +54 -0
- data/ext/oboe_metal/lib/.keep +0 -0
- data/ext/oboe_metal/lib/liboboe-1.0.so.0.0.0 +0 -0
- data/ext/oboe_metal/noop/noop.c +7 -0
- data/ext/oboe_metal/src/VERSION +1 -0
- data/ext/oboe_metal/src/bson/bson.h +221 -0
- data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
- data/ext/oboe_metal/src/oboe.h +883 -0
- data/ext/oboe_metal/src/oboe.hpp +793 -0
- data/ext/oboe_metal/src/oboe_debug.h +50 -0
- data/ext/oboe_metal/src/oboe_wrap.cxx +6088 -0
- data/ext/oboe_metal/tests/test.rb +11 -0
- data/gemfiles/delayed_job.gemfile +36 -0
- data/gemfiles/frameworks.gemfile +44 -0
- data/gemfiles/instrumentation_mocked.gemfile +29 -0
- data/gemfiles/libraries.gemfile +85 -0
- data/gemfiles/rails23.gemfile +39 -0
- data/gemfiles/rails30.gemfile +42 -0
- data/gemfiles/rails31.gemfile +44 -0
- data/gemfiles/rails32.gemfile +54 -0
- data/gemfiles/rails40.gemfile +27 -0
- data/gemfiles/rails41.gemfile +27 -0
- data/gemfiles/rails42.gemfile +35 -0
- data/gemfiles/rails50.gemfile +44 -0
- data/gemfiles/rails51.gemfile +44 -0
- data/get_version.rb +5 -0
- data/init.rb +4 -0
- data/lib/appoptics_apm/api/layerinit.rb +39 -0
- data/lib/appoptics_apm/api/logging.rb +359 -0
- data/lib/appoptics_apm/api/memcache.rb +34 -0
- data/lib/appoptics_apm/api/profiling.rb +201 -0
- data/lib/appoptics_apm/api/tracing.rb +152 -0
- data/lib/appoptics_apm/api/util.rb +128 -0
- data/lib/appoptics_apm/api.rb +18 -0
- data/lib/appoptics_apm/base.rb +252 -0
- data/lib/appoptics_apm/config.rb +281 -0
- data/lib/appoptics_apm/frameworks/grape.rb +93 -0
- data/lib/appoptics_apm/frameworks/padrino/templates.rb +58 -0
- data/lib/appoptics_apm/frameworks/padrino.rb +52 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +106 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller2.rb +61 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +58 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view_2x.rb +56 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +120 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +101 -0
- data/lib/appoptics_apm/frameworks/rails.rb +116 -0
- data/lib/appoptics_apm/frameworks/sinatra/templates.rb +56 -0
- data/lib/appoptics_apm/frameworks/sinatra.rb +71 -0
- data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
- data/lib/appoptics_apm/inst/bunny-consumer.rb +92 -0
- data/lib/appoptics_apm/inst/curb.rb +329 -0
- data/lib/appoptics_apm/inst/dalli.rb +85 -0
- data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
- data/lib/appoptics_apm/inst/em-http-request.rb +105 -0
- data/lib/appoptics_apm/inst/excon.rb +130 -0
- data/lib/appoptics_apm/inst/faraday.rb +77 -0
- data/lib/appoptics_apm/inst/http.rb +83 -0
- data/lib/appoptics_apm/inst/httpclient.rb +176 -0
- data/lib/appoptics_apm/inst/memcache.rb +102 -0
- data/lib/appoptics_apm/inst/memcached.rb +94 -0
- data/lib/appoptics_apm/inst/mongo.rb +242 -0
- data/lib/appoptics_apm/inst/mongo2.rb +225 -0
- data/lib/appoptics_apm/inst/moped.rb +466 -0
- data/lib/appoptics_apm/inst/rack.rb +146 -0
- data/lib/appoptics_apm/inst/redis.rb +275 -0
- data/lib/appoptics_apm/inst/resque.rb +151 -0
- data/lib/appoptics_apm/inst/rest-client.rb +50 -0
- data/lib/appoptics_apm/inst/sequel.rb +178 -0
- data/lib/appoptics_apm/inst/sidekiq-client.rb +53 -0
- data/lib/appoptics_apm/inst/sidekiq-worker.rb +67 -0
- data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
- data/lib/appoptics_apm/inst/typhoeus.rb +113 -0
- data/lib/appoptics_apm/instrumentation.rb +22 -0
- data/lib/appoptics_apm/legacy_method_profiling.rb +97 -0
- data/lib/appoptics_apm/loading.rb +66 -0
- data/lib/appoptics_apm/logger.rb +41 -0
- data/lib/appoptics_apm/method_profiling.rb +33 -0
- data/lib/appoptics_apm/ruby.rb +35 -0
- data/lib/appoptics_apm/support.rb +135 -0
- data/lib/appoptics_apm/test.rb +94 -0
- data/lib/appoptics_apm/thread_local.rb +26 -0
- data/lib/appoptics_apm/util.rb +312 -0
- data/lib/appoptics_apm/version.rb +15 -0
- data/lib/appoptics_apm/xtrace.rb +103 -0
- data/lib/appoptics_apm.rb +72 -0
- data/lib/joboe_metal.rb +214 -0
- data/lib/oboe/README +2 -0
- data/lib/oboe/backward_compatibility.rb +80 -0
- data/lib/oboe/inst/rack.rb +11 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe_metal.rb +187 -0
- data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
- data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +222 -0
- data/ruby_setup.sh +47 -0
- data/run_docker_build_gem_upload_to_packagecloud.sh +20 -0
- data/run_tests_docker.rb +32 -0
- data/test/benchmark/README.md +65 -0
- data/test/benchmark/logging_bench.rb +54 -0
- data/test/benchmark/with_libraries_gemfile/bunny_bench.rb +69 -0
- data/test/benchmark/with_rails5x_gemfile/action_controller5x_bench.rb +43 -0
- data/test/frameworks/apps/grape_nested.rb +33 -0
- data/test/frameworks/apps/grape_simple.rb +80 -0
- data/test/frameworks/apps/padrino_simple.rb +80 -0
- data/test/frameworks/apps/sinatra_simple.rb +55 -0
- data/test/frameworks/grape_test.rb +286 -0
- data/test/frameworks/padrino_test.rb +222 -0
- data/test/frameworks/rails3x_test.rb +554 -0
- data/test/frameworks/rails4x_test.rb +570 -0
- data/test/frameworks/rails5x_api_test.rb +210 -0
- data/test/frameworks/rails5x_test.rb +376 -0
- data/test/frameworks/rails_shared_tests.rb +172 -0
- data/test/frameworks/sinatra_test.rb +140 -0
- data/test/instrumentation/bunny_client_test.rb +276 -0
- data/test/instrumentation/bunny_consumer_test.rb +204 -0
- data/test/instrumentation/curb_test.rb +398 -0
- data/test/instrumentation/dalli_test.rb +177 -0
- data/test/instrumentation/em_http_request_test.rb +89 -0
- data/test/instrumentation/excon_test.rb +231 -0
- data/test/instrumentation/faraday_test.rb +228 -0
- data/test/instrumentation/http_test.rb +143 -0
- data/test/instrumentation/httpclient_test.rb +320 -0
- data/test/instrumentation/memcache_test.rb +260 -0
- data/test/instrumentation/memcached_test.rb +229 -0
- data/test/instrumentation/mongo_v1_test.rb +479 -0
- data/test/instrumentation/mongo_v2_index_test.rb +124 -0
- data/test/instrumentation/mongo_v2_test.rb +584 -0
- data/test/instrumentation/mongo_v2_view_test.rb +435 -0
- data/test/instrumentation/moped_test.rb +517 -0
- data/test/instrumentation/rack_test.rb +165 -0
- data/test/instrumentation/redis_hashes_test.rb +268 -0
- data/test/instrumentation/redis_keys_test.rb +321 -0
- data/test/instrumentation/redis_lists_test.rb +310 -0
- data/test/instrumentation/redis_misc_test.rb +163 -0
- data/test/instrumentation/redis_sets_test.rb +296 -0
- data/test/instrumentation/redis_sortedsets_test.rb +328 -0
- data/test/instrumentation/redis_strings_test.rb +349 -0
- data/test/instrumentation/resque_test.rb +185 -0
- data/test/instrumentation/rest-client_test.rb +288 -0
- data/test/instrumentation/sequel_mysql2_test.rb +353 -0
- data/test/instrumentation/sequel_mysql_test.rb +334 -0
- data/test/instrumentation/sequel_pg_test.rb +336 -0
- data/test/instrumentation/sidekiq-client_test.rb +159 -0
- data/test/instrumentation/sidekiq-worker_test.rb +180 -0
- data/test/instrumentation/twitter-cassandra_test.rb +424 -0
- data/test/instrumentation/typhoeus_test.rb +284 -0
- data/test/jobs/delayed_job/db_worker_job.rb +29 -0
- data/test/jobs/delayed_job/error_worker_job.rb +10 -0
- data/test/jobs/delayed_job/remote_call_worker_job.rb +20 -0
- data/test/jobs/resque/db_worker_job.rb +29 -0
- data/test/jobs/resque/error_worker_job.rb +10 -0
- data/test/jobs/resque/remote_call_worker_job.rb +20 -0
- data/test/jobs/sidekiq/db_worker_job.rb +29 -0
- data/test/jobs/sidekiq/error_worker_job.rb +10 -0
- data/test/jobs/sidekiq/remote_call_worker_job.rb +20 -0
- data/test/minitest_helper.rb +276 -0
- data/test/mocked/curb_mocked_test.rb +311 -0
- data/test/mocked/excon_mocked_test.rb +166 -0
- data/test/mocked/faraday_mocked_test.rb +93 -0
- data/test/mocked/http_mocked_test.rb +129 -0
- data/test/mocked/httpclient_mocked_test.rb +245 -0
- data/test/mocked/rest_client_mocked_test.rb +103 -0
- data/test/mocked/typhoeus_mocked_test.rb +192 -0
- data/test/models/widget.rb +36 -0
- data/test/profiling/legacy_method_profiling_test.rb +201 -0
- data/test/profiling/method_profiling_test.rb +631 -0
- data/test/queues/delayed_job-client_test.rb +95 -0
- data/test/queues/delayed_job-worker_test.rb +91 -0
- data/test/reporter/reporter_test.rb +14 -0
- data/test/servers/delayed_job.rb +107 -0
- data/test/servers/rackapp_8101.rb +29 -0
- data/test/servers/rails3x_8140.rb +96 -0
- data/test/servers/rails4x_8140.rb +96 -0
- data/test/servers/rails5x_8140.rb +95 -0
- data/test/servers/rails5x_api_8150.rb +78 -0
- data/test/servers/sidekiq.rb +29 -0
- data/test/servers/sidekiq.yml +7 -0
- data/test/servers/sidekiq_initializer.rb +25 -0
- data/test/settings +0 -0
- data/test/support/auto_tracing_test.rb +50 -0
- data/test/support/backcompat_test.rb +276 -0
- data/test/support/config_test.rb +149 -0
- data/test/support/dnt_test.rb +98 -0
- data/test/support/init_report_test.rb +25 -0
- data/test/support/liboboe_settings_test.rb +110 -0
- data/test/support/logging_test.rb +130 -0
- data/test/support/noop_test.rb +88 -0
- data/test/support/sql_sanitize_test.rb +55 -0
- data/test/support/tracing_mode_test.rb +33 -0
- data/test/support/tvalias_test.rb +15 -0
- data/test/support/xtrace_test.rb +41 -0
- metadata +475 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
##
|
|
6
|
+
# This module exposes a nested configuration hash that can be used to
|
|
7
|
+
# configure and/or modify the functionality of the appoptics_apm gem.
|
|
8
|
+
#
|
|
9
|
+
# Use AppOpticsAPM::Config.show to view the entire nested hash.
|
|
10
|
+
#
|
|
11
|
+
module Config
|
|
12
|
+
@@config = {}
|
|
13
|
+
|
|
14
|
+
@@instrumentation = [:action_controller, :action_controller_api, :action_view,
|
|
15
|
+
:active_record, :bunnyclient, :bunnyconsumer, :cassandra, :curb,
|
|
16
|
+
:dalli, :delayed_jobclient, :delayed_jobworker,
|
|
17
|
+
:em_http_request, :excon, :faraday, :grape,
|
|
18
|
+
:httpclient, :nethttp, :memcached,
|
|
19
|
+
:memcache, :mongo, :moped, :rack, :redis,
|
|
20
|
+
:resqueclient, :resqueworker, :rest_client,
|
|
21
|
+
:sequel, :sidekiqclient, :sidekiqworker, :typhoeus]
|
|
22
|
+
|
|
23
|
+
# Subgrouping of instrumentation
|
|
24
|
+
@@http_clients = [:curb, :excon, :em_http_request, :faraday, :httpclient, :nethttp, :rest_client, :typhoeus]
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
# Return the raw nested hash.
|
|
28
|
+
#
|
|
29
|
+
def self.show
|
|
30
|
+
@@config
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# initialize
|
|
35
|
+
#
|
|
36
|
+
# Initializer method to set everything up with a
|
|
37
|
+
# default configuration.
|
|
38
|
+
#
|
|
39
|
+
# rubocop:disable Metrics/AbcSize
|
|
40
|
+
def self.initialize(_data = {})
|
|
41
|
+
# Setup default instrumentation values
|
|
42
|
+
@@instrumentation.each do |k|
|
|
43
|
+
@@config[k] = {}
|
|
44
|
+
@@config[k][:enabled] = true
|
|
45
|
+
@@config[k][:collect_backtraces] = false
|
|
46
|
+
@@config[k][:log_args] = true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Beta instrumentation disabled by default
|
|
50
|
+
AppOpticsAPM::Config[:em_http_request][:enabled] = false
|
|
51
|
+
|
|
52
|
+
# Set collect_backtraces defaults
|
|
53
|
+
AppOpticsAPM::Config[:action_controller][:collect_backtraces] = false
|
|
54
|
+
AppOpticsAPM::Config[:action_controller_api][:collect_backtraces] = false
|
|
55
|
+
AppOpticsAPM::Config[:active_record][:collect_backtraces] = true
|
|
56
|
+
AppOpticsAPM::Config[:bunnyclient][:collect_backtraces] = false
|
|
57
|
+
AppOpticsAPM::Config[:bunnyconsumer][:collect_backtraces] = false
|
|
58
|
+
AppOpticsAPM::Config[:action_view][:collect_backtraces] = true
|
|
59
|
+
AppOpticsAPM::Config[:cassandra][:collect_backtraces] = true
|
|
60
|
+
AppOpticsAPM::Config[:curb][:collect_backtraces] = true
|
|
61
|
+
AppOpticsAPM::Config[:dalli][:collect_backtraces] = false
|
|
62
|
+
AppOpticsAPM::Config[:delayed_jobclient][:collect_backtraces] = false
|
|
63
|
+
AppOpticsAPM::Config[:delayed_jobworker][:collect_backtraces] = false
|
|
64
|
+
AppOpticsAPM::Config[:em_http_request][:collect_backtraces] = false
|
|
65
|
+
AppOpticsAPM::Config[:excon][:collect_backtraces] = true
|
|
66
|
+
AppOpticsAPM::Config[:faraday][:collect_backtraces] = false
|
|
67
|
+
AppOpticsAPM::Config[:grape][:collect_backtraces] = true
|
|
68
|
+
AppOpticsAPM::Config[:httpclient][:collect_backtraces] = true
|
|
69
|
+
AppOpticsAPM::Config[:memcache][:collect_backtraces] = false
|
|
70
|
+
AppOpticsAPM::Config[:memcached][:collect_backtraces] = false
|
|
71
|
+
AppOpticsAPM::Config[:mongo][:collect_backtraces] = true
|
|
72
|
+
AppOpticsAPM::Config[:moped][:collect_backtraces] = true
|
|
73
|
+
AppOpticsAPM::Config[:nethttp][:collect_backtraces] = true
|
|
74
|
+
AppOpticsAPM::Config[:rack][:collect_backtraces] = false
|
|
75
|
+
AppOpticsAPM::Config[:redis][:collect_backtraces] = false
|
|
76
|
+
AppOpticsAPM::Config[:resqueclient][:collect_backtraces] = true
|
|
77
|
+
AppOpticsAPM::Config[:resqueworker][:collect_backtraces] = false
|
|
78
|
+
AppOpticsAPM::Config[:rest_client][:collect_backtraces] = false
|
|
79
|
+
AppOpticsAPM::Config[:sequel][:collect_backtraces] = true
|
|
80
|
+
AppOpticsAPM::Config[:sidekiqclient][:collect_backtraces] = false
|
|
81
|
+
AppOpticsAPM::Config[:sidekiqworker][:collect_backtraces] = false
|
|
82
|
+
AppOpticsAPM::Config[:typhoeus][:collect_backtraces] = false
|
|
83
|
+
|
|
84
|
+
# Legacy Resque config support. To be removed in a future version
|
|
85
|
+
@@config[:resque] = {}
|
|
86
|
+
|
|
87
|
+
# Setup an empty host blacklist (see: AppOpticsAPM::API::Util.blacklisted?)
|
|
88
|
+
@@config[:blacklist] = []
|
|
89
|
+
|
|
90
|
+
# Logging of outgoing HTTP query args
|
|
91
|
+
#
|
|
92
|
+
# This optionally disables the logging of query args of outgoing
|
|
93
|
+
# HTTP clients such as Net::HTTP, excon, typhoeus and others.
|
|
94
|
+
#
|
|
95
|
+
# This flag is global to all HTTP client instrumentation.
|
|
96
|
+
#
|
|
97
|
+
# To configure this on a per instrumentation basis, set this
|
|
98
|
+
# option to true and instead disable the instrumenstation specific
|
|
99
|
+
# option <tt>log_args</tt>:
|
|
100
|
+
#
|
|
101
|
+
# AppOpticsAPM::Config[:nethttp][:log_args] = false
|
|
102
|
+
# AppOpticsAPM::Config[:excon][:log_args] = false
|
|
103
|
+
# AppOpticsAPM::Config[:typhoeus][:log_args] = true
|
|
104
|
+
#
|
|
105
|
+
@@config[:include_url_query_params] = true
|
|
106
|
+
|
|
107
|
+
# Logging of incoming HTTP query args
|
|
108
|
+
#
|
|
109
|
+
# This optionally disables the logging of incoming URL request
|
|
110
|
+
# query args.
|
|
111
|
+
#
|
|
112
|
+
# This flag is global and currently only affects the Rack
|
|
113
|
+
# instrumentation which reports incoming request URLs and
|
|
114
|
+
# query args by default.
|
|
115
|
+
@@config[:include_remote_url_params] = true
|
|
116
|
+
|
|
117
|
+
# The AppOpticsAPM Ruby gem has the ability to sanitize query literals
|
|
118
|
+
# from SQL statements. By default this is enabled to
|
|
119
|
+
# avoid collecting and reporting query literals to AppOpticsAPM.
|
|
120
|
+
@@config[:sanitize_sql] = true
|
|
121
|
+
|
|
122
|
+
# The regular expression used to sanitize SQL.
|
|
123
|
+
@@config[:sanitize_sql_regexp] = '(\'[\s\S][^\']*\'|\d*\.\d+|\d+|NULL)'
|
|
124
|
+
@@config[:sanitize_sql_opts] = Regexp::IGNORECASE
|
|
125
|
+
|
|
126
|
+
# Do Not Trace
|
|
127
|
+
# These two values allow you to configure specific URL patterns to
|
|
128
|
+
# never be traced. By default, this is set to common static file
|
|
129
|
+
# extensions but you may want to customize this list for your needs.
|
|
130
|
+
#
|
|
131
|
+
# dnt_regexp and dnt_opts is passed to Regexp.new to create
|
|
132
|
+
# a regular expression object. That is then used to match against
|
|
133
|
+
# the incoming request path.
|
|
134
|
+
#
|
|
135
|
+
# The path string originates from the rack layer and is retrieved
|
|
136
|
+
# as follows:
|
|
137
|
+
#
|
|
138
|
+
# req = ::Rack::Request.new(env)
|
|
139
|
+
# path = URI.unescape(req.path)
|
|
140
|
+
#
|
|
141
|
+
# Usage:
|
|
142
|
+
# AppOpticsAPM::Config[:dnt_regexp] = "lobster$"
|
|
143
|
+
# AppOpticsAPM::Config[:dnt_opts] = Regexp::IGNORECASE
|
|
144
|
+
#
|
|
145
|
+
# This will ignore all requests that end with the string lobster
|
|
146
|
+
# regardless of case
|
|
147
|
+
#
|
|
148
|
+
# Requests with positive matches (non nil) will not be traced.
|
|
149
|
+
# See lib/appoptics_apm/util.rb: AppOpticsAPM::Util.static_asset?
|
|
150
|
+
#
|
|
151
|
+
@@config[:dnt_regexp] = '\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|otf|eot|ttf|woff|woff2|svg|less)(\?.+){0,1}$'
|
|
152
|
+
@@config[:dnt_opts] = Regexp::IGNORECASE
|
|
153
|
+
|
|
154
|
+
# In Rails, raised exceptions with rescue handlers via
|
|
155
|
+
# <tt>rescue_from</tt> are not reported to the AppOptics
|
|
156
|
+
# dashboard by default. Setting this value to true will
|
|
157
|
+
# report all raised exception regardless.
|
|
158
|
+
#
|
|
159
|
+
@@config[:report_rescued_errors] = false
|
|
160
|
+
|
|
161
|
+
# The bunny (Rabbitmq) instrumentation can optionally report
|
|
162
|
+
# Controller and Action values to allow filtering of bunny
|
|
163
|
+
# message handling in # the UI. Use of Controller and Action
|
|
164
|
+
# for filters is temporary until the UI is updated with
|
|
165
|
+
# additional filters.
|
|
166
|
+
#
|
|
167
|
+
# These values identify which properties of
|
|
168
|
+
# Bunny::MessageProperties to report as Controller
|
|
169
|
+
# and Action. The defaults are to report :app_id (as
|
|
170
|
+
# Controller) and :type (as Action). If these values
|
|
171
|
+
# are not specified in the publish, then nothing
|
|
172
|
+
# will be reported here.
|
|
173
|
+
#
|
|
174
|
+
@@config[:bunnyconsumer][:controller] = :app_id
|
|
175
|
+
@@config[:bunnyconsumer][:action] = :type
|
|
176
|
+
|
|
177
|
+
@@config[:verbose] = ENV.key?('APPOPTICS_GEM_VERBOSE') && ENV['APPOPTICS_GEM_VERBOSE'] == 'true' ? true : false
|
|
178
|
+
end
|
|
179
|
+
# rubocop:enable Metrics/AbcSize
|
|
180
|
+
|
|
181
|
+
def self.update!(data)
|
|
182
|
+
data.each do |key, value|
|
|
183
|
+
self[key] = value
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def self.merge!(data)
|
|
188
|
+
update!(data)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def self.[](key)
|
|
192
|
+
if key == :resque
|
|
193
|
+
AppOpticsAPM.logger.warn '[appoptics_apm/warn] :resque config is deprecated. It is now split into :resqueclient and :resqueworker.'
|
|
194
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/warn] Called from #{Kernel.caller[0]}"
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
@@config[key.to_sym]
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
##
|
|
201
|
+
# []=
|
|
202
|
+
#
|
|
203
|
+
# Config variable assignment method. Here we validate and store the
|
|
204
|
+
# assigned value(s) and trigger any secondary action needed.
|
|
205
|
+
#
|
|
206
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
207
|
+
def self.[]=(key, value)
|
|
208
|
+
@@config[key.to_sym] = value
|
|
209
|
+
|
|
210
|
+
if key == :sampling_rate
|
|
211
|
+
AppOpticsAPM.logger.warn 'sampling_rate is not a supported setting for AppOpticsAPM::Config. ' \
|
|
212
|
+
'Please use :sample_rate.'
|
|
213
|
+
|
|
214
|
+
elsif key == :sample_rate
|
|
215
|
+
unless value.is_a?(Integer) || value.is_a?(Float)
|
|
216
|
+
fail 'appoptics_apm :sample_rate must be a number between 0 and 1000000 (1m)'
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Validate :sample_rate value
|
|
220
|
+
unless value.between?(0, 1e6)
|
|
221
|
+
fail 'appoptics_apm :sample_rate must be between 0 and 1000000 (1m)'
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Assure value is an integer
|
|
225
|
+
@@config[key.to_sym] = value.to_i
|
|
226
|
+
AppOpticsAPM.set_sample_rate(value) if AppOpticsAPM.loaded
|
|
227
|
+
|
|
228
|
+
elsif key == :action_blacklist
|
|
229
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/unsupported] :action_blacklist has been deprecated and no longer functions."
|
|
230
|
+
|
|
231
|
+
elsif key == :resque
|
|
232
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/warn] :resque config is deprecated. It is now split into :resqueclient and :resqueworker."
|
|
233
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/warn] Called from #{Kernel.caller[0]}"
|
|
234
|
+
|
|
235
|
+
elsif key == :include_url_query_params
|
|
236
|
+
# Obey the global flag and update all of the per instrumentation
|
|
237
|
+
# <tt>:log_args</tt> values.
|
|
238
|
+
@@config[:rack][:log_args] = value
|
|
239
|
+
|
|
240
|
+
elsif key == :include_remote_url_params
|
|
241
|
+
# Obey the global flag and update all of the per instrumentation
|
|
242
|
+
# <tt>:log_args</tt> values.
|
|
243
|
+
@@http_clients.each do |i|
|
|
244
|
+
@@config[i][:log_args] = value
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Update liboboe if updating :tracing_mode
|
|
249
|
+
if key == :tracing_mode
|
|
250
|
+
AppOpticsAPM.set_tracing_mode(value.to_sym) if AppOpticsAPM.loaded
|
|
251
|
+
|
|
252
|
+
# Make sure that the mode is stored as a symbol
|
|
253
|
+
@@config[key.to_sym] = value.to_sym
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
257
|
+
|
|
258
|
+
def self.method_missing(sym, *args)
|
|
259
|
+
class_var_name = "@@#{sym}"
|
|
260
|
+
|
|
261
|
+
if sym.to_s =~ /(.+)=$/
|
|
262
|
+
self[$1] = args.first
|
|
263
|
+
else
|
|
264
|
+
# Try part of the @@config hash first
|
|
265
|
+
if @@config.key?(sym)
|
|
266
|
+
self[sym]
|
|
267
|
+
|
|
268
|
+
# Then try as a class variable
|
|
269
|
+
elsif self.class_variable_defined?(class_var_name.to_sym)
|
|
270
|
+
self.class_eval(class_var_name)
|
|
271
|
+
|
|
272
|
+
# Congrats - You've won a brand new nil...
|
|
273
|
+
else
|
|
274
|
+
nil
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
AppOpticsAPM::Config.initialize
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
module Grape
|
|
6
|
+
module API
|
|
7
|
+
def self.extended(klass)
|
|
8
|
+
::AppOpticsAPM::Util.class_method_alias(klass, :inherited, ::Grape::API)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def inherited_with_appoptics(subclass)
|
|
12
|
+
inherited_without_appoptics(subclass)
|
|
13
|
+
|
|
14
|
+
subclass.use ::AppOpticsAPM::Rack
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
module Endpoint
|
|
19
|
+
def self.included(klass)
|
|
20
|
+
::AppOpticsAPM::Util.method_alias(klass, :run, ::Grape::Endpoint)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def run_with_appoptics(*args)
|
|
24
|
+
# Report Controller/Action and Transaction as best possible
|
|
25
|
+
report_kvs = {}
|
|
26
|
+
|
|
27
|
+
report_kvs[:Controller] = options[:for].name
|
|
28
|
+
if route && route.pattern
|
|
29
|
+
report_kvs[:Action] = route.pattern.origin
|
|
30
|
+
else
|
|
31
|
+
report_kvs[:Action] = args.empty? ? env['PATH_INFO'] : args[0]['PATH_INFO']
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
env['appoptics_apm.controller'] = report_kvs[:Controller]
|
|
35
|
+
env['appoptics_apm.action'] = report_kvs[:Action]
|
|
36
|
+
|
|
37
|
+
::AppOpticsAPM::API.log_entry('grape', report_kvs)
|
|
38
|
+
|
|
39
|
+
run_without_appoptics(*args)
|
|
40
|
+
ensure
|
|
41
|
+
::AppOpticsAPM::API.log_exit('grape')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
module Middleware
|
|
46
|
+
module Error
|
|
47
|
+
def self.included(klass)
|
|
48
|
+
::AppOpticsAPM::Util.method_alias(klass, :error_response, ::Grape::Middleware::Error)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def error_response_with_appoptics(error = {})
|
|
52
|
+
status, headers, body = error_response_without_appoptics(error)
|
|
53
|
+
|
|
54
|
+
if AppOpticsAPM.tracing?
|
|
55
|
+
# Since Grape uses throw/catch and not Exceptions, we manually log
|
|
56
|
+
# the error here.
|
|
57
|
+
kvs = {}
|
|
58
|
+
kvs[:ErrorClass] = 'GrapeError'
|
|
59
|
+
kvs[:ErrorMsg] = error[:message] ? error[:message] : "No message given."
|
|
60
|
+
kvs[:Backtrace] = ::AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:grape][:collect_backtraces]
|
|
61
|
+
|
|
62
|
+
::AppOpticsAPM::API.log(nil, 'error', kvs)
|
|
63
|
+
|
|
64
|
+
# Since calls to error() are handled similar to abort in Grape. We
|
|
65
|
+
# manually log the rack exit here since the original code won't
|
|
66
|
+
# be returned to
|
|
67
|
+
xtrace = AppOpticsAPM::API.log_end('rack', :Status => status)
|
|
68
|
+
|
|
69
|
+
if headers && AppOpticsAPM::XTrace.valid?(xtrace)
|
|
70
|
+
unless defined?(JRUBY_VERSION) && AppOpticsAPM.is_continued_trace?
|
|
71
|
+
headers['X-Trace'] = xtrace if headers.is_a?(Hash)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
[status, headers, body]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
if AppOpticsAPM::Config[:grape][:enabled] && defined?(::Grape)
|
|
84
|
+
require 'appoptics_apm/inst/rack'
|
|
85
|
+
|
|
86
|
+
AppOpticsAPM.logger.info "[appoptics_apm/loading] Instrumenting Grape" if AppOpticsAPM::Config[:verbose]
|
|
87
|
+
|
|
88
|
+
AppOpticsAPM::Inst.load_instrumentation
|
|
89
|
+
|
|
90
|
+
::AppOpticsAPM::Util.send_extend(::Grape::API, ::AppOpticsAPM::Grape::API)
|
|
91
|
+
::AppOpticsAPM::Util.send_include(::Grape::Endpoint, ::AppOpticsAPM::Grape::Endpoint)
|
|
92
|
+
::AppOpticsAPM::Util.send_include(::Grape::Middleware::Error, ::AppOpticsAPM::Grape::Middleware::Error)
|
|
93
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
module PadrinoInst
|
|
6
|
+
module Rendering
|
|
7
|
+
def self.included(klass)
|
|
8
|
+
::AppOpticsAPM::Util.method_alias(klass, :render, ::Padrino::Rendering)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def render_with_appoptics(engine, data = nil, options = {}, locals = {}, &block)
|
|
12
|
+
if AppOpticsAPM.tracing?
|
|
13
|
+
report_kvs = {}
|
|
14
|
+
|
|
15
|
+
if data
|
|
16
|
+
report_kvs[:engine] = engine
|
|
17
|
+
report_kvs[:template] = data
|
|
18
|
+
else
|
|
19
|
+
report_kvs[:template] = engine
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if AppOpticsAPM.tracing_layer_op?(:render)
|
|
23
|
+
# For recursive calls to :render (for sub-partials and layouts),
|
|
24
|
+
# use method profiling.
|
|
25
|
+
begin
|
|
26
|
+
report_kvs[:FunctionName] = :render
|
|
27
|
+
report_kvs[:Class] = :Rendering
|
|
28
|
+
report_kvs[:Module] = :Padrino
|
|
29
|
+
report_kvs[:File] = __FILE__
|
|
30
|
+
report_kvs[:LineNumber] = __LINE__
|
|
31
|
+
rescue StandardError => e
|
|
32
|
+
::AppOpticsAPM.logger.debug e.message
|
|
33
|
+
::AppOpticsAPM.logger.debug e.backtrace.join(', ')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
AppOpticsAPM::API.profile(report_kvs[:template], report_kvs, false) do
|
|
37
|
+
render_without_appoptics(engine, data, options, locals, &block)
|
|
38
|
+
end
|
|
39
|
+
else
|
|
40
|
+
# Fall back to the raw tracing API so we can pass KVs
|
|
41
|
+
# back on exit (a limitation of the AppOpticsAPM::API.trace
|
|
42
|
+
# block method) This removes the need for an info
|
|
43
|
+
# event to send additonal KVs
|
|
44
|
+
::AppOpticsAPM::API.log_entry(:render, {}, :render)
|
|
45
|
+
|
|
46
|
+
begin
|
|
47
|
+
render_without_appoptics(engine, data, options, locals, &block)
|
|
48
|
+
ensure
|
|
49
|
+
::AppOpticsAPM::API.log_exit(:render, report_kvs)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
else
|
|
53
|
+
render_without_appoptics(engine, data, options, locals, &block)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
|
|
15
|
+
result = dispatch_without_appoptics
|
|
16
|
+
|
|
17
|
+
# Report Controller/Action and Transaction as best possible
|
|
18
|
+
report_kvs = {}
|
|
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
|
+
ensure
|
|
27
|
+
::AppOpticsAPM::API.log_exit('padrino', report_kvs)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if defined?(::Padrino)
|
|
34
|
+
# This instrumentation is a superset of the Sinatra instrumentation similar
|
|
35
|
+
# to how Padrino is a superset of Sinatra itself.
|
|
36
|
+
::AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting Padrino' if AppOpticsAPM::Config[:verbose]
|
|
37
|
+
|
|
38
|
+
require 'appoptics_apm/frameworks/padrino/templates'
|
|
39
|
+
|
|
40
|
+
Padrino.after_load do
|
|
41
|
+
::AppOpticsAPM.logger = ::Padrino.logger if ::Padrino.respond_to?(:logger)
|
|
42
|
+
::AppOpticsAPM::Inst.load_instrumentation
|
|
43
|
+
|
|
44
|
+
::AppOpticsAPM::Util.send_include(::Padrino::Routing::InstanceMethods, ::AppOpticsAPM::PadrinoInst::Routing)
|
|
45
|
+
if defined?(::Padrino::Rendering)
|
|
46
|
+
::AppOpticsAPM::Util.send_include(::Padrino::Rendering::InstanceMethods, ::AppOpticsAPM::PadrinoInst::Rendering)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Report __Init after fork when in Heroku
|
|
50
|
+
AppOpticsAPM::API.report_init unless AppOpticsAPM.heroku?
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
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(:@appoptics_logged)
|
|
47
|
+
|
|
48
|
+
has_handler = has_handler?(exception)
|
|
49
|
+
|
|
50
|
+
if !has_handler || (has_handler && AppOpticsAPM::Config[:report_rescued_errors])
|
|
51
|
+
return true
|
|
52
|
+
end
|
|
53
|
+
false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
##
|
|
57
|
+
# This method does the logging if we are tracing
|
|
58
|
+
# it `wraps` around the call to the original method
|
|
59
|
+
#
|
|
60
|
+
def trace(layer)
|
|
61
|
+
return yield unless AppOpticsAPM.tracing?
|
|
62
|
+
begin
|
|
63
|
+
AppOpticsAPM::API.log_entry(layer)
|
|
64
|
+
yield
|
|
65
|
+
rescue Exception => e
|
|
66
|
+
AppOpticsAPM::API.log_exception(layer, e) if log_rails_error?(e)
|
|
67
|
+
raise
|
|
68
|
+
ensure
|
|
69
|
+
AppOpticsAPM::API.log_exit(layer)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
#
|
|
75
|
+
# render_with_appoptics
|
|
76
|
+
#
|
|
77
|
+
# Our render wrapper that calls 'add_logging', which will log if we are tracing
|
|
78
|
+
#
|
|
79
|
+
def render_with_appoptics(*args, &blk)
|
|
80
|
+
trace('actionview') do
|
|
81
|
+
render_without_appoptics(*args, &blk)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# ActionController::Base
|
|
89
|
+
if defined?(ActionController::Base) && AppOpticsAPM::Config[:action_controller][:enabled]
|
|
90
|
+
AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting actioncontroller' if AppOpticsAPM::Config[:verbose]
|
|
91
|
+
require "appoptics_apm/frameworks/rails/inst/action_controller#{Rails::VERSION::MAJOR}"
|
|
92
|
+
if Rails::VERSION::MAJOR >= 5
|
|
93
|
+
::ActionController::Base.send(:prepend, ::AppOpticsAPM::Inst::ActionController)
|
|
94
|
+
else
|
|
95
|
+
::AppOpticsAPM::Util.send_include(::ActionController::Base, AppOpticsAPM::Inst::ActionController)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# ActionController::API - Rails 5+ or via the rails-api gem
|
|
100
|
+
if defined?(ActionController::API) && AppOpticsAPM::Config[:action_controller_api][:enabled]
|
|
101
|
+
AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting actioncontroller api' if AppOpticsAPM::Config[:verbose]
|
|
102
|
+
require "appoptics_apm/frameworks/rails/inst/action_controller_api"
|
|
103
|
+
::ActionController::API.send(:prepend, ::AppOpticsAPM::Inst::ActionControllerAPI)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# vim:set expandtab:tabstop=2
|
|
@@ -0,0 +1,61 @@
|
|
|
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 v2
|
|
11
|
+
#
|
|
12
|
+
module ActionController
|
|
13
|
+
include ::AppOpticsAPM::Inst::RailsBase
|
|
14
|
+
|
|
15
|
+
def self.included(klass)
|
|
16
|
+
::AppOpticsAPM::Util.method_alias(klass, :perform_action)
|
|
17
|
+
::AppOpticsAPM::Util.method_alias(klass, :rescue_action)
|
|
18
|
+
::AppOpticsAPM::Util.method_alias(klass, :process)
|
|
19
|
+
::AppOpticsAPM::Util.method_alias(klass, :render)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def process_with_appoptics(*args)
|
|
23
|
+
AppOpticsAPM::API.log_entry('rails')
|
|
24
|
+
process_without_appoptics(*args)
|
|
25
|
+
|
|
26
|
+
rescue Exception => e
|
|
27
|
+
AppOpticsAPM::API.log_exception(nil, e) if log_rails_error?(e)
|
|
28
|
+
raise
|
|
29
|
+
ensure
|
|
30
|
+
AppOpticsAPM::API.log_exit('rails')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def perform_action_with_appoptics(*arguments)
|
|
34
|
+
kvs = {
|
|
35
|
+
:Controller => @_request.path_parameters['controller'],
|
|
36
|
+
:Action => @_request.path_parameters['action']
|
|
37
|
+
}
|
|
38
|
+
kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:action_controller][:collect_backtraces]
|
|
39
|
+
|
|
40
|
+
AppOpticsAPM::API.log(nil, 'info', kvs)
|
|
41
|
+
perform_action_without_appoptics(*arguments)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def rescue_action_with_appoptics(exn)
|
|
45
|
+
AppOpticsAPM::API.log_exception(nil, exn) if log_rails_error?(exn)
|
|
46
|
+
rescue_action_without_appoptics(exn)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def render_with_appoptics(options = nil, extra_options = {}, &block)
|
|
50
|
+
AppOpticsAPM::API.log_entry('actionview')
|
|
51
|
+
render_without_appoptics(options, extra_options, &block)
|
|
52
|
+
|
|
53
|
+
rescue Exception => e
|
|
54
|
+
AppOpticsAPM::API.log_exception(nil, e) if log_rails_error?(e)
|
|
55
|
+
raise
|
|
56
|
+
ensure
|
|
57
|
+
AppOpticsAPM::API.log_exit('actionview')
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|