class Tracing::Tracer
Attributes
delayed[RW]
indent[RW]
nested[RW]
Public Class Methods
new()
click to toggle source
# File lib/tracing.rb, line 54 def initialize reinitialize end
Public Instance Methods
available_keys()
click to toggle source
# File lib/tracing.rb, line 80 def available_keys @available.keys end
disable(key)
click to toggle source
# File lib/tracing.rb, line 102 def disable key !key.empty? and @keys.delete(key.to_sym) end
display(key, msg)
click to toggle source
# File lib/tracing.rb, line 212 def display key, msg puts msg end
enable(key)
click to toggle source
# File lib/tracing.rb, line 92 def enable key if !key.empty? && !@keys[s = key.to_sym] @keys[s] = true setup_help if s == :help setup_flame if s == :flame else true end end
enabled()
click to toggle source
# File lib/tracing.rb, line 88 def enabled @keys.keys end
enabled?(key)
click to toggle source
# File lib/tracing.rb, line 84 def enabled? key !key.empty? && @keys[key.to_sym] end
reinitialize()
click to toggle source
# File lib/tracing.rb, line 58 def reinitialize @indent = 0 # Current nesting level of enabled trace blocks @nested = false # Set when a block enables all enclosed tracing @available = {} # Hash of available trace keys, accumulated during the run @delayed = nil # A delayed message, emitted only if the enclosed block emits tracing @keys = {} if (e = ENV["TRACE"]) e.split(/[^_a-zA-Z0-9]/).each{|k| enable(k) } end end
setup_debugger()
click to toggle source
# File lib/tracing.rb, line 141 def setup_debugger begin require 'ruby-trace ' Debugger.start # (:post_mortem => true) # Some Ruby versions crash on post-mortem debugging rescue LoadError # Ok, no debugger, tough luck. end if trace :trap trap('SIGINT') do puts "Stopped at:\n\t"+caller*"\n\t" debugger true # Stopped on SIGINT end end errors = [] ( [ENV["DEBUG_PREFERENCE"]].compact + [ 'byebug', 'pry', 'debugger', 'ruby-trace ' ] ).each do |debugger| begin require debugger if debugger == 'byebug' Kernel.class_eval do alias_method :debugger, :byebug end end ::Debugger.start if (const_get(::Debugger) rescue nil) return rescue LoadError => e errors << e end end # Report when we couldn't load any debugger $stderr.puts(errors.inspect) end
setup_firstaid()
click to toggle source
# File lib/tracing.rb, line 185 def setup_firstaid if trace :firstaid puts "Preparing first aid kit" ::Exception.class_eval do alias_method :firstaid_initialize, :initialize def initialize *args, &b send(:firstaid_initialize, *args, &b) # Array#flatten calls to_ary, ignore it when it comes from Gem Specifications: return if NoMethodError === self && message =~ /^undefined method `to_ary' for \#<Gem::Specification/ # LoadErrors are not hard to diagnose, and polyglot uses them return if LoadError === self return if self.message =~ /uninitialized constant Mini[Tt]est/ # From RSpec usually # The Array() method calls to_ary and/or to_a before making a new array, ignore that: clr = caller return if NoMethodError === self && clr.detect{|frame| frame =~ /in `Array'/} puts "Stopped due to #{self.class}: #{message} at "+clr*"\n\t" debugger true # Stopped in Exception constructor end end end end
setup_flame()
click to toggle source
# File lib/tracing.rb, line 124 def setup_flame require 'ruby-prof' require 'ruby-prof-flamegraph' profile_result = RubyProf.start at_exit { profile_result2 = RubyProf.stop printer = RubyProf::FlameGraphPrinter.new(profile_result2) data_file = "/tmp/flamedata_#{Process.pid}.txt" svg_file = "/tmp/flamedata_#{Process.pid}.svg" flamegraph = File.dirname(__FILE__)+"/flamegraph.pl" File.popen("tee #{data_file} | perl #{flamegraph} --countname=ms --width=4800 > #{svg_file}", "w") { |f| printer.print(f, {}) } STDERR.puts("Flame graph dumped to file:///#{svg_file}") } end
setup_help()
click to toggle source
# File lib/tracing.rb, line 118 def setup_help at_exit { $stderr.puts "---\nTracing keys available: #{@available.keys.map{|s| s.to_s}.sort*", "}" } end
show(*args)
click to toggle source
# File lib/tracing.rb, line 216 def show(*args) key, enabled_prefix = *selected?(args) # Emit the message if enabled or a parent is: if enabled_prefix && args.size > 0 message = "\##{enabled_prefix} " + ' '*@indent + args. map{|a| a.respond_to?(:call) ? a.call : a}. join(' ') if @delay @delayed = [@delayed, message].compact*"\n" # Arrange to display this message later, if necessary @delay = false else if @delayed display key, @delayed # Display a delayed message, then the current one @delayed = nil @delay = false end display key, message end end @indent += (enabled_prefix ? 1 : 0) !!enabled_prefix end
toggle(key)
click to toggle source
# File lib/tracing.rb, line 106 def toggle key if !key.empty? if enabled?(key) disable(key) false else enable(key) true end end end
trace(*args) { |: (size == 0 ? self : enabled)| ... }
click to toggle source
# File lib/tracing.rb, line 70 def trace(*args, &block) begin old_indent, old_nested, old_delayed, enabled = @indent, @nested, @delayed, show(*args) # This monstrosity reduces the steps when single-stepping: block ? yield : (args.size == 0 ? self : enabled) ensure @indent, @nested, @delayed = old_indent, old_nested, old_delayed end end
Private Instance Methods
selected?(args)
click to toggle source
# File lib/tracing.rb, line 245 def selected?(args) # Figure out whether this trace is enabled (itself or by :all), if it nests, and if we should print the key: @delay = false key = if Symbol === args[0] control = args.shift case s = control.to_s when /!\Z/ # Enable all nested trace calls nested = true s.sub(/!\Z/, '').to_sym when /\?\Z/ # Delay this message until a nested active trace @delay = true s.sub(/\?\Z/, '').to_sym else control end else :all end @available[key] ||= key # Remember that this trace was requested, for help if @nested || # This trace is enabled because it's in a nested block @keys[key] || # This trace is enabled in its own right @keys[:all] # This trace is enabled because all are if @keys[:keys] || @keys[:all] # Use a formatting prefix? enabled_prefix = " %-15s"%key @keys[key] = enabled_prefix if @keys[key] == true # Save the formatting prefix else enabled_prefix = '' end @nested ||= nested # Activate nesting, if requested end [key, enabled_prefix] end