토요일, 11월 30, 2013

[B급 프로그래머] 루비 slf4r java_logger의 버그 하나

조금 전문적인 이야기가 될지 몰라 적을까 말까 고민하다, 혹시 jruby에서 slf4r을 사용하다 동일한 문제에 부딪힐지도 모르는 개발자분들을 위해 간략하게 팁을 정리하고 넘어가겠다. 다름이 아니라, jruby에서 Java의 slf4j와 연계해 같은 로그 파일에 기록하려면 slf4r에 속한 java_logger를 사용하면 딱인데, 사소한 버그 하나 때문에 애로 사항이 꽃핀다.

java_logger.rb에서 문제가 되는 코드 일부를 가져와봤다. 눈썰미 있는 독자라면 숨겨진 폭탄을 하나 찾을 수 있을테다. 5분을 줄테니 코드를 검토해 벌레를 잡아보자.

    def #{level}(msg = nil, exception = nil)
      if(@logger.is_#{level}_enabled)
        msg, exception = yield if block_given?
        if(exception.type == NativeException)
          @logger.#{level}(msg, exception.cause)
        else
          @logger.#{level}("\#{msg}\#{format(exception)}")
        end
      end
    end

이미 짐작하는 바와 같이, 위 코드는 exception이 nil이 아닌 경우에만 정상 동작한다. 만일 exception이 nil일 경우 nil에서 type을 찾으므로 런타임 오류가 발생한다. 그렇다면 어떻게 수정하면 문제가 해결될까? 다음과 같이 단순하게 exception.nil?을 사용하는 nil 점검 루틴을 넣어보았다.

    def #{level}(msg = nil, exception = nil)
      if(@logger.is_#{level}_enabled)
        msg, exception = yield if block_given?
        if exception.nil?
          @logger.#{level}(msg)
        else
          if(exception.type == NativeException)
            @logger.#{level}(msg, exception.cause)
          else
            @logger.#{level}("\#{msg}\#{format(exception)}")
          end
        end
      end
    end

연이은 null 연재물로 인해 지금쯤이면 B급 프로그래머를 null 애호가로 부르고 싶을지도 모르겠다. 이렇게 null로 이미지를 굳힌 김에... 다음 시간에 또 다른 null 관련 이야기 보따리를 풀어보겠다. 기대하시라~

EOB

댓글 없음:

댓글 쓰기