traceview 3.1.0-java → 3.2.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/CHANGELOG.md +12 -0
- data/lib/traceview.rb +1 -0
- data/lib/traceview/api/profiling.rb +146 -0
- data/lib/traceview/api/util.rb +6 -5
- data/lib/traceview/base.rb +2 -3
- data/lib/traceview/config.rb +5 -5
- data/lib/traceview/legacy_method_profiling.rb +97 -0
- data/lib/traceview/method_profiling.rb +16 -88
- data/lib/traceview/support.rb +28 -6
- data/lib/traceview/version.rb +2 -2
- data/test/frameworks/rails4x_test.rb +3 -1
- data/test/minitest_helper.rb +11 -3
- data/test/profiling/{method_test.rb → legacy_method_profiling_test.rb} +0 -0
- data/test/profiling/method_profiling_test.rb +631 -0
- data/test/servers/rails4x_8140.rb +2 -3
- data/test/support/config_test.rb +6 -6
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96c087aab94a58d443be7e150a674f72cffbf110
|
4
|
+
data.tar.gz: 08616ab412adefe991cc489aecb9c960c64dc8db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f950a8ad1c44cf89064f94c4eb17b26020a74e2c1156af6e4cb8cfc1c80612e0e96aefb4576bcff8ffab3908e0358a0c2d3edd0338c69cc2fd44215e6b0100d
|
7
|
+
data.tar.gz: 311bb5d286c6eef95149a6807f81334117a727ab1d440c773442c6d7c6ce6e8e647bfad93742b2ac1e227245b6d2aba988533d279404eabbf9482c9c91b66690
|
data/.travis.yml
CHANGED
@@ -63,8 +63,8 @@ before_install:
|
|
63
63
|
- sudo service cassandra start
|
64
64
|
|
65
65
|
install:
|
66
|
-
- wget https://
|
67
|
-
- sudo sh ./
|
66
|
+
- wget https://files.appneta.com/install_appneta.sh
|
67
|
+
- sudo sh ./install_appneta.sh f51e2a43-0ee5-4851-8a54-825773b3218e
|
68
68
|
- sudo apt-get install -y tracelytics-java-agent
|
69
69
|
|
70
70
|
before_script:
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,18 @@ https://github.com/appneta/oboe-ruby/releases
|
|
4
4
|
|
5
5
|
Dates in this file are in the format MM/DD/YYYY.
|
6
6
|
|
7
|
+
# traceview 3.2.0
|
8
|
+
|
9
|
+
This minor release adds the following:
|
10
|
+
|
11
|
+
* New and improved method profiling: #135
|
12
|
+
* Fix URL Query config: #136
|
13
|
+
|
14
|
+
Pushed to Rubygems:
|
15
|
+
|
16
|
+
https://rubygems.org/gems/traceview/versions/3.2.0
|
17
|
+
https://rubygems.org/gems/traceview/versions/3.2.0-java
|
18
|
+
|
7
19
|
# traceview 3.1.0
|
8
20
|
|
9
21
|
This minor release adds the following:
|
data/lib/traceview.rb
CHANGED
@@ -45,6 +45,152 @@ module TraceView
|
|
45
45
|
TraceView::API.log(nil, 'profile_exit', exit_kvs)
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Public: Profile a method on a class or module. That method can be of any (accessible)
|
51
|
+
# type (instance, singleton, private, protected etc.).
|
52
|
+
#
|
53
|
+
# klass - the class or module that has the method to profile
|
54
|
+
# method - the method to profile. Can be singleton, instance, private etc...
|
55
|
+
# opts - a hash specifying the one or more of the following options:
|
56
|
+
# * :arguments - report the arguments passed to <tt>method</tt> on each profile (default: false)
|
57
|
+
# * :result - report the return value of <tt>method</tt> on each profile (default: false)
|
58
|
+
# * :backtrace - report the return value of <tt>method</tt> on each profile (default: false)
|
59
|
+
# * :name - alternate name for the profile reported in the dashboard (default: method name)
|
60
|
+
# extra_kvs - a hash containing any additional KVs you would like reported with the profile
|
61
|
+
#
|
62
|
+
# Example
|
63
|
+
#
|
64
|
+
# opts = {}
|
65
|
+
# opts[:backtrace] = true
|
66
|
+
# opts[:arguments] = false
|
67
|
+
# opts[:name] = :array_sort
|
68
|
+
#
|
69
|
+
# TraceView::API.profile_method(Array, :sort, opts)
|
70
|
+
#
|
71
|
+
def profile_method(klass, method, opts = {}, extra_kvs = {})
|
72
|
+
|
73
|
+
# If we're on an unsupported platform (ahem Mac), just act
|
74
|
+
# like we did something to nicely play the no-op part.
|
75
|
+
return true unless TraceView.loaded
|
76
|
+
|
77
|
+
if RUBY_VERSION < '1.9.3'
|
78
|
+
TraceView.logger.warn "[traceview/error] profile_method: Use the legacy method profiling for Ruby versions before 1.9.3"
|
79
|
+
return false
|
80
|
+
|
81
|
+
elsif !klass.is_a?(Module)
|
82
|
+
TraceView.logger.warn "[traceview/error] profile_method: Not sure what to do with #{klass}. Send a class or module."
|
83
|
+
return false
|
84
|
+
|
85
|
+
elsif !method.is_a?(Symbol)
|
86
|
+
if method.is_a?(String)
|
87
|
+
method = method.to_sym
|
88
|
+
else
|
89
|
+
TraceView.logger.warn "[traceview/error] profile_method: Not sure what to do with #{method}. Send a string or symbol for method."
|
90
|
+
return false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
instance_method = klass.instance_methods.include?(method) || klass.private_instance_methods.include?(method)
|
95
|
+
class_method = klass.singleton_methods.include?(method)
|
96
|
+
|
97
|
+
# Make sure the request klass::method exists
|
98
|
+
if !instance_method && !class_method
|
99
|
+
TraceView.logger.warn "[traceview/error] profile_method: Can't instrument #{klass}.#{method} as it doesn't seem to exist."
|
100
|
+
TraceView.logger.warn "[traceview/error] #{__FILE__}:#{__LINE__}"
|
101
|
+
return false
|
102
|
+
end
|
103
|
+
|
104
|
+
# Strip '!' or '?' from method if present
|
105
|
+
safe_method_name = method.to_s.chop if method.to_s =~ /\?$|\!$/
|
106
|
+
safe_method_name ||= method
|
107
|
+
|
108
|
+
without_traceview = "#{safe_method_name}_without_traceview"
|
109
|
+
with_traceview = "#{safe_method_name}_with_traceview"
|
110
|
+
|
111
|
+
# Check if already profiled
|
112
|
+
if klass.instance_methods.include?(with_traceview.to_sym) ||
|
113
|
+
klass.singleton_methods.include?(with_traceview.to_sym)
|
114
|
+
TraceView.logger.warn "[traceview/error] profile_method: #{klass}::#{method} already profiled."
|
115
|
+
TraceView.logger.warn "[traceview/error] profile_method: #{__FILE__}:#{__LINE__}"
|
116
|
+
return false
|
117
|
+
end
|
118
|
+
|
119
|
+
source_location = []
|
120
|
+
if instance_method
|
121
|
+
::TraceView::Util.send_include(klass, ::TraceView::MethodProfiling)
|
122
|
+
source_location = klass.instance_method(method).source_location
|
123
|
+
elsif class_method
|
124
|
+
::TraceView::Util.send_extend(klass, ::TraceView::MethodProfiling)
|
125
|
+
source_location = klass.method(method).source_location
|
126
|
+
end
|
127
|
+
|
128
|
+
report_kvs = collect_profile_kvs(klass, method, opts, extra_kvs, source_location)
|
129
|
+
report_kvs[:MethodName] = safe_method_name
|
130
|
+
|
131
|
+
if instance_method
|
132
|
+
klass.class_eval do
|
133
|
+
define_method(with_traceview) { | *args, &block |
|
134
|
+
profile_wrapper(without_traceview, report_kvs, opts, *args, &block)
|
135
|
+
}
|
136
|
+
|
137
|
+
alias_method without_traceview, "#{method}"
|
138
|
+
alias_method "#{method}", with_traceview
|
139
|
+
end
|
140
|
+
elsif class_method
|
141
|
+
klass.define_singleton_method(with_traceview) { | *args, &block |
|
142
|
+
profile_wrapper(without_traceview, report_kvs, opts, *args, &block)
|
143
|
+
}
|
144
|
+
|
145
|
+
klass.singleton_class.class_eval do
|
146
|
+
alias_method without_traceview, "#{method}"
|
147
|
+
alias_method "#{method}", with_traceview
|
148
|
+
end
|
149
|
+
end
|
150
|
+
true
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
##
|
156
|
+
# Private: Helper method to aggregate KVs to report
|
157
|
+
#
|
158
|
+
# klass - the class or module that has the method to profile
|
159
|
+
# method - the method to profile. Can be singleton, instance, private etc...
|
160
|
+
# opts - a hash specifying the one or more of the following options:
|
161
|
+
# * :arguments - report the arguments passed to <tt>method</tt> on each profile (default: false)
|
162
|
+
# * :result - report the return value of <tt>method</tt> on each profile (default: false)
|
163
|
+
# * :backtrace - report the return value of <tt>method</tt> on each profile (default: false)
|
164
|
+
# * :name - alternate name for the profile reported in the dashboard (default: method name)
|
165
|
+
# extra_kvs - a hash containing any additional KVs you would like reported with the profile
|
166
|
+
# source_location - array returned from klass.method(:name).source_location
|
167
|
+
#
|
168
|
+
def collect_profile_kvs(klass, method, opts, extra_kvs, source_location)
|
169
|
+
report_kvs = {}
|
170
|
+
report_kvs[:Language] ||= :ruby
|
171
|
+
report_kvs[:ProfileName] ||= opts[:name] ? opts[:name] : method
|
172
|
+
|
173
|
+
if klass.is_a?(Class)
|
174
|
+
report_kvs[:Class] = klass.to_s
|
175
|
+
else
|
176
|
+
report_kvs[:Module] = klass.to_s
|
177
|
+
end
|
178
|
+
|
179
|
+
# If this is a Rails Controller, report the KVs
|
180
|
+
if defined?(::AbstractController::Base) && klass.ancestors.include?(::AbstractController::Base)
|
181
|
+
report_kvs[:Controller] = klass.to_s
|
182
|
+
report_kvs[:Action] = method.to_s
|
183
|
+
end
|
184
|
+
|
185
|
+
# We won't have access to this info for native methods (those not defined in Ruby).
|
186
|
+
if source_location.is_a?(Array) && source_location.length == 2
|
187
|
+
report_kvs[:File] = source_location[0]
|
188
|
+
report_kvs[:LineNumber] = source_location[1]
|
189
|
+
end
|
190
|
+
|
191
|
+
# Merge in any extra_kvs requested
|
192
|
+
report_kvs.merge!(extra_kvs)
|
193
|
+
end
|
48
194
|
end
|
49
195
|
end
|
50
196
|
end
|
data/lib/traceview/api/util.rb
CHANGED
@@ -22,15 +22,16 @@ module TraceView
|
|
22
22
|
|
23
23
|
# Internal: Get the current backtrace.
|
24
24
|
#
|
25
|
-
# ignore - Number of frames to ignore at the
|
26
|
-
# when you know how many layers deep in
|
25
|
+
# ignore - Number of frames to ignore at the top of the backtrace. Use
|
26
|
+
# when you know how many layers deep in the key call is being
|
27
27
|
# made.
|
28
28
|
#
|
29
29
|
# Returns a string with each frame of the backtrace separated by '\r\n'.
|
30
30
|
#
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
def backtrace(ignore = 0)
|
32
|
+
bt = Kernel.caller
|
33
|
+
bt.slice!(0, ignore)
|
34
|
+
trim_backtrace(bt).join("\r\n")
|
34
35
|
end
|
35
36
|
|
36
37
|
# Internal: Trim a backtrace to a manageable size
|
data/lib/traceview/base.rb
CHANGED
@@ -168,9 +168,8 @@ module TraceViewBase
|
|
168
168
|
# False otherwise
|
169
169
|
#
|
170
170
|
def tracing?
|
171
|
-
return false
|
172
|
-
|
173
|
-
TraceView::Context.isValid && !TraceView.never?
|
171
|
+
return false if !TraceView.loaded || TraceView.never?
|
172
|
+
TraceView::Context.isValid
|
174
173
|
end
|
175
174
|
|
176
175
|
def log(layer, label, options = {})
|
data/lib/traceview/config.rb
CHANGED
@@ -18,7 +18,7 @@ module TraceView
|
|
18
18
|
:typhoeus]
|
19
19
|
|
20
20
|
# Subgrouping of instrumentation
|
21
|
-
@@http_clients = [:curb, :excon, :faraday, :httpclient, :nethttp, :rest_client, :typhoeus]
|
21
|
+
@@http_clients = [:curb, :excon, :em_http_request, :faraday, :httpclient, :nethttp, :rest_client, :typhoeus]
|
22
22
|
|
23
23
|
##
|
24
24
|
# Return the raw nested hash.
|
@@ -217,14 +217,14 @@ module TraceView
|
|
217
217
|
elsif key == :include_url_query_params
|
218
218
|
# Obey the global flag and update all of the per instrumentation
|
219
219
|
# <tt>:log_args</tt> values.
|
220
|
-
@@
|
221
|
-
@@config[i][:log_args] = value
|
222
|
-
end
|
220
|
+
@@config[:rack][:log_args] = value
|
223
221
|
|
224
222
|
elsif key == :include_remote_url_params
|
225
223
|
# Obey the global flag and update all of the per instrumentation
|
226
224
|
# <tt>:log_args</tt> values.
|
227
|
-
@@
|
225
|
+
@@http_clients.each do |i|
|
226
|
+
@@config[i][:log_args] = value
|
227
|
+
end
|
228
228
|
end
|
229
229
|
|
230
230
|
# Update liboboe if updating :tracing_mode
|
@@ -0,0 +1,97 @@
|
|
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_noop(*args)
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def profile_method_real(method_name, profile_name, store_args = false, store_return = false, *_)
|
30
|
+
begin
|
31
|
+
# this only gets file and line where profiling is turned on, presumably
|
32
|
+
# right after the function definition. ruby 1.9 and 2.0 has nice introspection (Method.source_location)
|
33
|
+
# but its appears no such luck for ruby 1.8
|
34
|
+
file = ''
|
35
|
+
line = ''
|
36
|
+
if RUBY_VERSION >= '1.9'
|
37
|
+
info = instance_method(method_name).source_location
|
38
|
+
unless info.nil?
|
39
|
+
file = info[0].to_s
|
40
|
+
line = info[1].to_s
|
41
|
+
end
|
42
|
+
else
|
43
|
+
info = Kernel.caller[0].split(':')
|
44
|
+
file = info.first.to_s
|
45
|
+
line = info.last.to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
# Safety: Make sure there are no quotes or double quotes to break the class_eval
|
49
|
+
file = file.gsub(/[\'\"]/, '')
|
50
|
+
line = line.gsub(/[\'\"]/, '')
|
51
|
+
|
52
|
+
# profiling via ruby-prof, is it possible to get return value of profiled code?
|
53
|
+
code = "def _traceview_profiled_#{method_name}(*args, &block)
|
54
|
+
entry_kvs = {}
|
55
|
+
entry_kvs['Language'] = 'ruby'
|
56
|
+
entry_kvs['ProfileName'] = '#{TraceView::Util.prettify(profile_name)}'
|
57
|
+
entry_kvs['FunctionName'] = '#{TraceView::Util.prettify(method_name)}'
|
58
|
+
entry_kvs['File'] = '#{file}'
|
59
|
+
entry_kvs['LineNumber'] = '#{line}'
|
60
|
+
entry_kvs['Args'] = TraceView::API.pps(*args) if #{store_args}
|
61
|
+
entry_kvs.merge!(::TraceView::API.get_class_name(self))
|
62
|
+
|
63
|
+
TraceView::API.log(nil, 'profile_entry', entry_kvs)
|
64
|
+
|
65
|
+
ret = _traceview_orig_#{method_name}(*args, &block)
|
66
|
+
|
67
|
+
exit_kvs = {}
|
68
|
+
exit_kvs['Language'] = 'ruby'
|
69
|
+
exit_kvs['ProfileName'] = '#{TraceView::Util.prettify(profile_name)}'
|
70
|
+
exit_kvs['ReturnValue'] = TraceView::API.pps(ret) if #{store_return}
|
71
|
+
|
72
|
+
TraceView::API.log(nil, 'profile_exit', exit_kvs)
|
73
|
+
ret
|
74
|
+
end"
|
75
|
+
rescue => e
|
76
|
+
TraceView.logger.warn "[traceview/warn] profile_method: #{e.inspect}"
|
77
|
+
end
|
78
|
+
|
79
|
+
begin
|
80
|
+
class_eval code, __FILE__, __LINE__
|
81
|
+
alias_method "_traceview_orig_#{method_name}", method_name
|
82
|
+
alias_method method_name, "_traceview_profiled_#{method_name}"
|
83
|
+
rescue => e
|
84
|
+
TraceView.logger.warn "[traceview/warn] Fatal error profiling method (#{method_name}): #{e.inspect}" if TraceView::Config[:verbose]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# This allows this module to be included and called even if the gem is in
|
89
|
+
# no-op mode (no base libraries).
|
90
|
+
if TraceView.loaded
|
91
|
+
alias :profile_method :profile_method_real
|
92
|
+
else
|
93
|
+
alias :profile_method :profile_method_noop
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -1,97 +1,25 @@
|
|
1
|
-
# Copyright (c) 2013 AppNeta, Inc.
|
2
|
-
# All rights reserved.
|
3
1
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
2
|
+
module TraceView
|
3
|
+
module MethodProfiling
|
4
|
+
def profile_wrapper(method, report_kvs, opts, *args, &block)
|
5
|
+
report_kvs[:Backtrace] = TraceView::API.backtrace(2) if opts[:backtrace]
|
6
|
+
report_kvs[:Arguments] = args if opts[:arguments]
|
23
7
|
|
24
|
-
|
25
|
-
def profile_method_noop(*args)
|
26
|
-
nil
|
27
|
-
end
|
8
|
+
TraceView::API.log(nil, 'profile_entry', report_kvs)
|
28
9
|
|
29
|
-
def profile_method_real(method_name, profile_name, store_args = false, store_return = false, *_)
|
30
10
|
begin
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
file = ''
|
35
|
-
line = ''
|
36
|
-
if RUBY_VERSION >= '1.9'
|
37
|
-
info = instance_method(method_name).source_location
|
38
|
-
unless info.nil?
|
39
|
-
file = info[0].to_s
|
40
|
-
line = info[1].to_s
|
41
|
-
end
|
42
|
-
else
|
43
|
-
info = Kernel.caller[0].split(':')
|
44
|
-
file = info.first.to_s
|
45
|
-
line = info.last.to_s
|
46
|
-
end
|
47
|
-
|
48
|
-
# Safety: Make sure there are no quotes or double quotes to break the class_eval
|
49
|
-
file = file.gsub(/[\'\"]/, '')
|
50
|
-
line = line.gsub(/[\'\"]/, '')
|
51
|
-
|
52
|
-
# profiling via ruby-prof, is it possible to get return value of profiled code?
|
53
|
-
code = "def _traceview_profiled_#{method_name}(*args, &block)
|
54
|
-
entry_kvs = {}
|
55
|
-
entry_kvs['Language'] = 'ruby'
|
56
|
-
entry_kvs['ProfileName'] = '#{TraceView::Util.prettify(profile_name)}'
|
57
|
-
entry_kvs['FunctionName'] = '#{TraceView::Util.prettify(method_name)}'
|
58
|
-
entry_kvs['File'] = '#{file}'
|
59
|
-
entry_kvs['LineNumber'] = '#{line}'
|
60
|
-
entry_kvs['Args'] = TraceView::API.pps(*args) if #{store_args}
|
61
|
-
entry_kvs.merge!(::TraceView::API.get_class_name(self))
|
62
|
-
|
63
|
-
TraceView::API.log(nil, 'profile_entry', entry_kvs)
|
64
|
-
|
65
|
-
ret = _traceview_orig_#{method_name}(*args, &block)
|
66
|
-
|
67
|
-
exit_kvs = {}
|
68
|
-
exit_kvs['Language'] = 'ruby'
|
69
|
-
exit_kvs['ProfileName'] = '#{TraceView::Util.prettify(profile_name)}'
|
70
|
-
exit_kvs['ReturnValue'] = TraceView::API.pps(ret) if #{store_return}
|
71
|
-
|
72
|
-
TraceView::API.log(nil, 'profile_exit', exit_kvs)
|
73
|
-
ret
|
74
|
-
end"
|
11
|
+
rv = self.send(method, *args, &block)
|
12
|
+
report_kvs[:ReturnValue] = rv if opts[:result]
|
13
|
+
rv
|
75
14
|
rescue => e
|
76
|
-
TraceView.
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
rescue => e
|
84
|
-
TraceView.logger.warn "[traceview/warn] Fatal error profiling method (#{method_name}): #{e.inspect}" if TraceView::Config[:verbose]
|
15
|
+
TraceView::API.log_exception(nil, e)
|
16
|
+
raise
|
17
|
+
ensure
|
18
|
+
report_kvs.delete(:Backtrace)
|
19
|
+
report_kvs.delete(:Controller)
|
20
|
+
report_kvs.delete(:Action)
|
21
|
+
TraceView::API.log(nil, 'profile_exit', report_kvs)
|
85
22
|
end
|
86
23
|
end
|
87
|
-
|
88
|
-
# This allows this module to be included and called even if the gem is in
|
89
|
-
# no-op mode (no base libraries).
|
90
|
-
if TraceView.loaded
|
91
|
-
alias :profile_method :profile_method_real
|
92
|
-
else
|
93
|
-
alias :profile_method :profile_method_noop
|
94
|
-
end
|
95
|
-
|
96
24
|
end
|
97
25
|
end
|