デバッグモードを使う
Rubyにはグローバル変数$DEBUGが定義されている。これは、Rubyインタプリタに--debugオプションを渡すか、コード$DEBUGをtrueにすることで有効になる。
loggerを使う
Ruby標準ライブラリのLoggerを使って、ログデータをファイルまたは別のストリームに出力する。
ログレベルはFATAL,ERROR,WARN,INFO,DEBUGの5段階。
require 'logger'
log = Logger.new(STDOUT)
#log.level = Logger::ERROR
#log.level = Logger::FATAL
#log.level = Logger::WARN
#log.level = Logger::INFO
log.level = Logger::DEBUG
log.error("Error!!");
log.fatal("Fatal!!");
log.debug("Created logger")
log.info("Program started");
log.warn("Nothing to do!");
出力
E, [2008-09-25T21:37:18.168000 #5664] ERROR -- : Error!!
F, [2008-09-25T21:37:18.168000 #5664] FATAL -- : Fatal!!
D, [2008-09-25T21:37:18.168000 #5664] DEBUG -- : Created logger
I, [2008-09-25T21:37:18.168000 #5664] INFO -- : Program started
W, [2008-09-25T21:37:18.178000 #5664] WARN -- : Nothing to do!
Loggerは期間あるいはファイルサイズを元にrotateしてログファイルを交換することもできる。
Logger.new('logfile.log', 'monthly') #月ごとにログファイルを交換 他にdaily, weeklyが指定できる。
Logger.new('logfile.log', 5, 100 * 1024 * 1024) #100MBのログを5つまで保持する
Logger.new('logfile.log', 0, 100 * 1024 * 1024) #100MBでログファイルを交換
datetime_formatを変更することで日付フォーマットを変更できる。
log = Logger.new(STDOUT)
log.datetime_format = "%Y-%m-%d %H:%M:%S"
さらに、Logger::Formatterのcallをオーバーライドすれば、さらに出力を変更できる。
Kernel#callerでコールスタックを調べる。
Kernel#callerによって呼び出し元のメソッドを調べることができる。
class ClassA
def ClassA.some_methodA
ClassB.some_methodB
end
end
class ClassB
def ClassB.some_methodB
ClassC.do_action
end
end
class ClassC
def ClassC.do_action
puts 'show trace back'
caller.each do |c|
puts c
end
end
end
ClassA.some_methodA
出力
show trace back
trace_back.rb:9:in `some_methodB'
trace_back.rb:3:in `some_methodA'
trace_back.rb:22
Breakpointライブラリを使用する
メソッドbreakpointを実行すると、irbの対話型のRubyセッションに切り替わります。
require 'breakpoint'
$KCODE ='sjis'
class Foo
def initialize(init_val)
@instance_var = init_val
end
def bar
test_var = @instance_var
puts 'before break'
breakpoint
puts 'after break'
puts "test_var: #{test_var}, @instance_var: #{@instance_var}"
end
end
f = Foo.new('start')
f.bar
プロファイリング機能を使用する
アプリケーションにRubyプロファイラをインクルードすると、rubyはアプリケーション終了後に標準エラー出力にレポートを出力する。
require 'profile'
total=0
('a'..'zz').each do |seq|
['a', 'b', 'c'].each do |i|
if seq.index(i)
total += 1
break
end
end
end
puts "Total: #{total}"
出力
Total: 150
% cumulative self self total
time seconds seconds calls ms/call ms/call name
48.00 0.12 0.12 702 0.17 0.27 Array#each
24.00 0.18 0.06 1952 0.03 0.03 String#index
24.00 0.24 0.06 1 60.00 250.00 Range#each
4.00 0.25 0.01 150 0.07 0.07 Fixnum#+
0.00 0.25 0.00 1 0.00 0.00 String#<=>
0.00 0.25 0.00 702 0.00 0.00 String#succ
0.00 0.25 0.00 1 0.00 0.00 Kernel.puts
0.00 0.25 0.00 2 0.00 0.00 IO#write
0.00 0.25 0.00 1 0.00 0.00 Fixnum#to_s
0.00 0.25 0.00 1 0.00 250.00 #toplevel
プロファイラは最も時間のかかるメソッドからリストアップする。