それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

rubyのLoggerでログを出力する方法

ruby のロガーについて調べておきました

ruby ではログを出すときに Logger が便利です。

require 'logger'

logger = Logger.new(STDOUT)

標準出力に出す場合は STDOUT($stdout) 、標準エラー出力に出す場合は STDERR($strerr) を指定する。

ログを出す

logger をインスタンス化したら、ログを書き出す。

logger.info('Hello Log')
# => I, [2017-06-07T13:53:15.178750 #20342]  INFO -- : Hello Log

ログの出し方:ログレベルに応じたログを書く

log()のような関数はなく、ログレベルに応じたメソッドを使う。

ログレベルは、 debug, info, warn, error, fatal, unknown があり、それぞれが、メソッド名になっている。

logger.debug('メッセージ')
logger.info('メッセージ')
logger.warn('メッセージ')
logger.fatal('メッセージ')
logger.unknown('メッセージ')

まとめて実行してみる。 Object.send(:method_name, args )インスタンスメソッドを呼び出せるのでそれを利用する。

[:debug,:info,:warn,:error,:fatal,:unknown].each{|e| logger.send(e,"message at level #{e}") }

実行結果

>> [:debug,:info,:warn,:error,:fatal,:unknown].each{|e| logger.send(e,"message at level #{e}") }
D, [2017-06-07T13:55:36.802479 #20342] DEBUG -- : message at level debug
I, [2017-06-07T13:55:36.802532 #20342]  INFO -- : message at level info
W, [2017-06-07T13:55:36.802549 #20342]  WARN -- : message at level warn
E, [2017-06-07T13:55:36.802562 #20342] ERROR -- : message at level error
F, [2017-06-07T13:55:36.802574 #20342] FATAL -- : message at level fatal
A, [2017-06-07T13:55:36.802585 #20342]   ANY -- : message at level unknown

ログのレベル

ログのレベルは次のようになっていて、debug が一番弱い。

  1. debug
  2. info
  3. warn
  4. error
  5. fatal
  6. unknown

一番弱いのはdebug。 弱いとは、設定でログ書き出しを無視することが出来る。

LOG_LEVELが info なら debug は書き出されない。

ログレベルに応じてフィルタをする。

ログにはレベルがあって debug, info, warn, error, fatal, unknown の順になっている。

すべてのログを出力する(デフォルト)

デフォルトではすべてのログを出力する Logger::DEBUG(=0) になっていて、ログを出すとすべてが書かれる

require 'logger'
logger = Logger.new(STDOUT)
logger.level == Logger::DEBUG #=> true

レベルを INFO にする

INFOにすると、DEBUGのメッセージが無視される。

logger.level = Logger::INFO
[:debug,:info,:warn,:error,:fatal,:unknown].each{|e| logger.send(e,"message at level #{e}") }

実行結果( debug のメッセージは捨てられる)

I, [2017-06-07T14:01:51.257465 #20342]  INFO -- : message at level info 
W, [2017-06-07T14:01:51.257579 #20342]  WARN -- : message at level warn
E, [2017-06-07T14:01:51.257608 #20342] ERROR -- : message at level error
F, [2017-06-07T14:01:51.257712 #20342] FATAL -- : message at level fatal
A, [2017-06-07T14:01:51.257743 #20342]   ANY -- : message at level unknown

長めのメッセージを出力する

ブロックで渡せる

logger.info {  "現在のログレベルは " + logger.level.to_s + "です" }
#=> I, [2017-06-07T14:05:42.599811 #20342]  INFO -- : 現在のログレベルは 1です

時刻は別にいらないんだけど、短く出来る?

できる。

開発中とか時刻は別にいらないんだけどってとき

logger.datetime_format = '%Y-%m-%d %H:%M:%S'
logger.datetime_format = ''
logger.info("サンプル")
#=>I, [#20342]  INFO -- : サンプル

番号とか記号も決めたい

proc を渡せばO.K.

logger.formatter = proc do |severity, datetime, progname, msg|
   ">>>>>> #{msg}\n"
end
logger.info("サンプル")
# =>  >>>>>> サンプル

書式に意味有るの?

ある。ログ書式を元に、複数のサーバーからエラーログを集めたり、ログに基づいた通知をしたりする。

参考資料

https://docs.ruby-lang.org/en/2.0.0/Logger.html#class-Logger-label-How+to+close+a+logger