traceview 3.0.0-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/.gitignore +10 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +58 -0
- data/Appraisals +10 -0
- data/CHANGELOG.md +490 -0
- data/CONFIG.md +16 -0
- data/Gemfile +95 -0
- data/LICENSE +199 -0
- data/README.md +380 -0
- data/Rakefile +109 -0
- data/examples/DNT.md +35 -0
- data/examples/carrying_context.rb +225 -0
- data/examples/instrumenting_metal_controller.rb +8 -0
- data/examples/puma_on_heroku_config.rb +17 -0
- data/examples/tracing_async_threads.rb +125 -0
- data/examples/tracing_background_jobs.rb +52 -0
- data/examples/tracing_forked_processes.rb +100 -0
- data/examples/unicorn_on_heroku_config.rb +28 -0
- data/ext/oboe_metal/extconf.rb +61 -0
- data/ext/oboe_metal/noop/noop.c +7 -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 +275 -0
- data/ext/oboe_metal/src/oboe.hpp +352 -0
- data/ext/oboe_metal/src/oboe_wrap.cxx +3886 -0
- data/ext/oboe_metal/tests/test.rb +11 -0
- data/gemfiles/mongo.gemfile +33 -0
- data/gemfiles/moped.gemfile +33 -0
- data/get_version.rb +5 -0
- data/init.rb +4 -0
- data/lib/joboe_metal.rb +206 -0
- data/lib/oboe/README +2 -0
- data/lib/oboe/backward_compatibility.rb +59 -0
- data/lib/oboe/inst/rack.rb +11 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe_metal.rb +151 -0
- data/lib/rails/generators/traceview/install_generator.rb +76 -0
- data/lib/rails/generators/traceview/templates/traceview_initializer.rb +159 -0
- data/lib/traceview/api/layerinit.rb +51 -0
- data/lib/traceview/api/logging.rb +209 -0
- data/lib/traceview/api/memcache.rb +31 -0
- data/lib/traceview/api/profiling.rb +50 -0
- data/lib/traceview/api/tracing.rb +135 -0
- data/lib/traceview/api/util.rb +121 -0
- data/lib/traceview/api.rb +18 -0
- data/lib/traceview/base.rb +225 -0
- data/lib/traceview/config.rb +238 -0
- data/lib/traceview/frameworks/grape.rb +97 -0
- data/lib/traceview/frameworks/padrino/templates.rb +58 -0
- data/lib/traceview/frameworks/padrino.rb +64 -0
- data/lib/traceview/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
- data/lib/traceview/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
- data/lib/traceview/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
- data/lib/traceview/frameworks/rails/inst/action_controller.rb +216 -0
- data/lib/traceview/frameworks/rails/inst/action_view.rb +56 -0
- data/lib/traceview/frameworks/rails/inst/action_view_2x.rb +54 -0
- data/lib/traceview/frameworks/rails/inst/action_view_30.rb +48 -0
- data/lib/traceview/frameworks/rails/inst/active_record.rb +24 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/utils.rb +117 -0
- data/lib/traceview/frameworks/rails.rb +145 -0
- data/lib/traceview/frameworks/sinatra/templates.rb +56 -0
- data/lib/traceview/frameworks/sinatra.rb +95 -0
- data/lib/traceview/inst/cassandra.rb +279 -0
- data/lib/traceview/inst/dalli.rb +86 -0
- data/lib/traceview/inst/em-http-request.rb +99 -0
- data/lib/traceview/inst/excon.rb +111 -0
- data/lib/traceview/inst/faraday.rb +73 -0
- data/lib/traceview/inst/http.rb +87 -0
- data/lib/traceview/inst/httpclient.rb +173 -0
- data/lib/traceview/inst/memcache.rb +102 -0
- data/lib/traceview/inst/memcached.rb +94 -0
- data/lib/traceview/inst/mongo.rb +238 -0
- data/lib/traceview/inst/moped.rb +474 -0
- data/lib/traceview/inst/rack.rb +122 -0
- data/lib/traceview/inst/redis.rb +271 -0
- data/lib/traceview/inst/resque.rb +192 -0
- data/lib/traceview/inst/rest-client.rb +38 -0
- data/lib/traceview/inst/sequel.rb +162 -0
- data/lib/traceview/inst/typhoeus.rb +102 -0
- data/lib/traceview/instrumentation.rb +21 -0
- data/lib/traceview/loading.rb +94 -0
- data/lib/traceview/logger.rb +41 -0
- data/lib/traceview/method_profiling.rb +84 -0
- data/lib/traceview/ruby.rb +36 -0
- data/lib/traceview/support.rb +113 -0
- data/lib/traceview/thread_local.rb +26 -0
- data/lib/traceview/util.rb +250 -0
- data/lib/traceview/version.rb +16 -0
- data/lib/traceview/xtrace.rb +90 -0
- data/lib/traceview.rb +62 -0
- data/test/frameworks/apps/grape_nested.rb +30 -0
- data/test/frameworks/apps/grape_simple.rb +24 -0
- data/test/frameworks/apps/padrino_simple.rb +45 -0
- data/test/frameworks/apps/sinatra_simple.rb +24 -0
- data/test/frameworks/grape_test.rb +142 -0
- data/test/frameworks/padrino_test.rb +30 -0
- data/test/frameworks/sinatra_test.rb +30 -0
- data/test/instrumentation/cassandra_test.rb +380 -0
- data/test/instrumentation/dalli_test.rb +171 -0
- data/test/instrumentation/em_http_request_test.rb +86 -0
- data/test/instrumentation/excon_test.rb +207 -0
- data/test/instrumentation/faraday_test.rb +235 -0
- data/test/instrumentation/http_test.rb +140 -0
- data/test/instrumentation/httpclient_test.rb +296 -0
- data/test/instrumentation/memcache_test.rb +251 -0
- data/test/instrumentation/memcached_test.rb +226 -0
- data/test/instrumentation/mongo_test.rb +462 -0
- data/test/instrumentation/moped_test.rb +496 -0
- data/test/instrumentation/rack_test.rb +116 -0
- data/test/instrumentation/redis_hashes_test.rb +265 -0
- data/test/instrumentation/redis_keys_test.rb +318 -0
- data/test/instrumentation/redis_lists_test.rb +310 -0
- data/test/instrumentation/redis_misc_test.rb +160 -0
- data/test/instrumentation/redis_sets_test.rb +293 -0
- data/test/instrumentation/redis_sortedsets_test.rb +325 -0
- data/test/instrumentation/redis_strings_test.rb +333 -0
- data/test/instrumentation/resque_test.rb +62 -0
- data/test/instrumentation/rest-client_test.rb +294 -0
- data/test/instrumentation/sequel_mysql2_test.rb +326 -0
- data/test/instrumentation/sequel_mysql_test.rb +326 -0
- data/test/instrumentation/sequel_pg_test.rb +330 -0
- data/test/instrumentation/typhoeus_test.rb +285 -0
- data/test/minitest_helper.rb +187 -0
- data/test/profiling/method_test.rb +198 -0
- data/test/servers/rackapp_8101.rb +22 -0
- data/test/support/backcompat_test.rb +269 -0
- data/test/support/config_test.rb +128 -0
- data/test/support/dnt_test.rb +73 -0
- data/test/support/liboboe_settings_test.rb +104 -0
- data/test/support/xtrace_test.rb +35 -0
- data/traceview.gemspec +29 -0
- metadata +248 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Copyright (c) 2015 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module TraceView
|
|
5
|
+
module Inst
|
|
6
|
+
module TyphoeusRequestOps
|
|
7
|
+
|
|
8
|
+
def self.included(klass)
|
|
9
|
+
::TraceView::Util.method_alias(klass, :run, ::Typhoeus::Request::Operations)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def run_with_traceview
|
|
13
|
+
return run_without_traceview unless TraceView.tracing?
|
|
14
|
+
|
|
15
|
+
TraceView::API.log_entry('typhoeus')
|
|
16
|
+
|
|
17
|
+
# Prepare X-Trace header handling
|
|
18
|
+
blacklisted = TraceView::API.blacklisted?(url)
|
|
19
|
+
context = TraceView::Context.toString
|
|
20
|
+
task_id = TraceView::XTrace.task_id(context)
|
|
21
|
+
options[:headers]['X-Trace'] = context unless blacklisted
|
|
22
|
+
|
|
23
|
+
response = run_without_traceview
|
|
24
|
+
|
|
25
|
+
if response.code == 0
|
|
26
|
+
TraceView::API.log('typhoeus', 'error', { :ErrorClass => response.return_code,
|
|
27
|
+
:ErrorMsg => response.return_message })
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
kvs = {}
|
|
31
|
+
kvs['IsService'] = 1
|
|
32
|
+
kvs[:HTTPStatus] = response.code
|
|
33
|
+
kvs['Backtrace'] = TraceView::API.backtrace if TraceView::Config[:typhoeus][:collect_backtraces]
|
|
34
|
+
|
|
35
|
+
uri = URI(response.effective_url)
|
|
36
|
+
|
|
37
|
+
# Conditionally log query params
|
|
38
|
+
if TraceView::Config[:typhoeus][:log_args]
|
|
39
|
+
kvs['RemoteURL'] = uri.to_s
|
|
40
|
+
else
|
|
41
|
+
kvs['RemoteURL'] = uri.to_s.split('?').first
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
kvs['HTTPMethod'] = ::TraceView::Util.upcase(options[:method])
|
|
45
|
+
kvs['Blacklisted'] = true if blacklisted
|
|
46
|
+
|
|
47
|
+
# Re-attach net::http edge unless it's blacklisted or if we don't have a
|
|
48
|
+
# valid X-Trace header
|
|
49
|
+
unless blacklisted
|
|
50
|
+
xtrace = response.headers['X-Trace']
|
|
51
|
+
|
|
52
|
+
if xtrace && TraceView::XTrace.valid?(xtrace) && TraceView.tracing?
|
|
53
|
+
|
|
54
|
+
# Assure that we received back a valid X-Trace with the same task_id
|
|
55
|
+
if task_id == TraceView::XTrace.task_id(xtrace)
|
|
56
|
+
TraceView::Context.fromString(xtrace)
|
|
57
|
+
else
|
|
58
|
+
TraceView.logger.debug "Mismatched returned X-Trace ID: #{xtrace}"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
TraceView::API.log('typhoeus', 'info', kvs)
|
|
64
|
+
response
|
|
65
|
+
rescue => e
|
|
66
|
+
TraceView::API.log_exception('typhoeus', e)
|
|
67
|
+
raise e
|
|
68
|
+
ensure
|
|
69
|
+
TraceView::API.log_exit('typhoeus')
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
module TyphoeusHydraRunnable
|
|
74
|
+
def self.included(klass)
|
|
75
|
+
::TraceView::Util.method_alias(klass, :run, ::Typhoeus::Hydra)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def run_with_traceview
|
|
79
|
+
kvs = {}
|
|
80
|
+
|
|
81
|
+
kvs[:queued_requests] = queued_requests.count
|
|
82
|
+
kvs[:max_concurrency] = max_concurrency
|
|
83
|
+
|
|
84
|
+
# FIXME: Until we figure out a strategy to deal with libcurl internal
|
|
85
|
+
# threading and Ethon's use of easy handles, here we just do a simple
|
|
86
|
+
# trace of the hydra run.
|
|
87
|
+
TraceView::API.trace("typhoeus_hydra", kvs) do
|
|
88
|
+
run_without_traceview
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
if TraceView::Config[:typhoeus][:enabled]
|
|
97
|
+
if defined?(::Typhoeus)
|
|
98
|
+
TraceView.logger.info '[traceview/loading] Instrumenting typhoeus' if TraceView::Config[:verbose]
|
|
99
|
+
::TraceView::Util.send_include(::Typhoeus::Request::Operations, ::TraceView::Inst::TyphoeusRequestOps)
|
|
100
|
+
::TraceView::Util.send_include(::Typhoeus::Hydra, ::TraceView::Inst::TyphoeusHydraRunnable)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module TraceView
|
|
5
|
+
##
|
|
6
|
+
# The Inst module holds all of the instrumentation extensions for various
|
|
7
|
+
# libraries suchs as Redis, Dalli and Resque.
|
|
8
|
+
module Inst
|
|
9
|
+
def self.load_instrumentation
|
|
10
|
+
# Load the general instrumentation
|
|
11
|
+
pattern = File.join(File.dirname(__FILE__), 'inst', '*.rb')
|
|
12
|
+
Dir.glob(pattern) do |f|
|
|
13
|
+
begin
|
|
14
|
+
require f
|
|
15
|
+
rescue => e
|
|
16
|
+
TraceView.logger.error "[traceview/loading] Error loading instrumentation file '#{f}' : #{e}"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
require 'digest/sha1'
|
|
5
|
+
|
|
6
|
+
module TraceView
|
|
7
|
+
module Util
|
|
8
|
+
##
|
|
9
|
+
# This module is used solely for RUM ID calculation
|
|
10
|
+
#
|
|
11
|
+
module Base64URL
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
def encode(bin)
|
|
15
|
+
c = [bin].pack('m0').gsub(/\=+\Z/, '').tr('+/', '-_').rstrip
|
|
16
|
+
m = c.size % 4
|
|
17
|
+
c += '=' * (4 - m) if m != 0
|
|
18
|
+
c
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def decode(bin)
|
|
22
|
+
m = bin.size % 4
|
|
23
|
+
bin += '=' * (4 - m) if m != 0
|
|
24
|
+
bin.tr('-_', '+/').unpack('m0').first
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# This module houses all of the loading functionality for the traceview gem.
|
|
31
|
+
#
|
|
32
|
+
# Note that this does not necessarily _have_ to include initialization routines
|
|
33
|
+
# (although it can).
|
|
34
|
+
#
|
|
35
|
+
# Actual initialization is often separated out as it can be dependent on on the state
|
|
36
|
+
# of the stack boot process. e.g. code requiring that initializers, frameworks or
|
|
37
|
+
# instrumented libraries are already loaded...
|
|
38
|
+
#
|
|
39
|
+
module Loading
|
|
40
|
+
##
|
|
41
|
+
# Load the TraceView access key (either from system configuration file
|
|
42
|
+
# or environment variable) and calculate internal RUM ID
|
|
43
|
+
#
|
|
44
|
+
def self.load_access_key
|
|
45
|
+
if ENV.key?('TRACEVIEW_CUUID')
|
|
46
|
+
# Preferably get access key from environment (e.g. Heroku)
|
|
47
|
+
TraceView::Config[:access_key] = ENV['TRACEVIEW_CUUID']
|
|
48
|
+
TraceView::Config[:rum_id] = TraceView::Util::Base64URL.encode(Digest::SHA1.digest('RUM' + TraceView::Config[:access_key]))
|
|
49
|
+
else
|
|
50
|
+
# ..else read from system-wide configuration file
|
|
51
|
+
if TraceView::Config.access_key.empty?
|
|
52
|
+
config_file = '/etc/tracelytics.conf'
|
|
53
|
+
return unless File.exist?(config_file)
|
|
54
|
+
|
|
55
|
+
File.open(config_file).each do |line|
|
|
56
|
+
if line =~ /^tracelyzer.access_key=/ || line =~ /^access_key/
|
|
57
|
+
bits = line.split(/=/)
|
|
58
|
+
TraceView::Config[:access_key] = bits[1].strip
|
|
59
|
+
TraceView::Config[:rum_id] = TraceView::Util::Base64URL.encode(Digest::SHA1.digest('RUM' + TraceView::Config[:access_key]))
|
|
60
|
+
break
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
rescue StandardError => e
|
|
66
|
+
TraceView.logger.error "Trouble obtaining access_key and rum_id: #{e.inspect}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# Load the traceview tracing API
|
|
71
|
+
#
|
|
72
|
+
def self.require_api
|
|
73
|
+
pattern = File.join(File.dirname(__FILE__), 'api', '*.rb')
|
|
74
|
+
Dir.glob(pattern) do |f|
|
|
75
|
+
require f
|
|
76
|
+
end
|
|
77
|
+
require 'traceview/api'
|
|
78
|
+
|
|
79
|
+
begin
|
|
80
|
+
TraceView::API.extend_with_tracing
|
|
81
|
+
rescue LoadError => e
|
|
82
|
+
TraceView.logger.fatal "[traceview/error] Couldn't load api: #{e.message}"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
TraceView::Loading.require_api
|
|
89
|
+
|
|
90
|
+
# Auto-start the Reporter unless we running Unicorn on Heroku
|
|
91
|
+
# In that case, we start the reporters after fork
|
|
92
|
+
unless TraceView.heroku? && TraceView.forking_webserver?
|
|
93
|
+
TraceView::Reporter.start if TraceView.loaded
|
|
94
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
require 'logger'
|
|
5
|
+
|
|
6
|
+
module TraceView
|
|
7
|
+
class << self
|
|
8
|
+
attr_accessor :logger
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Logger
|
|
12
|
+
# Fatal message
|
|
13
|
+
def fatal(string, exception = nil)
|
|
14
|
+
TraceView.logger.fatal(string) if TraceView.logger
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Error message
|
|
18
|
+
def error(msg, exception = nil)
|
|
19
|
+
TraceView.logger.error(string) if TraceView.logger
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Warn message
|
|
23
|
+
def warn(msg, exception = nil)
|
|
24
|
+
TraceView.logger.warn(string) if TraceView.logger
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Info message
|
|
28
|
+
def info(msg, exception = nil)
|
|
29
|
+
TraceView.logger.info(string) if TraceView.logger
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Debug message
|
|
33
|
+
def debug(msg, exception = nil)
|
|
34
|
+
TraceView.logger.debug(string) if TraceView.logger
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
TraceView.logger = Logger.new(STDERR)
|
|
41
|
+
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
##
|
|
5
|
+
# Provides the methods necessary for method profiling. Profiling
|
|
6
|
+
# results are sent to the TraceView dashboard.
|
|
7
|
+
#
|
|
8
|
+
# Example usage:
|
|
9
|
+
# class MyApp
|
|
10
|
+
# include TraceViewMethodProfiling
|
|
11
|
+
#
|
|
12
|
+
# def process_request()
|
|
13
|
+
# # The hard work
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# # call syntax: profile_method <method>, <profile_name>
|
|
17
|
+
# profile_method :process_request, 'request_processor'
|
|
18
|
+
# end
|
|
19
|
+
module TraceViewMethodProfiling
|
|
20
|
+
def self.included(klass)
|
|
21
|
+
klass.extend ClassMethods
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module ClassMethods
|
|
25
|
+
def profile_method(method_name, profile_name, store_args = false, store_return = false, *_)
|
|
26
|
+
begin
|
|
27
|
+
# this only gets file and line where profiling is turned on, presumably
|
|
28
|
+
# right after the function definition. ruby 1.9 and 2.0 has nice introspection (Method.source_location)
|
|
29
|
+
# but its appears no such luck for ruby 1.8
|
|
30
|
+
file = ''
|
|
31
|
+
line = ''
|
|
32
|
+
if RUBY_VERSION >= '1.9'
|
|
33
|
+
info = instance_method(method_name).source_location
|
|
34
|
+
unless info.nil?
|
|
35
|
+
file = info[0].to_s
|
|
36
|
+
line = info[1].to_s
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
info = Kernel.caller[0].split(':')
|
|
40
|
+
file = info.first.to_s
|
|
41
|
+
line = info.last.to_s
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Safety: Make sure there are no quotes or double quotes to break the class_eval
|
|
45
|
+
file = file.gsub(/[\'\"]/, '')
|
|
46
|
+
line = line.gsub(/[\'\"]/, '')
|
|
47
|
+
|
|
48
|
+
# profiling via ruby-prof, is it possible to get return value of profiled code?
|
|
49
|
+
code = "def _traceview_profiled_#{method_name}(*args, &block)
|
|
50
|
+
entry_kvs = {}
|
|
51
|
+
entry_kvs['Language'] = 'ruby'
|
|
52
|
+
entry_kvs['ProfileName'] = '#{TraceView::Util.prettify(profile_name)}'
|
|
53
|
+
entry_kvs['FunctionName'] = '#{TraceView::Util.prettify(method_name)}'
|
|
54
|
+
entry_kvs['File'] = '#{file}'
|
|
55
|
+
entry_kvs['LineNumber'] = '#{line}'
|
|
56
|
+
entry_kvs['Args'] = TraceView::API.pps(*args) if #{store_args}
|
|
57
|
+
entry_kvs.merge!(::TraceView::API.get_class_name(self))
|
|
58
|
+
|
|
59
|
+
TraceView::API.log(nil, 'profile_entry', entry_kvs)
|
|
60
|
+
|
|
61
|
+
ret = _traceview_orig_#{method_name}(*args, &block)
|
|
62
|
+
|
|
63
|
+
exit_kvs = {}
|
|
64
|
+
exit_kvs['Language'] = 'ruby'
|
|
65
|
+
exit_kvs['ProfileName'] = '#{TraceView::Util.prettify(profile_name)}'
|
|
66
|
+
exit_kvs['ReturnValue'] = TraceView::API.pps(ret) if #{store_return}
|
|
67
|
+
|
|
68
|
+
TraceView::API.log(nil, 'profile_exit', exit_kvs)
|
|
69
|
+
ret
|
|
70
|
+
end"
|
|
71
|
+
rescue => e
|
|
72
|
+
TraceView.logger.warn "[traceview/warn] profile_method: #{e.inspect}"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
begin
|
|
76
|
+
class_eval code, __FILE__, __LINE__
|
|
77
|
+
alias_method "_traceview_orig_#{method_name}", method_name
|
|
78
|
+
alias_method method_name, "_traceview_profiled_#{method_name}"
|
|
79
|
+
rescue => e
|
|
80
|
+
TraceView.logger.warn "[traceview/warn] Fatal error profiling method (#{method_name}): #{e.inspect}" if TraceView::Config[:verbose]
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module TraceView
|
|
5
|
+
##
|
|
6
|
+
# This module provides a method to manually initialize the
|
|
7
|
+
# Ruby instrumentation. Normally this is done by detecting
|
|
8
|
+
# frameworks at load time and inserting initialization hooks.
|
|
9
|
+
module Ruby
|
|
10
|
+
class << self
|
|
11
|
+
def initialize
|
|
12
|
+
load
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# The core method to load Ruby instrumentation. Call this
|
|
17
|
+
# from raw Ruby scripts or in Ruby applications where a
|
|
18
|
+
# supported framework isn't being used. Supported frameworks
|
|
19
|
+
# will instead be detected at load time and initialization is
|
|
20
|
+
# automatic.
|
|
21
|
+
def load
|
|
22
|
+
# In case some apps call this manually, make sure
|
|
23
|
+
# that the gem is fully loaded and not in no-op
|
|
24
|
+
# mode (e.g. on unsupported platforms etc.)
|
|
25
|
+
if TraceView.loaded
|
|
26
|
+
TraceView::Loading.load_access_key
|
|
27
|
+
TraceView::Inst.load_instrumentation
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if TraceView.loaded and !TraceView.framework?
|
|
35
|
+
::TraceView::Ruby.load
|
|
36
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Copyright (c) 2014 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
require 'rbconfig'
|
|
5
|
+
|
|
6
|
+
module TraceView
|
|
7
|
+
##
|
|
8
|
+
# This module is used to debug problematic setups and/or environments.
|
|
9
|
+
# Depending on the environment, output may be to stdout or the framework
|
|
10
|
+
# log file (e.g. log/production.log)
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# yesno
|
|
14
|
+
#
|
|
15
|
+
# Utility method to translate value/nil to "yes"/"no" strings
|
|
16
|
+
def self.yesno(x)
|
|
17
|
+
x ? "yes" : "no"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.support_report
|
|
21
|
+
TraceView.logger.warn "********************************************************"
|
|
22
|
+
TraceView.logger.warn "* BEGIN TraceView Support Report"
|
|
23
|
+
TraceView.logger.warn "* Please email the output of this report to traceviewsupport@appneta.com"
|
|
24
|
+
TraceView.logger.warn "********************************************************"
|
|
25
|
+
TraceView.logger.warn "Ruby: #{RUBY_DESCRIPTION}"
|
|
26
|
+
TraceView.logger.warn "$0: #{$0}"
|
|
27
|
+
TraceView.logger.warn "$1: #{$1}" unless $1.nil?
|
|
28
|
+
TraceView.logger.warn "$2: #{$2}" unless $2.nil?
|
|
29
|
+
TraceView.logger.warn "$3: #{$3}" unless $3.nil?
|
|
30
|
+
TraceView.logger.warn "$4: #{$4}" unless $4.nil?
|
|
31
|
+
TraceView.logger.warn "TraceView.loaded == #{TraceView.loaded}"
|
|
32
|
+
|
|
33
|
+
using_jruby = defined?(JRUBY_VERSION)
|
|
34
|
+
TraceView.logger.warn "Using JRuby?: #{yesno(using_jruby)}"
|
|
35
|
+
if using_jruby
|
|
36
|
+
TraceView.logger.warn "Jtraceview Agent Status: #{Java::ComTracelyticsAgent::Agent.getStatus}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
on_heroku = TraceView.heroku?
|
|
40
|
+
TraceView.logger.warn "On Heroku?: #{yesno(on_heroku)}"
|
|
41
|
+
if on_heroku
|
|
42
|
+
TraceView.logger.warn "TRACEVIEW_URL: #{ENV['TRACEVIEW_URL']}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
TraceView.logger.warn "TraceView::Ruby defined?: #{yesno(defined?(TraceView::Ruby))}"
|
|
46
|
+
TraceView.logger.warn "TraceView.reporter: #{TraceView.reporter}"
|
|
47
|
+
|
|
48
|
+
TraceView.logger.warn "********************************************************"
|
|
49
|
+
TraceView.logger.warn "* Frameworks"
|
|
50
|
+
TraceView.logger.warn "********************************************************"
|
|
51
|
+
|
|
52
|
+
using_rails = defined?(::Rails)
|
|
53
|
+
TraceView.logger.warn "Using Rails?: #{yesno(using_rails)}"
|
|
54
|
+
if using_rails
|
|
55
|
+
TraceView.logger.warn "TraceView::Rails loaded?: #{yesno(defined?(::TraceView::Rails))}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
using_sinatra = defined?(::Sinatra)
|
|
59
|
+
TraceView.logger.warn "Using Sinatra?: #{yesno(using_sinatra)}"
|
|
60
|
+
|
|
61
|
+
using_padrino = defined?(::Padrino)
|
|
62
|
+
TraceView.logger.warn "Using Padrino?: #{yesno(using_padrino)}"
|
|
63
|
+
|
|
64
|
+
using_grape = defined?(::Grape)
|
|
65
|
+
TraceView.logger.warn "Using Grape?: #{yesno(using_grape)}"
|
|
66
|
+
|
|
67
|
+
TraceView.logger.warn "********************************************************"
|
|
68
|
+
TraceView.logger.warn "* TraceView Libraries"
|
|
69
|
+
TraceView.logger.warn "********************************************************"
|
|
70
|
+
files = Dir.glob('/usr/lib/liboboe*')
|
|
71
|
+
if files.empty?
|
|
72
|
+
TraceView.logger.warn "Error: No liboboe libs!"
|
|
73
|
+
else
|
|
74
|
+
files.each { |f|
|
|
75
|
+
TraceView.logger.warn f
|
|
76
|
+
}
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
TraceView.logger.warn "********************************************************"
|
|
80
|
+
TraceView.logger.warn "* TraceView::Config Values"
|
|
81
|
+
TraceView.logger.warn "********************************************************"
|
|
82
|
+
TraceView::Config.show.each { |k,v|
|
|
83
|
+
TraceView.logger.warn "#{k}: #{v}"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
TraceView.logger.warn "********************************************************"
|
|
87
|
+
TraceView.logger.warn "* OS, Platform + Env"
|
|
88
|
+
TraceView.logger.warn "********************************************************"
|
|
89
|
+
TraceView.logger.warn RbConfig::CONFIG['host_os']
|
|
90
|
+
TraceView.logger.warn RbConfig::CONFIG['sitearch']
|
|
91
|
+
TraceView.logger.warn RbConfig::CONFIG['arch']
|
|
92
|
+
TraceView.logger.warn RUBY_PLATFORM
|
|
93
|
+
TraceView.logger.warn "RACK_ENV: #{ENV['RACK_ENV']}"
|
|
94
|
+
TraceView.logger.warn "RAILS_ENV: #{ENV['RAILS_ENV']}" if using_rails
|
|
95
|
+
|
|
96
|
+
TraceView.logger.warn "********************************************************"
|
|
97
|
+
TraceView.logger.warn "* Raw __Init KVs"
|
|
98
|
+
TraceView.logger.warn "********************************************************"
|
|
99
|
+
platform_info = TraceView::Util.build_init_report
|
|
100
|
+
platform_info.each { |k,v|
|
|
101
|
+
TraceView.logger.warn "#{k}: #{v}"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
TraceView.logger.warn "********************************************************"
|
|
105
|
+
TraceView.logger.warn "* END TraceView Support Report"
|
|
106
|
+
TraceView.logger.warn "* Support Email: traceviewsupport@appneta.com"
|
|
107
|
+
TraceView.logger.warn "* Support Portal: https://support.tv.appneta.com"
|
|
108
|
+
TraceView.logger.warn "* Freenode IRC: #appneta"
|
|
109
|
+
TraceView.logger.warn "* Github: https://github.com/appneta/traceview-ruby"
|
|
110
|
+
TraceView.logger.warn "********************************************************"
|
|
111
|
+
nil
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Copyright (c) 2014 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module TraceView
|
|
5
|
+
##
|
|
6
|
+
# Provides thread local storage for TraceView.
|
|
7
|
+
#
|
|
8
|
+
# Example usage:
|
|
9
|
+
# module TraceViewBase
|
|
10
|
+
# extend ::TraceView::ThreadLocal
|
|
11
|
+
# thread_local :layer_op
|
|
12
|
+
# end
|
|
13
|
+
module ThreadLocal
|
|
14
|
+
def thread_local(name)
|
|
15
|
+
key = "__#{self}_#{name}__".intern
|
|
16
|
+
|
|
17
|
+
define_method(name) do
|
|
18
|
+
Thread.current[key]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
define_method(name.to_s + '=') do |value|
|
|
22
|
+
Thread.current[key] = value
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|