로그는 언제 어떻게 남기는 것일까
처음으로 서버 프로그래밍을 할 때, 가장 낯선 개념 중 하나가 로그였다. 로그를 남기는 이유는 막연하게나마 알 것 같은데 언제, 어떻게 남겨야 할지는 허공의 구름을 잡는 듯한 느낌이었다. 뭔가 잡히는 것 같은데 안 잡히는… 그래서 새로운 콘텐츠를 담당하게 되었을 때, 로그를 제대로 남기어보고 싶어서 그에 대한 고민을 해 보았다.
로그를 도대체 왜 남길까? 그 이유는 간단하다. 로그는 표시다. 로그는 표시를 하기 위해서 남긴다. 그렇다면 왜 표시를 하냐. 바로 표시된 부분을 알기 위해서이다. 왜 표시된 부분을 알아야 하냐. 그것이 로직의 흐름이나, 문제점이나, 오작동여부를 확인하는 데 도움을 주기 때문이다. 그렇다. 로그를 남기는 이유는 로직이 의도된 바로 흐르는지, 내 코드의 문제나 내 코드를 잘못 사용한 코드가 없는지를 감지하기 위해서이다.
로그의 주 된 목표인 오류를 방지하기 위한 로그에 대해 생각해보자. 오류엔 두 종류가 있다. 내가 실수해서 생긴 오류, 그리고 다른 프로그래머가 내 코드를 잘못 사용해 생긴 오류이다. 전자나 후자나 로그를 남기는 방식은 똑같다. 어느 함수의 몇 번째 줄에 위치한 에러인지를 기록하고, 그 에러를 가장 잘 표현해주는 메시지를 남기도록 한다. 또한 그 에러가 발생한 정황을 역추적할 수 있는 정보들도 함께 출력해주면 원인을 더 쉽게 찾을 수 있다.
객체지향의 환경에서 클래스를 구현할 때, 오류에 대해서 우리가 신경 써야 할 2가지 가정이 있다. 절대 가정과 체크 가정이다. 절대 가정은 그것이 사실이라는 가정하에 클래스를 구현할 정도로 당연시 되는 가정이다. 따라서 사실이 아니면 오작동을 하거나 프로그램이 크래쉬가 날 수 있다. 너무나 당연히 사실이어야 하는 부분이기에 보통 따로 그 에러를 체크하여 로그를 남기지는 않는다. 하지만 크래쉬가 난다는 것은 서버 프로그래머에게 있어서 매우 치명적인 에러이기 때문에 퍼포먼스상의 하향이 있어도 가능한 한 이런 오류도 체크를 해서 로그로 남기고 크래쉬가 나지 않도록 돌려 처리하는 것이 좋다. 아닌 경우 헤더파일에 이러한 가정에 대해서 분명히 명시하는 것이 좋다. 이러한 가정은 행여나 인수인계 후 다른 사람이 그 클래스를 수정할 때 반드시 알고 있어야 하는 부분이므로 타작업자의 소스 분석의 혼돈을 줄이기 위해서라도 꼭 명시해 주도록 한다. 절대 가정은 아주 위험한 결과를 초래할 수 있기 때문에 그 내부 사정을 잘 알고 있는 클래스 내부에서만, 혹은 아주 결합도가 높은 컴퍼넌트 레벨에서만 하도록 한다.
Check 가정은 그 클래스 외부에서 그 클래스를 올바로 사용하는지를 검출하기 위한 것이다. 다른 메소드를 호출한 후에 호출해야 할 메소드를 바로 호출하거나, 클래스 멤버의 어떤 값을 설정해야 유효한 메소드를 설정 없이 호출한다거나, 무효한 값의 파라미터를 넘기는 행위 등은 오작동을 초래할 수 있다. 이런 외부동작에 대해서 그 클래스는 무조건 무결성으로 동작하는 것이 좋은 코드이지만 로그나 어썰트를 남기어 주는 것은 그러한 잘못된 사용을 감지하고 수정하는 데에도 도움을 준다. 이 경우 우린 로그를 남기어 그 코드를 사용하는 사람이 오류를 수정하도록 도와준다.