rubyでエラーコード付きの独自例外クラスを作成 + カスタムloggerで出力
アプリケーション開発でエラーの管理は特に重要で、あるエラーに対しては、エラーコードxxxの用に管理していくことが多いかなと思いますが、JavaとかだったらExceptionを継承して独自の例外クラスを作ったりしたんだけど、Rubyだとどうしたら良いかなと考え、作成してみました。
要求
Sample
# coding: utf-8 require 'logger' require 'json' ENV["TZ"] = "Asia/Tokyo" ## # 自作logger class class MyLogger < Logger def debug(progname = nil, method_name = nil, msg) super(progname) { { method_name: method_name, message: msg } } end def info(progname = nil, method_name = nil, msg) super(progname) { { method_name: method_name, message: msg } } end def warn(progname = nil, method_name = nil, msg) super(progname) { { method_name: method_name, message: msg } } end # Point 1 def error(progname = nil, method_name = nil, msg, error_code, backtrace) super(progname) { { method_name: method_name, message: msg, error_code: error_code, backtrace: backtrace } } end def fatal(progname = nil, method_name = nil, msg, error_code, backtrace) super(progname) { { method_name: method_name, message: msg, error_code: error_code, backtrace: backtrace } } end ## # logをjson形式で class JSONFormatter < Logger::Formatter # Point 2 def call(severity, time, progname, msg) { level: severity, time: time, program_name: progname.to_s, content: msg }.to_json + "\n" end end end ## # 自作exception class class MyException < StandardError def initialize(error_code, message) @code = error_code # Point 3 super("[#{error_code}] - #{message}") end def self.exception(error_code, message) self.new(error_code, message) end def self.throw(error_code) self.new(error_code, error_message(error_code)) end # Point 4 def self.error_message(error_code) # error_codeをyaml等で管理しておくと便利 end end ## # 例外補足にエラーコードを取れるように Exception.class_eval do # Point 5 def code @code ||= "---" end end class ExceptionTest def error begin raise MyException.exception("100", "Error1") rescue => e raise e end end def default_error begin raise StandardError.new "StandardError" rescue => e raise e end end end test = ExceptionTest.new logger = MyLogger.new(STDOUT) begin test.error rescue MyException => e logger.error(self, e.message, e.code, e.backtrace) rescue => e logger.error(self, e.message, e.code, e.backtrace) end logger.formatter = MyLogger::JSONFormatter.new begin test.default_error rescue => e logger.error(self, e.message, e.code, e.backtrace) end
Output
E, [2016-04-13T23:36:11.820632 #32316] ERROR -- main: {:method_name=>nil, :message=>"[100] - Error1", :error_code=>"100", :backtrace=>["lib/sample_exception.rb:81:in `error'", "lib/sample_exception.rb:102:in `<main>'"]} {"level":"ERROR","time":"2016-04-13 23:36:11 +0900","program_name":"main","content":{"method_name":null,"message":"StandardError","error_code":"---","backtrace":["lib/sample_exception.rb:90:in `default_error'","lib/sample_exception.rb:111:in `<main>'"]}}