instana 1.10.1-java
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 +23 -0
- data/.gitignore +16 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +43 -0
- data/Configuration.md +149 -0
- data/Dockerfile +13 -0
- data/Gemfile +41 -0
- data/LICENSE +21 -0
- data/README.md +102 -0
- data/Rakefile +56 -0
- data/Tracing.md +145 -0
- data/Troubleshooting.md +32 -0
- data/benchmarks/Gemfile +7 -0
- data/benchmarks/id_generation.rb +12 -0
- data/benchmarks/opentracing.rb +26 -0
- data/benchmarks/rack_vanilla_vs_traced.rb +80 -0
- data/benchmarks/stackprof_rack_tracing.rb +77 -0
- data/benchmarks/time_processing.rb +12 -0
- data/bin/console +7 -0
- data/bin/setup +8 -0
- data/examples/opentracing.rb +31 -0
- data/examples/tracing.rb +80 -0
- data/gemfiles/libraries.gemfile +71 -0
- data/gemfiles/rails32.gemfile +51 -0
- data/gemfiles/rails42.gemfile +50 -0
- data/gemfiles/rails50.gemfile +52 -0
- data/instana.gemspec +46 -0
- data/lib/instana.rb +12 -0
- data/lib/instana/agent.rb +441 -0
- data/lib/instana/agent/helpers.rb +61 -0
- data/lib/instana/agent/hooks.rb +37 -0
- data/lib/instana/agent/tasks.rb +48 -0
- data/lib/instana/base.rb +54 -0
- data/lib/instana/collector.rb +116 -0
- data/lib/instana/collectors/gc.rb +57 -0
- data/lib/instana/collectors/memory.rb +34 -0
- data/lib/instana/collectors/thread.rb +30 -0
- data/lib/instana/config.rb +79 -0
- data/lib/instana/eum/eum-test.js.erb +16 -0
- data/lib/instana/eum/eum.js.erb +14 -0
- data/lib/instana/frameworks/cuba.rb +6 -0
- data/lib/instana/frameworks/instrumentation/abstract_mysql_adapter.rb +58 -0
- data/lib/instana/frameworks/instrumentation/action_controller.rb +183 -0
- data/lib/instana/frameworks/instrumentation/action_view.rb +43 -0
- data/lib/instana/frameworks/instrumentation/active_record.rb +27 -0
- data/lib/instana/frameworks/instrumentation/mysql2_adapter.rb +81 -0
- data/lib/instana/frameworks/instrumentation/mysql_adapter.rb +56 -0
- data/lib/instana/frameworks/instrumentation/postgresql_adapter.rb +71 -0
- data/lib/instana/frameworks/rails.rb +42 -0
- data/lib/instana/frameworks/roda.rb +6 -0
- data/lib/instana/frameworks/sinatra.rb +9 -0
- data/lib/instana/helpers.rb +40 -0
- data/lib/instana/instrumentation.rb +21 -0
- data/lib/instana/instrumentation/dalli.rb +78 -0
- data/lib/instana/instrumentation/excon.rb +74 -0
- data/lib/instana/instrumentation/grpc.rb +84 -0
- data/lib/instana/instrumentation/net-http.rb +66 -0
- data/lib/instana/instrumentation/rack.rb +77 -0
- data/lib/instana/instrumentation/redis.rb +82 -0
- data/lib/instana/instrumentation/resque.rb +131 -0
- data/lib/instana/instrumentation/rest-client.rb +34 -0
- data/lib/instana/instrumentation/sidekiq-client.rb +45 -0
- data/lib/instana/instrumentation/sidekiq-worker.rb +54 -0
- data/lib/instana/opentracing/carrier.rb +4 -0
- data/lib/instana/opentracing/tracer.rb +18 -0
- data/lib/instana/rack.rb +10 -0
- data/lib/instana/setup.rb +36 -0
- data/lib/instana/test.rb +40 -0
- data/lib/instana/thread_local.rb +15 -0
- data/lib/instana/tracer.rb +392 -0
- data/lib/instana/tracing/processor.rb +92 -0
- data/lib/instana/tracing/span.rb +401 -0
- data/lib/instana/tracing/span_context.rb +33 -0
- data/lib/instana/util.rb +261 -0
- data/lib/instana/version.rb +4 -0
- data/lib/oj_check.rb +16 -0
- data/lib/opentracing.rb +6 -0
- data/test/agent/agent_test.rb +143 -0
- data/test/apps/cuba.rb +15 -0
- data/test/apps/grpc_server.rb +81 -0
- data/test/apps/roda.rb +10 -0
- data/test/apps/sinatra.rb +5 -0
- data/test/benchmarks/bench_id_generation.rb +12 -0
- data/test/benchmarks/bench_opentracing.rb +13 -0
- data/test/config_test.rb +37 -0
- data/test/frameworks/cuba_test.rb +44 -0
- data/test/frameworks/rack_test.rb +167 -0
- data/test/frameworks/rails/actioncontroller_test.rb +93 -0
- data/test/frameworks/rails/actionview3_test.rb +255 -0
- data/test/frameworks/rails/actionview4_test.rb +254 -0
- data/test/frameworks/rails/actionview5_test.rb +221 -0
- data/test/frameworks/rails/activerecord3_test.rb +134 -0
- data/test/frameworks/rails/activerecord4_test.rb +134 -0
- data/test/frameworks/rails/activerecord5_test.rb +87 -0
- data/test/frameworks/roda_test.rb +44 -0
- data/test/frameworks/sinatra_test.rb +44 -0
- data/test/instana_test.rb +27 -0
- data/test/instrumentation/dalli_test.rb +253 -0
- data/test/instrumentation/excon_test.rb +147 -0
- data/test/instrumentation/grpc_test.rb +377 -0
- data/test/instrumentation/net-http_test.rb +160 -0
- data/test/instrumentation/redis_test.rb +119 -0
- data/test/instrumentation/resque_test.rb +128 -0
- data/test/instrumentation/rest-client_test.rb +55 -0
- data/test/instrumentation/sidekiq-client_test.rb +125 -0
- data/test/instrumentation/sidekiq-worker_test.rb +173 -0
- data/test/jobs/resque_error_job.rb +22 -0
- data/test/jobs/resque_fast_job.rb +20 -0
- data/test/jobs/sidekiq_job_1.rb +6 -0
- data/test/jobs/sidekiq_job_2.rb +7 -0
- data/test/models/block.rb +18 -0
- data/test/servers/grpc_50051.rb +20 -0
- data/test/servers/helpers/sidekiq_worker_initializer.rb +27 -0
- data/test/servers/rackapp_6511.rb +25 -0
- data/test/servers/rails_3205.rb +167 -0
- data/test/servers/sidekiq/worker.rb +27 -0
- data/test/test_helper.rb +145 -0
- data/test/tracing/custom_test.rb +158 -0
- data/test/tracing/id_management_test.rb +130 -0
- data/test/tracing/opentracing_test.rb +335 -0
- data/test/tracing/trace_test.rb +67 -0
- data/test/tracing/tracer_async_test.rb +198 -0
- data/test/tracing/tracer_test.rb +223 -0
- metadata +327 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Instana
|
|
2
|
+
module Instrumentation
|
|
3
|
+
module MysqlAdapter
|
|
4
|
+
IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN CACHE).freeze
|
|
5
|
+
EXPLAINED_SQLS = /\A\s*(with|select|update|delete|insert)\b/i
|
|
6
|
+
|
|
7
|
+
# This module supports instrumenting ActiveRecord with the mysql2 adapter.
|
|
8
|
+
#
|
|
9
|
+
def self.included(klass)
|
|
10
|
+
if ActiveRecord::VERSION::STRING >= '3.2'
|
|
11
|
+
Instana::Util.method_alias(klass, :exec_query)
|
|
12
|
+
|
|
13
|
+
@@sanitize_regexp = Regexp.new('(\'[\s\S][^\']*\'|\d*\.\d+|\d+|NULL)', Regexp::IGNORECASE)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Collect up this DB connection info for reporting.
|
|
18
|
+
#
|
|
19
|
+
# @param sql [String]
|
|
20
|
+
# @return [Hash] Hash of collected KVs
|
|
21
|
+
#
|
|
22
|
+
def collect(sql)
|
|
23
|
+
payload = { :activerecord => {} }
|
|
24
|
+
payload[:activerecord][:sql] = sql.gsub(@@sanitize_regexp, '?')
|
|
25
|
+
payload[:activerecord][:adapter] = @config[:adapter]
|
|
26
|
+
payload[:activerecord][:host] = @config[:host]
|
|
27
|
+
payload[:activerecord][:db] = @config[:database]
|
|
28
|
+
payload[:activerecord][:username] = @config[:username]
|
|
29
|
+
payload
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# In the spirit of ::ActiveRecord::ExplainSubscriber.ignore_payload? There are
|
|
33
|
+
# only certain calls that we're interested in tracing. e.g. No use to instrument
|
|
34
|
+
# framework caches.
|
|
35
|
+
#
|
|
36
|
+
# @param payload [String]
|
|
37
|
+
# @return [Boolean]
|
|
38
|
+
#
|
|
39
|
+
def ignore_payload?(name, sql)
|
|
40
|
+
IGNORED_PAYLOADS.include?(name) || sql !~ EXPLAINED_SQLS
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def exec_query_with_instana(sql, name = 'SQL', binds = [], *args)
|
|
44
|
+
if !::Instana.tracer.tracing? || ignore_payload?(name, sql) ||
|
|
45
|
+
::Instana.tracer.current_span[:n] == :activerecord
|
|
46
|
+
return exec_query_without_instana(sql, name, binds, *args)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
kv_payload = collect(sql)
|
|
50
|
+
::Instana.tracer.trace(:activerecord, kv_payload) do
|
|
51
|
+
exec_query_without_instana(sql, name, binds, *args)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module Instana
|
|
2
|
+
module Instrumentation
|
|
3
|
+
module PostgreSQLAdapter
|
|
4
|
+
IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN CACHE).freeze
|
|
5
|
+
EXPLAINED_SQLS = /\A\s*(with|select|update|delete|insert)\b/i
|
|
6
|
+
|
|
7
|
+
# This module supports instrumenting ActiveRecord with the postgresql adapter. Only
|
|
8
|
+
# versions >= 3.1 are supported.
|
|
9
|
+
#
|
|
10
|
+
def self.included(klass)
|
|
11
|
+
if (::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR > 0) ||
|
|
12
|
+
::ActiveRecord::VERSION::MAJOR >= 4
|
|
13
|
+
|
|
14
|
+
# ActiveRecord 3.1 and up
|
|
15
|
+
Instana::Util.method_alias(klass, :exec_query)
|
|
16
|
+
Instana::Util.method_alias(klass, :exec_delete)
|
|
17
|
+
|
|
18
|
+
@@sanitize_regexp = Regexp.new('(\'[\s\S][^\']*\'|\d*\.\d+|\d+|NULL)', Regexp::IGNORECASE)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Collect up this DB connection info for reporting.
|
|
23
|
+
#
|
|
24
|
+
# @param sql [String]
|
|
25
|
+
# @return [Hash] Hash of collected KVs
|
|
26
|
+
#
|
|
27
|
+
def collect(sql)
|
|
28
|
+
payload = { :activerecord => {} }
|
|
29
|
+
payload[:activerecord][:sql] = sql.gsub(@@sanitize_regexp, '?')
|
|
30
|
+
payload[:activerecord][:adapter] = @config[:adapter]
|
|
31
|
+
payload[:activerecord][:host] = @config[:host]
|
|
32
|
+
payload[:activerecord][:db] = @config[:database]
|
|
33
|
+
payload[:activerecord][:username] = @config[:username]
|
|
34
|
+
payload
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# In the spirit of ::ActiveRecord::ExplainSubscriber.ignore_payload? There are
|
|
38
|
+
# only certain calls that we're interested in tracing. e.g. No use to instrument
|
|
39
|
+
# framework caches.
|
|
40
|
+
#
|
|
41
|
+
# @param payload [String]
|
|
42
|
+
# @return [Boolean]
|
|
43
|
+
#
|
|
44
|
+
def ignore_payload?(name, sql)
|
|
45
|
+
IGNORED_PAYLOADS.include?(name) || sql !~ EXPLAINED_SQLS
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def exec_query_with_instana(sql, name = 'SQL', binds = [], *args)
|
|
49
|
+
if !::Instana.tracer.tracing? || ignore_payload?(name, sql)
|
|
50
|
+
return exec_query_without_instana(sql, name, binds, *args)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
kv_payload = collect(sql)
|
|
54
|
+
::Instana.tracer.trace(:activerecord, kv_payload) do
|
|
55
|
+
exec_query_without_instana(sql, name, binds, *args)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def exec_delete_with_instana(sql, name = nil, binds = [])
|
|
60
|
+
if !::Instana.tracer.tracing? || ignore_payload?(name, sql)
|
|
61
|
+
return exec_delete_without_instana(sql, name, binds)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
kv_payload = collect(sql)
|
|
65
|
+
::Instana.tracer.trace(:activerecord, kv_payload) do
|
|
66
|
+
exec_delete_without_instana(sql, name, binds)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require "instana/rack"
|
|
2
|
+
|
|
3
|
+
if defined?(::Rails)
|
|
4
|
+
|
|
5
|
+
if ::Rails::VERSION::MAJOR < 3
|
|
6
|
+
::Rails.configuration.after_initialize do
|
|
7
|
+
# In Rails, let's use the Rails logger
|
|
8
|
+
::Instana.logger = ::Rails.logger if ::Rails.logger
|
|
9
|
+
|
|
10
|
+
if ::Instana.config[:tracing][:enabled]
|
|
11
|
+
::Instana.logger.info "Instrumenting Rack"
|
|
12
|
+
::Rails.configuration.middleware.insert 0, ::Instana::Rack
|
|
13
|
+
else
|
|
14
|
+
::Instana.logger.info "Rack: Tracing disabled via config. Not enabling middleware."
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
module ::Instana
|
|
19
|
+
class Railtie < ::Rails::Railtie
|
|
20
|
+
initializer 'instana.rack' do |app|
|
|
21
|
+
# In Rails, let's use the Rails logger
|
|
22
|
+
::Instana.logger = ::Rails.logger if ::Rails.logger
|
|
23
|
+
|
|
24
|
+
if ::Instana.config[:tracing][:enabled]
|
|
25
|
+
::Instana.logger.info "Instrumenting Rack"
|
|
26
|
+
app.config.middleware.insert 0, ::Instana::Rack
|
|
27
|
+
else
|
|
28
|
+
::Instana.logger.info "Rack: Tracing disabled via config. Not enabling middleware."
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if ::Instana.config[:tracing][:enabled]
|
|
33
|
+
config.after_initialize do
|
|
34
|
+
require "instana/frameworks/instrumentation/active_record"
|
|
35
|
+
require "instana/frameworks/instrumentation/action_controller"
|
|
36
|
+
require "instana/frameworks/instrumentation/action_view"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Instana
|
|
2
|
+
module Helpers
|
|
3
|
+
EUM_SNIPPET= (File.read(File.dirname(__FILE__) + '/eum/eum.js.erb')).freeze
|
|
4
|
+
EUM_TEST_SNIPPET= (File.read(File.dirname(__FILE__) + '/eum/eum-test.js.erb')).freeze
|
|
5
|
+
|
|
6
|
+
class << self
|
|
7
|
+
|
|
8
|
+
# Returns a processed javascript snippet to be placed within the HEAD tag of an HTML page.
|
|
9
|
+
#
|
|
10
|
+
def eum_snippet(api_key, kvs = {})
|
|
11
|
+
return nil if !::Instana.tracer.tracing?
|
|
12
|
+
|
|
13
|
+
::Instana.config[:eum_api_key] = api_key
|
|
14
|
+
::Instana.config[:eum_baggage] = kvs
|
|
15
|
+
|
|
16
|
+
ERB.new(EUM_SNIPPET).result
|
|
17
|
+
rescue => e
|
|
18
|
+
Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
|
19
|
+
Instana.logger.debug { e.backtrace.join("\r\n") }
|
|
20
|
+
return nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Returns a processed javascript snippet to be placed within the HEAD tag of an HTML page.
|
|
24
|
+
# This one is used for testing only
|
|
25
|
+
#
|
|
26
|
+
def eum_test_snippet(api_key, kvs = {})
|
|
27
|
+
return nil if !::Instana.tracer.tracing?
|
|
28
|
+
|
|
29
|
+
::Instana.config[:eum_api_key] = api_key
|
|
30
|
+
::Instana.config[:eum_baggage] = kvs
|
|
31
|
+
|
|
32
|
+
ERB.new(EUM_TEST_SNIPPET).result
|
|
33
|
+
rescue => e
|
|
34
|
+
Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
|
35
|
+
Instana.logger.debug { e.backtrace.join("\r\n") }
|
|
36
|
+
return nil
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Instana
|
|
2
|
+
AUTOLOAD_DIRECTORIES = [:instrumentation, :frameworks].freeze
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
if !ENV.key?('INSTANA_DISABLE_AUTO_INSTR') || ENV['INSTANA_DISABLE_AUTO_INSTR'] === 'false'
|
|
7
|
+
#
|
|
8
|
+
# Load all of the files in the specified subdirectories
|
|
9
|
+
#
|
|
10
|
+
::Instana::AUTOLOAD_DIRECTORIES.each do |d|
|
|
11
|
+
pattern = File.join(File.dirname(__FILE__), d.to_s, '*.rb')
|
|
12
|
+
Dir.glob(pattern) do |f|
|
|
13
|
+
begin
|
|
14
|
+
require f
|
|
15
|
+
rescue => e
|
|
16
|
+
Instana.logger.error "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
|
17
|
+
Instana.logger.debug { e.backtrace.join("\r\n") }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
module Instana
|
|
2
|
+
module Instrumentation
|
|
3
|
+
module Dalli
|
|
4
|
+
def self.included(klass)
|
|
5
|
+
::Instana::Util.method_alias(klass, :perform)
|
|
6
|
+
::Instana::Util.method_alias(klass, :get_multi)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def perform_with_instana(*args, &blk)
|
|
10
|
+
if !::Instana.tracer.tracing? || ::Instana.tracer.tracing_span?(:memcache)
|
|
11
|
+
do_skip = true
|
|
12
|
+
return perform_without_instana(*args, &blk)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
op, key, *_opts = args
|
|
16
|
+
|
|
17
|
+
entry_payload = { :memcache => {} }
|
|
18
|
+
entry_payload[:memcache][:namespace] = @options[:namespace] if @options.key?(:namespace)
|
|
19
|
+
entry_payload[:memcache][:command] = op
|
|
20
|
+
entry_payload[:memcache][:key] = key
|
|
21
|
+
|
|
22
|
+
::Instana.tracer.log_entry(:memcache, entry_payload)
|
|
23
|
+
result = perform_without_instana(*args, &blk)
|
|
24
|
+
|
|
25
|
+
kv_payload = { :memcache => {}}
|
|
26
|
+
if op == :get
|
|
27
|
+
kv_payload[:memcache][:hit] = result ? 1 : 0
|
|
28
|
+
end
|
|
29
|
+
result
|
|
30
|
+
rescue => e
|
|
31
|
+
::Instana.tracer.log_error(e)
|
|
32
|
+
raise
|
|
33
|
+
ensure
|
|
34
|
+
::Instana.tracer.log_exit(:memcache, kv_payload) unless do_skip
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def get_multi_with_instana(*keys)
|
|
38
|
+
entry_payload = { :memcache => {} }
|
|
39
|
+
entry_payload[:memcache][:namespace] = @options[:namespace] if @options.key?(:namespace)
|
|
40
|
+
entry_payload[:memcache][:command] = :get_multi
|
|
41
|
+
entry_payload[:memcache][:keys] = keys.flatten.join(", ")
|
|
42
|
+
|
|
43
|
+
::Instana.tracer.log_entry(:memcache, entry_payload)
|
|
44
|
+
result = get_multi_without_instana(*keys)
|
|
45
|
+
|
|
46
|
+
exit_payload = { :memcache => {} }
|
|
47
|
+
exit_payload[:memcache][:hits] = result.length
|
|
48
|
+
result
|
|
49
|
+
rescue => e
|
|
50
|
+
::Instana.tracer.log_error(e)
|
|
51
|
+
raise
|
|
52
|
+
ensure
|
|
53
|
+
::Instana.tracer.log_exit(:memcache, exit_payload)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
module DalliServer
|
|
58
|
+
def self.included(klass)
|
|
59
|
+
::Instana::Util.method_alias(klass, :request)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def request_with_instana(op, *args)
|
|
63
|
+
if ::Instana.tracer.tracing? || ::Instana.tracer.tracing_span?(:memcache)
|
|
64
|
+
info_payload = { :memcache => {} }
|
|
65
|
+
info_payload[:memcache][:server] = "#{@hostname}:#{@port}"
|
|
66
|
+
::Instana.tracer.log_info(info_payload)
|
|
67
|
+
end
|
|
68
|
+
request_without_instana(op, *args)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
if defined?(::Dalli) && ::Instana.config[:dalli][:enabled]
|
|
75
|
+
::Instana.logger.info "Instrumenting Dalli"
|
|
76
|
+
::Dalli::Client.send(:include, ::Instana::Instrumentation::Dalli)
|
|
77
|
+
::Dalli::Server.send(:include, ::Instana::Instrumentation::DalliServer)
|
|
78
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
if defined?(::Excon) && ::Instana.config[:excon][:enabled]
|
|
2
|
+
module Instana
|
|
3
|
+
module Instrumentation
|
|
4
|
+
class Excon < ::Excon::Middleware::Base
|
|
5
|
+
def request_call(datum)
|
|
6
|
+
return @stack.request_call(datum) unless ::Instana.tracer.tracing?
|
|
7
|
+
|
|
8
|
+
payload = { :http => {} }
|
|
9
|
+
path = datum[:path].split('?').first
|
|
10
|
+
payload[:http][:url] = "#{datum[:connection].instance_variable_get(:@socket_key)}#{path}"
|
|
11
|
+
payload[:http][:method] = datum[:method] if datum.key?(:method)
|
|
12
|
+
|
|
13
|
+
if datum[:pipeline] == true
|
|
14
|
+
# Pass the context along in the datum so we get back on response
|
|
15
|
+
# and can close out the async span
|
|
16
|
+
datum[:instana_span] = ::Instana.tracer.log_async_entry(:excon, payload)
|
|
17
|
+
t_context = datum[:instana_span].context
|
|
18
|
+
else
|
|
19
|
+
::Instana.tracer.log_entry(:excon, payload)
|
|
20
|
+
t_context = ::Instana.tracer.context
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Set request headers; encode IDs as hexadecimal strings
|
|
24
|
+
datum[:headers]['X-Instana-T'] = t_context.trace_id_header
|
|
25
|
+
datum[:headers]['X-Instana-S'] = t_context.span_id_header
|
|
26
|
+
|
|
27
|
+
@stack.request_call(datum)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def error_call(datum)
|
|
31
|
+
return @stack.error_call(datum) unless ::Instana.tracer.tracing?
|
|
32
|
+
|
|
33
|
+
if datum[:pipeline] == true
|
|
34
|
+
::Instana.tracer.log_async_error(datum[:error], datum[:instana_span])
|
|
35
|
+
else
|
|
36
|
+
::Instana.tracer.log_error(datum[:error])
|
|
37
|
+
end
|
|
38
|
+
@stack.error_call(datum)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def response_call(datum)
|
|
42
|
+
# FIXME: Will connect exceptions call a response?
|
|
43
|
+
#
|
|
44
|
+
return @stack.response_call(datum) unless ::Instana.tracer.tracing?
|
|
45
|
+
|
|
46
|
+
result = @stack.response_call(datum)
|
|
47
|
+
|
|
48
|
+
status = datum[:status]
|
|
49
|
+
if !status && datum.key?(:response) && datum[:response].is_a?(Hash)
|
|
50
|
+
status = datum[:response][:status]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if status.between?(500, 511)
|
|
54
|
+
# Because of the 5xx response, we flag this span as errored but
|
|
55
|
+
# without a backtrace (no exception)
|
|
56
|
+
::Instana.tracer.log_error(nil)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
if datum[:pipeline] == true
|
|
60
|
+
# Pickup context of this async span from datum[:instana_span]
|
|
61
|
+
::Instana.tracer.log_async_exit(:excon, { :http => {:status => status } }, datum[:instana_span])
|
|
62
|
+
else
|
|
63
|
+
::Instana.tracer.log_exit(:excon, { :http => {:status => status } })
|
|
64
|
+
end
|
|
65
|
+
result
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
::Instana.logger.info "Instrumenting Excon"
|
|
72
|
+
::Excon.defaults[:middlewares].unshift(::Instana::Instrumentation::Excon)
|
|
73
|
+
end
|
|
74
|
+
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
call_types = [:request_response, :client_streamer, :server_streamer, :bidi_streamer]
|
|
2
|
+
|
|
3
|
+
if defined?(GRPC::ActiveCall) && ::Instana.config[:grpc][:enabled]
|
|
4
|
+
call_types.each do |call_type|
|
|
5
|
+
GRPC::ClientStub.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
6
|
+
def #{call_type}_with_instana(method, *others, **options)
|
|
7
|
+
kvs = { rpc: {} }
|
|
8
|
+
|
|
9
|
+
unless ::Instana.tracer.tracing?
|
|
10
|
+
return #{call_type}_without_instana(method, *others, **options)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
kvs[:rpc][:flavor] = :grpc
|
|
14
|
+
kvs[:rpc][:host] = @host
|
|
15
|
+
kvs[:rpc][:call] = method
|
|
16
|
+
kvs[:rpc][:call_type] = :#{call_type}
|
|
17
|
+
|
|
18
|
+
::Instana.tracer.log_entry(:'rpc-client', kvs)
|
|
19
|
+
|
|
20
|
+
context = ::Instana.tracer.context
|
|
21
|
+
if context
|
|
22
|
+
options[:metadata] = (options[:metadata] || {}).merge(
|
|
23
|
+
'x-instana-t' => context.trace_id_header,
|
|
24
|
+
'x-instana-s' => context.span_id_header
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#{call_type}_without_instana(method, *others, **options)
|
|
29
|
+
rescue => e
|
|
30
|
+
kvs[:rpc][:error] = true
|
|
31
|
+
::Instana.tracer.log_info(kvs)
|
|
32
|
+
::Instana.tracer.log_error(e)
|
|
33
|
+
raise
|
|
34
|
+
ensure
|
|
35
|
+
::Instana.tracer.log_exit(:'rpc-client', {})
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
alias #{call_type}_without_instana #{call_type}
|
|
39
|
+
alias #{call_type} #{call_type}_with_instana
|
|
40
|
+
RUBY
|
|
41
|
+
end
|
|
42
|
+
::Instana.logger.info 'Instrumenting GRPC client'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if defined?(GRPC::RpcDesc) && ::Instana.config[:grpc][:enabled]
|
|
46
|
+
call_types.each do |call_type|
|
|
47
|
+
GRPC::RpcDesc.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
48
|
+
def handle_#{call_type}_with_instana(active_call, mth, *others)
|
|
49
|
+
kvs = { rpc: {} }
|
|
50
|
+
metadata = active_call.metadata
|
|
51
|
+
|
|
52
|
+
incoming_context = {}
|
|
53
|
+
if metadata.key?('x-instana-t')
|
|
54
|
+
incoming_context[:trace_id] = ::Instana::Util.header_to_id(metadata['x-instana-t'])
|
|
55
|
+
incoming_context[:span_id] = ::Instana::Util.header_to_id(metadata['x-instana-s']) if metadata.key?('x-instana-s')
|
|
56
|
+
incoming_context[:level] = metadata['x-instana-l'] if metadata.key?('x-instana-l')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
kvs[:rpc][:flavor] = :grpc
|
|
60
|
+
kvs[:rpc][:host] = Socket.gethostname
|
|
61
|
+
kvs[:rpc][:call] = "/\#{mth.owner.service_name}/\#{name}"
|
|
62
|
+
kvs[:rpc][:call_type] = :#{call_type}
|
|
63
|
+
kvs[:rpc][:peer] = { address: active_call.peer }
|
|
64
|
+
|
|
65
|
+
::Instana.tracer.log_start_or_continue(
|
|
66
|
+
:'rpc-server', kvs, incoming_context
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
handle_#{call_type}_without_instana(active_call, mth, *others)
|
|
70
|
+
rescue => e
|
|
71
|
+
kvs[:rpc][:error] = true
|
|
72
|
+
::Instana.tracer.log_info(kvs)
|
|
73
|
+
::Instana.tracer.log_error(e)
|
|
74
|
+
raise
|
|
75
|
+
ensure
|
|
76
|
+
::Instana.tracer.log_end(:'rpc-server', {}) if ::Instana.tracer.tracing?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
alias handle_#{call_type}_without_instana handle_#{call_type}
|
|
80
|
+
alias handle_#{call_type} handle_#{call_type}_with_instana
|
|
81
|
+
RUBY
|
|
82
|
+
end
|
|
83
|
+
::Instana.logger.info 'Instrumenting GRPC server'
|
|
84
|
+
end
|