traceview 3.1.0-java → 3.2.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 +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
|