oneapm_rpm 1.1.0
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/.gitignore +30 -0
- data/.rubocop.yml +725 -0
- data/Gemfile +3 -0
- data/Guardfile +7 -0
- data/LICENSE +1 -0
- data/README.md +3 -0
- data/config/cert/cacert.pem +1177 -0
- data/config/database.yml +5 -0
- data/lib/initializers/goliath.rb +11 -0
- data/lib/initializers/other.rb +1 -0
- data/lib/initializers/rails.rb +15 -0
- data/lib/one_apm/agent.rb +253 -0
- data/lib/one_apm/agent/agent.rb +283 -0
- data/lib/one_apm/agent/agent/connect.rb +175 -0
- data/lib/one_apm/agent/agent/container_data_manager.rb +218 -0
- data/lib/one_apm/agent/agent/forkable_dispatcher_functions.rb +96 -0
- data/lib/one_apm/agent/agent/helpers.rb +45 -0
- data/lib/one_apm/agent/agent/start.rb +226 -0
- data/lib/one_apm/agent/agent/start_worker_thread.rb +148 -0
- data/lib/one_apm/agent/busy_calculator.rb +115 -0
- data/lib/one_apm/agent/cross_app/cross_app_monitor.rb +181 -0
- data/lib/one_apm/agent/cross_app/cross_app_tracing.rb +336 -0
- data/lib/one_apm/agent/database.rb +308 -0
- data/lib/one_apm/agent/database/active_record_helper.rb +80 -0
- data/lib/one_apm/agent/database/obfuscation_helpers.rb +76 -0
- data/lib/one_apm/agent/database/obfuscator.rb +78 -0
- data/lib/one_apm/agent/database/postgres_explain_obfuscator.rb +45 -0
- data/lib/one_apm/agent/datastores.rb +175 -0
- data/lib/one_apm/agent/datastores/metric_helper.rb +83 -0
- data/lib/one_apm/agent/datastores/mongo.rb +27 -0
- data/lib/one_apm/agent/datastores/mongo/metric_translator.rb +189 -0
- data/lib/one_apm/agent/datastores/mongo/obfuscator.rb +37 -0
- data/lib/one_apm/agent/datastores/mongo/statement_formatter.rb +51 -0
- data/lib/one_apm/agent/event/event_listener.rb +40 -0
- data/lib/one_apm/agent/event/event_loop.rb +191 -0
- data/lib/one_apm/agent/event/worker_loop.rb +97 -0
- data/lib/one_apm/agent/harvester.rb +48 -0
- data/lib/one_apm/agent/inbound_request_monitor.rb +30 -0
- data/lib/one_apm/agent/javascript_instrumentor.rb +186 -0
- data/lib/one_apm/agent/pipe/pipe_channel_manager.rb +275 -0
- data/lib/one_apm/agent/pipe/pipe_service.rb +81 -0
- data/lib/one_apm/agent/sampler.rb +55 -0
- data/lib/one_apm/agent/sampler_collection.rb +65 -0
- data/lib/one_apm/agent/samplers/cpu_sampler.rb +49 -0
- data/lib/one_apm/agent/samplers/delayed_job_sampler.rb +109 -0
- data/lib/one_apm/agent/samplers/memory_sampler.rb +144 -0
- data/lib/one_apm/agent/samplers/object_sampler.rb +22 -0
- data/lib/one_apm/agent/samplers/vm_sampler.rb +124 -0
- data/lib/one_apm/agent/synthetics_monitor.rb +48 -0
- data/lib/one_apm/agent/threading/agent_thread.rb +74 -0
- data/lib/one_apm/agent/threading/backtrace_node.rb +133 -0
- data/lib/one_apm/agent/threading/backtrace_service.rb +259 -0
- data/lib/one_apm/agent/threading/thread_profile.rb +155 -0
- data/lib/one_apm/collector/collector/helper.rb +139 -0
- data/lib/one_apm/collector/collector/http_connection.rb +254 -0
- data/lib/one_apm/collector/collector/server_methods.rb +71 -0
- data/lib/one_apm/collector/collector_service.rb +123 -0
- data/lib/one_apm/collector/commands/agent_command.rb +17 -0
- data/lib/one_apm/collector/commands/thread_profiler_session.rb +108 -0
- data/lib/one_apm/collector/commands/xray_session.rb +53 -0
- data/lib/one_apm/collector/commands/xray_session_collection.rb +156 -0
- data/lib/one_apm/collector/containers/agent_command_router.rb +153 -0
- data/lib/one_apm/collector/containers/custom_event_aggregator.rb +94 -0
- data/lib/one_apm/collector/containers/error_collector.rb +349 -0
- data/lib/one_apm/collector/containers/sql_sampler.rb +331 -0
- data/lib/one_apm/collector/containers/stats_engine.rb +34 -0
- data/lib/one_apm/collector/containers/transaction_event_aggregator.rb +249 -0
- data/lib/one_apm/collector/containers/transaction_sampler.rb +352 -0
- data/lib/one_apm/collector/containers/utilization_data.rb +36 -0
- data/lib/one_apm/collector/stats_engine/gc_profiler.rb +106 -0
- data/lib/one_apm/collector/stats_engine/metric_stats.rb +243 -0
- data/lib/one_apm/collector/stats_engine/stats_hash.rb +105 -0
- data/lib/one_apm/configuration.rb +429 -0
- data/lib/one_apm/configuration/autostart.rb +41 -0
- data/lib/one_apm/configuration/default_source.rb +1026 -0
- data/lib/one_apm/configuration/environment_source.rb +113 -0
- data/lib/one_apm/configuration/high_security_source.rb +56 -0
- data/lib/one_apm/configuration/manual_source.rb +13 -0
- data/lib/one_apm/configuration/server_source.rb +60 -0
- data/lib/one_apm/configuration/yaml_source.rb +134 -0
- data/lib/one_apm/errors/agent_errors.rb +26 -0
- data/lib/one_apm/errors/internal_agent_error.rb +16 -0
- data/lib/one_apm/errors/noticed_error.rb +79 -0
- data/lib/one_apm/frameworks/external.rb +15 -0
- data/lib/one_apm/frameworks/rails.rb +103 -0
- data/lib/one_apm/frameworks/rails3.rb +37 -0
- data/lib/one_apm/frameworks/rails4.rb +21 -0
- data/lib/one_apm/frameworks/ruby.rb +21 -0
- data/lib/one_apm/frameworks/sinatra.rb +12 -0
- data/lib/one_apm/inst/3rd/active_merchant.rb +35 -0
- data/lib/one_apm/inst/3rd/acts_as_solr.rb +70 -0
- data/lib/one_apm/inst/3rd/authlogic.rb +23 -0
- data/lib/one_apm/inst/3rd/sunspot.rb +31 -0
- data/lib/one_apm/inst/background_job/active_job.rb +88 -0
- data/lib/one_apm/inst/background_job/delayed_job.rb +52 -0
- data/lib/one_apm/inst/background_job/delayed_job_injection.rb +8 -0
- data/lib/one_apm/inst/background_job/resque.rb +107 -0
- data/lib/one_apm/inst/background_job/sidekiq.rb +64 -0
- data/lib/one_apm/inst/dispatcher/passenger.rb +25 -0
- data/lib/one_apm/inst/dispatcher/rainbows.rb +23 -0
- data/lib/one_apm/inst/framework/grape.rb +94 -0
- data/lib/one_apm/inst/framework/padrino.rb +30 -0
- data/lib/one_apm/inst/framework/sinatra.rb +185 -0
- data/lib/one_apm/inst/framework/sinatra/ignorer.rb +50 -0
- data/lib/one_apm/inst/framework/sinatra/transaction_namer.rb +54 -0
- data/lib/one_apm/inst/http_clients/curb.rb +189 -0
- data/lib/one_apm/inst/http_clients/excon.rb +70 -0
- data/lib/one_apm/inst/http_clients/excon/connection.rb +31 -0
- data/lib/one_apm/inst/http_clients/excon/middleware.rb +55 -0
- data/lib/one_apm/inst/http_clients/httpclient.rb +44 -0
- data/lib/one_apm/inst/http_clients/net.rb +34 -0
- data/lib/one_apm/inst/http_clients/typhoeus.rb +76 -0
- data/lib/one_apm/inst/nosql/memcache.rb +134 -0
- data/lib/one_apm/inst/nosql/mongo.rb +126 -0
- data/lib/one_apm/inst/nosql/mongo_moped.rb +85 -0
- data/lib/one_apm/inst/nosql/redis.rb +83 -0
- data/lib/one_apm/inst/orm/active_record.rb +99 -0
- data/lib/one_apm/inst/orm/active_record_4.rb +28 -0
- data/lib/one_apm/inst/orm/data_mapper.rb +180 -0
- data/lib/one_apm/inst/orm/sequel.rb +47 -0
- data/lib/one_apm/inst/rack.rb +38 -0
- data/lib/one_apm/inst/rack/rack.rb +44 -0
- data/lib/one_apm/inst/rack/rack_builder.rb +51 -0
- data/lib/one_apm/inst/rails/action_controller.rb +118 -0
- data/lib/one_apm/inst/rails/action_web_service.rb +44 -0
- data/lib/one_apm/inst/rails/errors.rb +43 -0
- data/lib/one_apm/inst/rails3/action_controller.rb +172 -0
- data/lib/one_apm/inst/rails3/errors.rb +43 -0
- data/lib/one_apm/inst/rails4/action_controller.rb +27 -0
- data/lib/one_apm/inst/rails4/action_controller_subscriber.rb +121 -0
- data/lib/one_apm/inst/rails4/action_view.rb +23 -0
- data/lib/one_apm/inst/rails4/action_view_subscriber.rb +93 -0
- data/lib/one_apm/inst/rails4/active_record_subscriber.rb +96 -0
- data/lib/one_apm/inst/rails4/errors.rb +42 -0
- data/lib/one_apm/inst/rails_middleware.rb +40 -0
- data/lib/one_apm/inst/support/evented_subscriber.rb +98 -0
- data/lib/one_apm/inst/support/ignore_actions.rb +39 -0
- data/lib/one_apm/inst/support/queue_time.rb +76 -0
- data/lib/one_apm/inst/transaction_base.rb +405 -0
- data/lib/one_apm/logger/agent_logger.rb +206 -0
- data/lib/one_apm/logger/audit_logger.rb +78 -0
- data/lib/one_apm/logger/memory_logger.rb +50 -0
- data/lib/one_apm/logger/null_logger.rb +19 -0
- data/lib/one_apm/metrics/metric_data.rb +72 -0
- data/lib/one_apm/metrics/metric_spec.rb +82 -0
- data/lib/one_apm/metrics/stats.rb +173 -0
- data/lib/one_apm/probe.rb +16 -0
- data/lib/one_apm/probe/framework_loader.rb +53 -0
- data/lib/one_apm/probe/instance_methods.rb +105 -0
- data/lib/one_apm/probe/instrumentation.rb +60 -0
- data/lib/one_apm/rack/browser_monitoring.rb +144 -0
- data/lib/one_apm/rack/middleware_base.rb +27 -0
- data/lib/one_apm/rack/middleware_hooks.rb +17 -0
- data/lib/one_apm/rack/middleware_tracing.rb +81 -0
- data/lib/one_apm/rack/middleware_wrapper.rb +86 -0
- data/lib/one_apm/support/chained_call.rb +15 -0
- data/lib/one_apm/support/coerce.rb +81 -0
- data/lib/one_apm/support/collection_helper.rb +79 -0
- data/lib/one_apm/support/dotted_hash.rb +45 -0
- data/lib/one_apm/support/encoders.rb +34 -0
- data/lib/one_apm/support/environment_report.rb +127 -0
- data/lib/one_apm/support/event_buffer.rb +82 -0
- data/lib/one_apm/support/event_buffer/sampled_buffer.rb +45 -0
- data/lib/one_apm/support/event_buffer/sized_buffer.rb +21 -0
- data/lib/one_apm/support/event_buffer/synthetics_event_buffer.rb +40 -0
- data/lib/one_apm/support/helper.rb +49 -0
- data/lib/one_apm/support/hostname.rb +13 -0
- data/lib/one_apm/support/http_clients/curb_wrappers.rb +65 -0
- data/lib/one_apm/support/http_clients/excon_wrappers.rb +63 -0
- data/lib/one_apm/support/http_clients/httpclient_wrappers.rb +61 -0
- data/lib/one_apm/support/http_clients/net_http_wrappers.rb +48 -0
- data/lib/one_apm/support/http_clients/typhoeus_wrappers.rb +73 -0
- data/lib/one_apm/support/http_clients/uri_util.rb +39 -0
- data/lib/one_apm/support/json_marshaller.rb +68 -0
- data/lib/one_apm/support/json_wrapper.rb +130 -0
- data/lib/one_apm/support/language_support.rb +142 -0
- data/lib/one_apm/support/library_detection.rb +119 -0
- data/lib/one_apm/support/local_environment.rb +196 -0
- data/lib/one_apm/support/marshaller.rb +62 -0
- data/lib/one_apm/support/method_tracer.rb +334 -0
- data/lib/one_apm/support/method_tracer/helpers.rb +92 -0
- data/lib/one_apm/support/method_tracer/traced_method_stack.rb +103 -0
- data/lib/one_apm/support/obfuscator.rb +47 -0
- data/lib/one_apm/support/okjson.rb +601 -0
- data/lib/one_apm/support/parameter_filtering.rb +35 -0
- data/lib/one_apm/support/rules_engine.rb +56 -0
- data/lib/one_apm/support/rules_engine/replacement_rule.rb +80 -0
- data/lib/one_apm/support/rules_engine/segment_terms_rule.rb +46 -0
- data/lib/one_apm/support/server.rb +11 -0
- data/lib/one_apm/support/supported_versions.rb +257 -0
- data/lib/one_apm/support/system_info.rb +211 -0
- data/lib/one_apm/support/timer_lib.rb +29 -0
- data/lib/one_apm/support/version_number.rb +51 -0
- data/lib/one_apm/support/vm.rb +30 -0
- data/lib/one_apm/support/vm/jruby_vm.rb +38 -0
- data/lib/one_apm/support/vm/monotonic_gc_profiler.rb +43 -0
- data/lib/one_apm/support/vm/mri_vm.rb +85 -0
- data/lib/one_apm/support/vm/rubinius_vm.rb +129 -0
- data/lib/one_apm/support/vm/snapshot.rb +18 -0
- data/lib/one_apm/transaction.rb +336 -0
- data/lib/one_apm/transaction/class_methods.rb +132 -0
- data/lib/one_apm/transaction/instance_helpers.rb +82 -0
- data/lib/one_apm/transaction/metric_constants.rb +42 -0
- data/lib/one_apm/transaction/sample_buffer/force_persist_sample_buffer.rb +21 -0
- data/lib/one_apm/transaction/sample_buffer/slowest_sample_buffer.rb +21 -0
- data/lib/one_apm/transaction/sample_buffer/synthetics_sample_buffer.rb +21 -0
- data/lib/one_apm/transaction/sample_buffer/transaction_sample_buffer.rb +101 -0
- data/lib/one_apm/transaction/sample_buffer/xray_sample_buffer.rb +60 -0
- data/lib/one_apm/transaction/segment.rb +193 -0
- data/lib/one_apm/transaction/segment_summary.rb +51 -0
- data/lib/one_apm/transaction/thread_local_access.rb +73 -0
- data/lib/one_apm/transaction/transaction_analysis.rb +78 -0
- data/lib/one_apm/transaction/transaction_apdex.rb +20 -0
- data/lib/one_apm/transaction/transaction_cpu.rb +22 -0
- data/lib/one_apm/transaction/transaction_finish_append.rb +67 -0
- data/lib/one_apm/transaction/transaction_ignore.rb +33 -0
- data/lib/one_apm/transaction/transaction_jruby_functions.rb +40 -0
- data/lib/one_apm/transaction/transaction_metrics.rb +53 -0
- data/lib/one_apm/transaction/transaction_name.rb +90 -0
- data/lib/one_apm/transaction/transaction_namer.rb +49 -0
- data/lib/one_apm/transaction/transaction_sample.rb +204 -0
- data/lib/one_apm/transaction/transaction_sample_builder.rb +168 -0
- data/lib/one_apm/transaction/transaction_state.rb +149 -0
- data/lib/one_apm/transaction/transaction_summary.rb +28 -0
- data/lib/one_apm/transaction/transaction_synthetics.rb +40 -0
- data/lib/one_apm/transaction/transaction_timings.rb +54 -0
- data/lib/one_apm/version.rb +13 -0
- data/lib/oneapm_rpm.rb +16 -0
- data/lib/sequel/extensions/oneapm_instrumentation.rb +84 -0
- data/lib/sequel/plugins/oneapm_instrumentation.rb +66 -0
- data/oneapm.yml +135 -0
- data/oneapm_rpm.gemspec +58 -0
- metadata +474 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module OneApm
|
4
|
+
module Agent
|
5
|
+
module Instrumentation
|
6
|
+
module Sinatra
|
7
|
+
module Ignorer
|
8
|
+
|
9
|
+
def self.should_ignore?(app, type)
|
10
|
+
return false if !app.settings.respond_to?(:oneapm_ignores)
|
11
|
+
|
12
|
+
app.settings.oneapm_ignores[type].any? do |pattern|
|
13
|
+
pattern.match(app.request.path_info)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def oneapm_ignore(*routes)
|
18
|
+
set_oneapm_ignore(:routes, *routes)
|
19
|
+
end
|
20
|
+
|
21
|
+
def oneapm_ignore_apdex(*routes)
|
22
|
+
set_oneapm_ignore(:apdex, *routes)
|
23
|
+
end
|
24
|
+
|
25
|
+
def oneapm_ignore_enduser(*routes)
|
26
|
+
set_oneapm_ignore(:enduser, *routes)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def set_oneapm_ignore(type, *routes)
|
32
|
+
# Important to default this in the context of the actual app
|
33
|
+
# If it's done at register time, ignores end up shared between apps.
|
34
|
+
set :oneapm_ignores, Hash.new([]) if !respond_to?(:oneapm_ignores)
|
35
|
+
|
36
|
+
# If we call an ignore without a route, it applies to the whole app
|
37
|
+
routes = ["*"] if routes.empty?
|
38
|
+
|
39
|
+
settings.oneapm_ignores[type] += routes.map do |r|
|
40
|
+
# Ugly sending to private Base#compile, but we want to mimic
|
41
|
+
# exactly Sinatra's mapping of route text to regex
|
42
|
+
send(:compile, r).first
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module OneApm
|
4
|
+
module Agent
|
5
|
+
module Instrumentation
|
6
|
+
module Sinatra
|
7
|
+
module TransactionNamer
|
8
|
+
extend self
|
9
|
+
|
10
|
+
def transaction_name_for_route(env, request)
|
11
|
+
name = route_for_sinatra(env)
|
12
|
+
name = route_name_for_padrino(request) if name.nil?
|
13
|
+
|
14
|
+
transaction_name(name, request) unless name.nil?
|
15
|
+
end
|
16
|
+
|
17
|
+
def initial_transaction_name(request)
|
18
|
+
transaction_name(OneApm::Transaction::UNKNOWN_METRIC, request)
|
19
|
+
end
|
20
|
+
|
21
|
+
def transaction_name(route_text, request)
|
22
|
+
verb = http_verb(request)
|
23
|
+
|
24
|
+
route_text = route_text.source if route_text.is_a?(Regexp)
|
25
|
+
name = route_text.gsub(%r{^[/^\\A]*(.*?)[/\$\?\\z]*$}, '\1')
|
26
|
+
name = "#{verb} #{name}" unless verb.nil?
|
27
|
+
name
|
28
|
+
rescue => e
|
29
|
+
::OneApm::Agent.logger.debug("#{e.class} : #{e.message} - Error encountered trying to identify Sinatra transaction name")
|
30
|
+
OneApm::Transaction::UNKNOWN_METRIC
|
31
|
+
end
|
32
|
+
|
33
|
+
def http_verb(request)
|
34
|
+
request.request_method if request.respond_to?(:request_method)
|
35
|
+
end
|
36
|
+
|
37
|
+
# For bare Sinatra, our override on process_route captures the last
|
38
|
+
# route into the environment for us to use later on
|
39
|
+
def route_for_sinatra(env)
|
40
|
+
env["oneapm.last_route"]
|
41
|
+
end
|
42
|
+
|
43
|
+
# For Padrino, the request object has a copy of the matched route
|
44
|
+
# on it when we go to evaluating, so we can just retrieve that
|
45
|
+
def route_name_for_padrino(request)
|
46
|
+
request.route_obj.original_path
|
47
|
+
rescue
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
LibraryDetection.defer do
|
4
|
+
named :curb
|
5
|
+
|
6
|
+
CURB_MINIMUM_VERSION = ::OneApm::VersionNumber.new("0.8.1")
|
7
|
+
|
8
|
+
depends_on do
|
9
|
+
defined?(::Curl) && defined?(::Curl::CURB_VERSION) &&
|
10
|
+
::OneApm::VersionNumber.new(::Curl::CURB_VERSION) >= CURB_MINIMUM_VERSION
|
11
|
+
end
|
12
|
+
|
13
|
+
executes do
|
14
|
+
::OneApm::Agent.logger.info 'Installing Curb instrumentation'
|
15
|
+
require 'one_apm/agent/cross_app/cross_app_tracing'
|
16
|
+
require 'one_apm/support/http_clients/curb_wrappers'
|
17
|
+
end
|
18
|
+
|
19
|
+
executes do
|
20
|
+
class Curl::Easy
|
21
|
+
|
22
|
+
attr_accessor :_oa_instrumented,
|
23
|
+
:_oa_http_verb,
|
24
|
+
:_oa_header_str,
|
25
|
+
:_oa_original_on_header,
|
26
|
+
:_oa_original_on_complete,
|
27
|
+
:_oa_serial
|
28
|
+
|
29
|
+
# We have to hook these three methods separately, as they don't use
|
30
|
+
# Curl::Easy#http
|
31
|
+
def http_head_with_oneapm(*args, &blk)
|
32
|
+
self._oa_http_verb = :HEAD
|
33
|
+
http_head_without_oneapm(*args, &blk)
|
34
|
+
end
|
35
|
+
alias_method :http_head_without_oneapm, :http_head
|
36
|
+
alias_method :http_head, :http_head_with_oneapm
|
37
|
+
|
38
|
+
def http_post_with_oneapm(*args, &blk)
|
39
|
+
self._oa_http_verb = :POST
|
40
|
+
http_post_without_oneapm(*args, &blk)
|
41
|
+
end
|
42
|
+
alias_method :http_post_without_oneapm, :http_post
|
43
|
+
alias_method :http_post, :http_post_with_oneapm
|
44
|
+
|
45
|
+
def http_put_with_oneapm(*args, &blk)
|
46
|
+
self._oa_http_verb = :PUT
|
47
|
+
http_put_without_oneapm(*args, &blk)
|
48
|
+
end
|
49
|
+
alias_method :http_put_without_oneapm, :http_put
|
50
|
+
alias_method :http_put, :http_put_with_oneapm
|
51
|
+
|
52
|
+
|
53
|
+
# Hook the #http method to set the verb.
|
54
|
+
def http_with_oneapm( verb )
|
55
|
+
self._oa_http_verb = verb.to_s.upcase
|
56
|
+
http_without_oneapm( verb )
|
57
|
+
end
|
58
|
+
|
59
|
+
alias_method :http_without_oneapm, :http
|
60
|
+
alias_method :http, :http_with_oneapm
|
61
|
+
|
62
|
+
|
63
|
+
# Hook the #perform method to mark the request as non-parallel.
|
64
|
+
def perform_with_oneapm
|
65
|
+
self._oa_serial = true
|
66
|
+
perform_without_oneapm
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_method :perform_without_oneapm, :perform
|
70
|
+
alias_method :perform, :perform_with_oneapm
|
71
|
+
|
72
|
+
# We override this method in order to ensure access to header_str even
|
73
|
+
# though we use an on_header callback
|
74
|
+
def header_str_with_oneapm
|
75
|
+
if self._oa_serial
|
76
|
+
self._oa_header_str
|
77
|
+
else
|
78
|
+
# Since we didn't install a header callback for a non-serial request,
|
79
|
+
# just fall back to the original implementation.
|
80
|
+
header_str_without_oneapm
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
alias_method :header_str_without_oneapm, :header_str
|
85
|
+
alias_method :header_str, :header_str_with_oneapm
|
86
|
+
end # class Curl::Easy
|
87
|
+
|
88
|
+
|
89
|
+
class Curl::Multi
|
90
|
+
include OneApm::Support::MethodTracer
|
91
|
+
|
92
|
+
# Add CAT with callbacks if the request is serial
|
93
|
+
def add_with_oneapm(curl) #THREAD_LOCAL_ACCESS
|
94
|
+
if curl.respond_to?(:_oa_serial) && curl._oa_serial
|
95
|
+
hook_pending_request(curl) if OneApm::Agent.tl_is_execution_traced?
|
96
|
+
end
|
97
|
+
|
98
|
+
return add_without_oneapm( curl )
|
99
|
+
end
|
100
|
+
|
101
|
+
alias_method :add_without_oneapm, :add
|
102
|
+
alias_method :add, :add_with_oneapm
|
103
|
+
|
104
|
+
|
105
|
+
# Trace as an External/Multiple call if the first request isn't serial.
|
106
|
+
def perform_with_oneapm(&blk)
|
107
|
+
return perform_without_oneapm if
|
108
|
+
self.requests.first &&
|
109
|
+
self.requests.first.respond_to?(:_oa_serial) &&
|
110
|
+
self.requests.first._oa_serial
|
111
|
+
|
112
|
+
trace_execution_scoped("External/Multiple/Curb::Multi/perform") do
|
113
|
+
perform_without_oneapm(&blk)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
alias_method :perform_without_oneapm, :perform
|
118
|
+
alias_method :perform, :perform_with_oneapm
|
119
|
+
|
120
|
+
|
121
|
+
# Instrument the specified +request+ (a Curl::Easy object) and set up cross-application
|
122
|
+
# tracing if it's enabled.
|
123
|
+
def hook_pending_request(request) #THREAD_LOCAL_ACCESS
|
124
|
+
wrapped_request, wrapped_response = wrap_request(request)
|
125
|
+
state = OneApm::TransactionState.tl_get
|
126
|
+
t0 = Time.now
|
127
|
+
segment = OneApm::Agent::CrossAppTracing.start_trace(state, t0, wrapped_request)
|
128
|
+
|
129
|
+
unless request._oa_instrumented
|
130
|
+
install_header_callback(request, wrapped_response)
|
131
|
+
install_completion_callback(request, t0, segment, wrapped_request, wrapped_response)
|
132
|
+
request._oa_instrumented = true
|
133
|
+
end
|
134
|
+
rescue => err
|
135
|
+
OneApm::Agent.logger.error("Untrapped exception", err)
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
# Create request and response adapter objects for the specified +request+
|
140
|
+
def wrap_request(request)
|
141
|
+
return OneApm::Support::HTTPClients::CurbRequest.new(request),
|
142
|
+
OneApm::Support::HTTPClients::CurbResponse.new(request)
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
# Install a callback that will record the response headers to enable
|
147
|
+
# CAT linking
|
148
|
+
def install_header_callback( request, wrapped_response )
|
149
|
+
original_callback = request.on_header
|
150
|
+
request._oa_original_on_header = original_callback
|
151
|
+
request._oa_header_str = ''
|
152
|
+
request.on_header do |header_data|
|
153
|
+
wrapped_response.append_header_data( header_data )
|
154
|
+
|
155
|
+
if original_callback
|
156
|
+
original_callback.call( header_data )
|
157
|
+
else
|
158
|
+
header_data.length
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Install a callback that will finish the trace.
|
164
|
+
def install_completion_callback(request, t0, segment, wrapped_request, wrapped_response) #THREAD_LOCAL_ACCESS
|
165
|
+
original_callback = request.on_complete
|
166
|
+
request._oa_original_on_complete = original_callback
|
167
|
+
request.on_complete do |finished_request|
|
168
|
+
begin
|
169
|
+
state = OneApm::TransactionState.tl_get
|
170
|
+
OneApm::Agent::CrossAppTracing.finish_trace(state, t0, segment, wrapped_request, wrapped_response)
|
171
|
+
ensure
|
172
|
+
# Make sure the existing completion callback is run, and restore the
|
173
|
+
# on_complete callback to how it was before.
|
174
|
+
original_callback.call(finished_request) if original_callback
|
175
|
+
remove_instrumentation_callbacks(request)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def remove_instrumentation_callbacks(request)
|
181
|
+
request.on_complete(&request._oa_original_on_complete)
|
182
|
+
request.on_header(&request._oa_original_on_header)
|
183
|
+
request._oa_instrumented = false
|
184
|
+
end
|
185
|
+
|
186
|
+
end # class Curl::Multi
|
187
|
+
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
LibraryDetection.defer do
|
4
|
+
named :excon
|
5
|
+
|
6
|
+
# We have two ways of instrumenting Excon:
|
7
|
+
# - For newer versions, use the middleware mechanism Excon exposes
|
8
|
+
# - For older versions, monkey-patch Excon::Connection#request
|
9
|
+
#
|
10
|
+
# EXCON_MINIMUM_VERSION is the minimum version we attempt to instrument at all.
|
11
|
+
# EXCON_MIDDLEWARE_MINIMUM_VERSION is the min version we use the newer
|
12
|
+
# instrumentation for.
|
13
|
+
#
|
14
|
+
# Note that middlewares were added to Excon prior to 0.19, but we don't
|
15
|
+
# use middleware-based instrumentation prior to that version because it didn't
|
16
|
+
# expose a way for middlewares to know about request failures.
|
17
|
+
#
|
18
|
+
# Why don't we use Excon.defaults[:instrumentor]?
|
19
|
+
# While this might seem a perfect fit, it unfortunately isn't suitable in
|
20
|
+
# current form. Someone might reasonably set the default instrumentor to
|
21
|
+
# something else after we install our instrumentation. Ideally, excon would
|
22
|
+
# itself conform to the #subscribe interface of ActiveSupport::Notifications,
|
23
|
+
# so we could safely subscribe and not be clobbered by future subscribers,
|
24
|
+
# but alas, it does not yet.
|
25
|
+
|
26
|
+
EXCON_MINIMUM_VERSION = ::OneApm::VersionNumber.new("0.10.1")
|
27
|
+
EXCON_MIDDLEWARE_MINIMUM_VERSION = ::OneApm::VersionNumber.new("0.19.0")
|
28
|
+
|
29
|
+
depends_on do
|
30
|
+
defined?(::Excon) && defined?(::Excon::VERSION)
|
31
|
+
end
|
32
|
+
|
33
|
+
executes do
|
34
|
+
excon_version = OneApm::VersionNumber.new(::Excon::VERSION)
|
35
|
+
if excon_version >= EXCON_MINIMUM_VERSION
|
36
|
+
install_excon_instrumentation(excon_version)
|
37
|
+
else
|
38
|
+
::OneApm::Agent.logger.warn("Excon instrumentation requires at least version #{EXCON_MINIMUM_VERSION}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def install_excon_instrumentation(excon_version)
|
43
|
+
require 'one_apm/agent/cross_app/cross_app_tracing'
|
44
|
+
require 'one_apm/support/http_clients/excon_wrappers'
|
45
|
+
|
46
|
+
if excon_version >= EXCON_MIDDLEWARE_MINIMUM_VERSION
|
47
|
+
install_middleware_excon_instrumentation
|
48
|
+
else
|
49
|
+
install_legacy_excon_instrumentation
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def install_middleware_excon_instrumentation
|
54
|
+
::OneApm::Agent.logger.info 'Installing middleware-based Excon instrumentation'
|
55
|
+
require 'one_apm/inst/http_clients/excon/middleware'
|
56
|
+
defaults = Excon.defaults
|
57
|
+
|
58
|
+
if defaults[:middlewares]
|
59
|
+
defaults[:middlewares] << ::Excon::Middleware::OneApmCrossAppTracing
|
60
|
+
else
|
61
|
+
::OneApm::Agent.logger.warn("Did not find :middlewares key in Excon.defaults, skipping Excon instrumentation")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def install_legacy_excon_instrumentation
|
66
|
+
::OneApm::Agent.logger.info 'Installing legacy Excon instrumentation'
|
67
|
+
require 'one_apm/inst/http_clients/excon/connection'
|
68
|
+
::Excon::Connection.install_oneapm_instrumentation
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module ::Excon
|
4
|
+
class Connection
|
5
|
+
def oneapm_connection_params
|
6
|
+
(@connection || @data)
|
7
|
+
end
|
8
|
+
|
9
|
+
def oneapm_resolved_request_params(request_params)
|
10
|
+
resolved = oneapm_connection_params.merge(request_params)
|
11
|
+
resolved[:headers] = resolved[:headers].merge(request_params[:headers] || {})
|
12
|
+
resolved
|
13
|
+
end
|
14
|
+
|
15
|
+
def request_with_oneapm_trace(params, &block)
|
16
|
+
orig_response = nil
|
17
|
+
resolved_params = oneapm_resolved_request_params(params)
|
18
|
+
wrapped_request = ::OneApm::Support::HTTPClients::ExconHTTPRequest.new(resolved_params)
|
19
|
+
::OneApm::Agent::CrossAppTracing.tl_trace_http_request(wrapped_request) do
|
20
|
+
orig_response = request_without_oneapm_trace(resolved_params, &block)
|
21
|
+
::OneApm::Support::HTTPClients::ExconHTTPResponse.new(orig_response)
|
22
|
+
end
|
23
|
+
orig_response
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.install_oneapm_instrumentation
|
27
|
+
alias request_without_oneapm_trace request
|
28
|
+
alias request request_with_oneapm_trace
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module ::Excon
|
4
|
+
module Middleware
|
5
|
+
class OneApmCrossAppTracing
|
6
|
+
TRACE_DATA_IVAR = :@oneapm_trace_data
|
7
|
+
|
8
|
+
def initialize(stack)
|
9
|
+
@stack = stack
|
10
|
+
end
|
11
|
+
|
12
|
+
def request_call(datum) #THREAD_LOCAL_ACCESS
|
13
|
+
begin
|
14
|
+
# Only instrument this request if we haven't already done so, because
|
15
|
+
# we can get request_call multiple times for requests marked as
|
16
|
+
# :idempotent in the options, but there will be only a single
|
17
|
+
# accompanying response_call/error_call.
|
18
|
+
if datum[:connection] && !datum[:connection].instance_variable_get(TRACE_DATA_IVAR)
|
19
|
+
wrapped_request = ::OneApm::Support::HTTPClients::ExconHTTPRequest.new(datum)
|
20
|
+
state = ::OneApm::TransactionState.tl_get
|
21
|
+
t0 = Time.now
|
22
|
+
segment = ::OneApm::Agent::CrossAppTracing.start_trace(state, t0, wrapped_request)
|
23
|
+
datum[:connection].instance_variable_set(TRACE_DATA_IVAR, [t0, segment, wrapped_request])
|
24
|
+
end
|
25
|
+
rescue => e
|
26
|
+
OneApm::Agent.logger.debug(e)
|
27
|
+
end
|
28
|
+
@stack.request_call(datum)
|
29
|
+
end
|
30
|
+
|
31
|
+
def response_call(datum)
|
32
|
+
finish_trace(datum)
|
33
|
+
@stack.response_call(datum)
|
34
|
+
end
|
35
|
+
|
36
|
+
def error_call(datum)
|
37
|
+
finish_trace(datum)
|
38
|
+
@stack.error_call(datum)
|
39
|
+
end
|
40
|
+
|
41
|
+
def finish_trace(datum) #THREAD_LOCAL_ACCESS
|
42
|
+
trace_data = datum[:connection] && datum[:connection].instance_variable_get(TRACE_DATA_IVAR)
|
43
|
+
if trace_data
|
44
|
+
datum[:connection].instance_variable_set(TRACE_DATA_IVAR, nil)
|
45
|
+
t0, segment, wrapped_request = trace_data
|
46
|
+
if datum[:response]
|
47
|
+
wrapped_response = ::OneApm::Support::HTTPClients::ExconHTTPResponse.new(datum[:response])
|
48
|
+
end
|
49
|
+
state = ::OneApm::TransactionState.tl_get
|
50
|
+
::OneApm::Agent::CrossAppTracing.finish_trace(state, t0, segment, wrapped_request, wrapped_response)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|