tracing 2.0.7 → 2.0.8
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/lib/tracing.rb +125 -125
- data/lib/tracing/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 451b42647f93a6905678d300be911fd882a26a50
|
4
|
+
data.tar.gz: 4744af46b946edab0f575bad81f1dafe0d1fdd49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a53aa1036fa7f803e9a4b8b8a1a2a28e2d7806874f64b2362ef3fa95f5b95d723a45f888bd43022cedd325375d3d46c52b1654fbf5dcaa9a7331c4f45def4b0
|
7
|
+
data.tar.gz: 3dedf16b095bb81b078f49428d10e57287e1a1813d110a277a865ab274ee5b462a29f9a217e3e7f239c3367b8d303e705cd73ed6bcebe04e9b94d948eb9c4526
|
data/lib/tracing.rb
CHANGED
@@ -56,24 +56,24 @@ module Tracing
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def reinitialize
|
59
|
-
@indent = 0
|
59
|
+
@indent = 0 # Current nesting level of enabled trace blocks
|
60
60
|
@nested = false # Set when a block enables all enclosed tracing
|
61
|
-
@available = {}
|
62
|
-
@delayed = nil
|
61
|
+
@available = {} # Hash of available trace keys, accumulated during the run
|
62
|
+
@delayed = nil # A delayed message, emitted only if the enclosed block emits tracing
|
63
63
|
|
64
64
|
@keys = {}
|
65
65
|
if (e = ENV["TRACE"])
|
66
|
-
|
66
|
+
e.split(/[^_a-zA-Z0-9]/).each{|k| enable(k) }
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
def trace(*args, &block)
|
71
71
|
begin
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
old_indent, old_nested, old_delayed, enabled = @indent, @nested, @delayed, show(*args)
|
73
|
+
# This monstrosity reduces the steps when single-stepping:
|
74
|
+
block ? yield : (args.size == 0 ? self : enabled)
|
75
75
|
ensure
|
76
|
-
|
76
|
+
@indent, @nested, @delayed = old_indent, old_nested, old_delayed
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -91,11 +91,11 @@ module Tracing
|
|
91
91
|
|
92
92
|
def enable key
|
93
93
|
if !key.empty? && !@keys[s = key.to_sym]
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
@keys[s] = true
|
95
|
+
setup_help if s == :help
|
96
|
+
setup_flame if s == :flame
|
97
97
|
else
|
98
|
-
|
98
|
+
true
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
@@ -105,19 +105,19 @@ module Tracing
|
|
105
105
|
|
106
106
|
def toggle key
|
107
107
|
if !key.empty?
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
108
|
+
if enabled?(key)
|
109
|
+
disable(key)
|
110
|
+
false
|
111
|
+
else
|
112
|
+
enable(key)
|
113
|
+
true
|
114
|
+
end
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
118
|
def setup_help
|
119
119
|
at_exit {
|
120
|
-
|
120
|
+
$stderr.puts "---\nTracing keys available: #{@available.keys.map{|s| s.to_s}.sort*", "}"
|
121
121
|
}
|
122
122
|
end
|
123
123
|
|
@@ -126,86 +126,86 @@ module Tracing
|
|
126
126
|
require 'ruby-prof-flamegraph'
|
127
127
|
profile_result = RubyProf.start
|
128
128
|
at_exit {
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
129
|
+
profile_result2 = RubyProf.stop
|
130
|
+
printer = RubyProf::FlameGraphPrinter.new(profile_result2)
|
131
|
+
data_file = "/tmp/flamedata_#{Process.pid}.txt"
|
132
|
+
svg_file = "/tmp/flamedata_#{Process.pid}.svg"
|
133
|
+
flamegraph = File.dirname(__FILE__)+"/flamegraph.pl"
|
134
|
+
File.popen("tee #{data_file} | perl #{flamegraph} --countname=ms --width=4800 > #{svg_file}", "w") { |f|
|
135
|
+
printer.print(f, {})
|
136
|
+
}
|
137
|
+
STDERR.puts("Flame graph dumped to file:///#{svg_file}")
|
138
138
|
}
|
139
139
|
end
|
140
140
|
|
141
141
|
def setup_debugger
|
142
142
|
begin
|
143
|
-
|
144
|
-
|
143
|
+
require 'ruby-trace '
|
144
|
+
Debugger.start # (:post_mortem => true) # Some Ruby versions crash on post-mortem debugging
|
145
145
|
rescue LoadError
|
146
|
-
|
146
|
+
# Ok, no debugger, tough luck.
|
147
147
|
end
|
148
148
|
|
149
149
|
if trace :trap
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
150
|
+
trap('SIGINT') do
|
151
|
+
puts "Stopped at:\n\t"+caller*"\n\t"
|
152
|
+
debugger
|
153
|
+
true # Stopped on SIGINT
|
154
|
+
end
|
155
155
|
end
|
156
156
|
|
157
157
|
errors = []
|
158
158
|
(
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
159
|
+
[ENV["DEBUG_PREFERENCE"]].compact +
|
160
|
+
[
|
161
|
+
'byebug',
|
162
|
+
'pry',
|
163
|
+
'debugger',
|
164
|
+
'ruby-trace '
|
165
|
+
]
|
166
166
|
).each do |debugger|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
167
|
+
begin
|
168
|
+
require debugger
|
169
|
+
if debugger == 'byebug'
|
170
|
+
Kernel.class_eval do
|
171
|
+
alias_method :debugger, :byebug
|
172
|
+
end
|
173
|
+
end
|
174
|
+
::Debugger.start if (const_get(::Debugger) rescue nil)
|
175
|
+
return
|
176
|
+
rescue LoadError => e
|
177
|
+
errors << e
|
178
|
+
end
|
179
179
|
end
|
180
180
|
|
181
181
|
# Report when we couldn't load any debugger
|
182
|
-
$stderr.
|
182
|
+
$stderr.puts(errors.inspect)
|
183
183
|
end
|
184
184
|
|
185
185
|
def setup_firstaid
|
186
186
|
if trace :firstaid
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
187
|
+
puts "Preparing first aid kit"
|
188
|
+
::Exception.class_eval do
|
189
|
+
alias_method :firstaid_initialize, :initialize
|
190
|
+
|
191
|
+
def initialize *args, &b
|
192
|
+
send(:firstaid_initialize, *args, &b)
|
193
|
+
# Array#flatten calls to_ary, ignore it when it comes from Gem Specifications:
|
194
|
+
return if NoMethodError === self && message =~ /^undefined method `to_ary' for \#<Gem::Specification/
|
195
|
+
|
196
|
+
# LoadErrors are not hard to diagnose, and polyglot uses them
|
197
|
+
return if LoadError === self
|
198
|
+
return if self.message =~ /uninitialized constant Mini[Tt]est/ # From RSpec usually
|
199
|
+
|
200
|
+
# The Array() method calls to_ary and/or to_a before making a new array, ignore that:
|
201
|
+
clr = caller
|
202
|
+
return if NoMethodError === self && clr.detect{|frame| frame =~ /in `Array'/}
|
203
|
+
|
204
|
+
puts "Stopped due to #{self.class}: #{message} at "+clr*"\n\t"
|
205
|
+
debugger
|
206
|
+
true # Stopped in Exception constructor
|
207
|
+
end
|
208
|
+
end
|
209
209
|
end
|
210
210
|
end
|
211
211
|
|
@@ -218,24 +218,24 @@ module Tracing
|
|
218
218
|
|
219
219
|
# Emit the message if enabled or a parent is:
|
220
220
|
if enabled_prefix && args.size > 0
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
221
|
+
message =
|
222
|
+
"\##{enabled_prefix} " +
|
223
|
+
' '*@indent +
|
224
|
+
args.
|
225
|
+
map{|a| a.respond_to?(:call) ? a.call : a}.
|
226
|
+
join(' ')
|
227
|
+
|
228
|
+
if @delay
|
229
|
+
@delayed = [@delayed, message].compact*"\n" # Arrange to display this message later, if necessary
|
230
|
+
@delay = false
|
231
|
+
else
|
232
|
+
if @delayed
|
233
|
+
display key, @delayed # Display a delayed message, then the current one
|
234
|
+
@delayed = nil
|
235
|
+
@delay = false
|
236
|
+
end
|
237
|
+
display key, message
|
238
|
+
end
|
239
239
|
end
|
240
240
|
@indent += (enabled_prefix ? 1 : 0)
|
241
241
|
!!enabled_prefix
|
@@ -246,33 +246,33 @@ module Tracing
|
|
246
246
|
# Figure out whether this trace is enabled (itself or by :all), if it nests, and if we should print the key:
|
247
247
|
@delay = false
|
248
248
|
key =
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
@available[key] ||= key
|
266
|
-
if @nested ||
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
249
|
+
if Symbol === args[0]
|
250
|
+
control = args.shift
|
251
|
+
case s = control.to_s
|
252
|
+
when /!\Z/ # Enable all nested trace calls
|
253
|
+
nested = true
|
254
|
+
s.sub(/!\Z/, '').to_sym
|
255
|
+
when /\?\Z/ # Delay this message until a nested active trace
|
256
|
+
@delay = true
|
257
|
+
s.sub(/\?\Z/, '').to_sym
|
258
|
+
else
|
259
|
+
control
|
260
|
+
end
|
261
|
+
else
|
262
|
+
:all
|
263
|
+
end
|
264
|
+
|
265
|
+
@available[key] ||= key # Remember that this trace was requested, for help
|
266
|
+
if @nested || # This trace is enabled because it's in a nested block
|
267
|
+
@keys[key] || # This trace is enabled in its own right
|
268
|
+
@keys[:all] # This trace is enabled because all are
|
269
|
+
if @keys[:keys] || @keys[:all] # Use a formatting prefix?
|
270
|
+
enabled_prefix = " %-15s"%key
|
271
|
+
@keys[key] = enabled_prefix if @keys[key] == true # Save the formatting prefix
|
272
|
+
else
|
273
|
+
enabled_prefix = ''
|
274
|
+
end
|
275
|
+
@nested ||= nested # Activate nesting, if requested
|
276
276
|
end
|
277
277
|
|
278
278
|
[key, enabled_prefix]
|
@@ -287,7 +287,7 @@ class Object
|
|
287
287
|
begin
|
288
288
|
# This monstrosity reduces the steps when single-stepping:
|
289
289
|
tracer = (Tracing.tracer ||= Tracing::Tracer.new) and
|
290
|
-
|
290
|
+
(old_indent, old_nested, old_delayed, enabled = tracer.indent, tracer.nested, tracer.delayed, tracer.show(*args))
|
291
291
|
|
292
292
|
block ? yield : (args.size == 0 ? tracer : enabled)
|
293
293
|
ensure
|
data/lib/tracing/version.rb
CHANGED