(iOS) cocoalumberjack 를 이용한 logger 탑재

NSLog 의 지겨움을 느끼던 차에 로거가 필요하다는 생각은 늘 하고 있었지만 문제는 언제 도입하느냐였는데 만들고 있는 것이 블루투스 앱인지라, 로그를 세세하게 받아야 하는 급박한 상황이 생겨서 로거를 넣자는 생각을 하였다. stackoverflow, OSXDEV 등에 문의를 한 결과 몇가지의 로거가 있었는데 그 중에 내가 선택한것은 cocoalumberjack 이다. 제약조건은:

 

 
 1. 최대한 LOG4J 와 비슷해야한다. 
 2. iOS7 에서도 잘 동작해야한다. 
 3. 파일의 형태로 로그를 떨굴수 있어야 한다. 
 
 
[OSXDEV](http://osxdev.org/forum/index.php?threads/logger-%EC%B6%94%EC%B2%9C%ED%95%B4%EC%A3%BC%EC%84%B8%EC%9A%94.279/) 에서 많은 글들이 달렸는데 NSLogger 라는 좋은 라이브러리도 있었지만, cocoalumberjack을 사용하게 되었고 어떻게 사용했는지, 그리고 wrapping 해서 사용한 방식에 대해서 공유하고자 한다. 
 
**1. 설치 하기 **
 
[https://github.com/robbiehanson/CocoaLumberjack ](https://github.com/robbiehanson/CocoaLumberjack)
 
위의 링크에 가서 일단 zip 파일의 형태로 다운을 받고 압축을 푼다. 디렉토리 중에 Lumberjack 라는 디렉토리가 있는데 그 디렉토리를 본인의 xcode 프로젝트에 붙여 넣기를 한다. 
 
** **
**2. 초기 세팅하기 **
 
lgo4j도 처음에 log4j.properties를 설정하듯이 이 Lumberjack 로거도 초기 세팅작업을 해줘야 한다. 물론 log4j처럼 xml 형식을 사용하는 것은 아닌데 대부분의 경우 앱이 시작하는 AppDelegate.m의 didFinishLaunchingWithOptions: 메소드에서 아래의 작업을 해주면 된다. 일단 코드를 보고 설명하겠다. 
 
  logger.h를 import 했는데 아래의 코드를 보면 알겠지만 Lumberjack 에서 사용하는 여러가지 헤더파일을 한곳에서 관리하기 위해서 만든 헤더파일이다. 이렇게 만든 이유는 여러 뷰에서 사용할 경우, 몇개의 헤더파일을 다 적어줘야 하는 귀찮음이 있어서 logger.h 라는 파일에 묶었다.    일단 3가지의 로거(logger) 가 있음을 알려드리는데 용도는 다음과 같다.   
 – DDASLogger : Apple System 로거인 Console.app 으로 출력  – DDTTYLogger : 로그를 xcode 터미널로 출력   – DDFileLogger : 로그를 파일로 출력 
    이렇게 기본적으로 3가지 로거가 있고 DDLog 에 위의 로거들을 생성해서 add 한후에, DDLog 내 메소드를 통해서 실제 로그를 남길수가 있는 방식이다. 즉, 사용하는 쪽에서 필요한 로그를 생성을 하고 추가해 주면 된다. 코드를 보면 로거를 생성해서 [DDLog addLogger:xcLogger]; 이런식으로 추가하는 부분을 볼수 있을것이다.          ** 3. 로그 남기기 **   대부분의 로그 프레임워크가 그러하겠지만 레벨이라는 것이 존재하는데 Lumberjack 에도 로그 레벨이 존재한다. 로깅레벨은 아래와 같은데, 설정을 하면 해당 레벨과 해당레벨 이하는 모두 출력이 된다.  
error < warn < info < verbose 
  위의 로그레벨에 따른 로그를 남길때 쓰는 함수는 아래와 같다.   
DDLogError  DDLogWarn  DDLogInfo  DDLogVerbose 
   자, 그럼 로그 레벨을 어떻게 설정을 할까? 위의 logger.h 파일을보면   
static const int ddLogLevel = LOG_LEVEL_WARN; 
  전역 변수가 있는데 이 부분이 바로 로그 레벨을 설정하는 부분이다. 해당 로그레벨을 어떻게 설정하느냐에 따라서 로그가 남는가 안남느냐의 차이가 있다. 예를 들어,   
DDLogVerbose(@”TEST1″);  DDLogWarn(@”TEST2″);
  이렇게 남겼다고 할때 ddLogLevel 이 LOG_LEVEL_WARN 이기 때문에 TEST1은 출력되지 않는다. 이렇게 하게되면 기본적으로 로그를 남길수가 있다.     하지만 몇가지 더 추가한다면 금상첨화인데, 특히 필자의 경우 파일 로그를 남겨서 ITUNES 로 빼고 싶었고, 당연히 로거라면 일정한 포맷이 맞아야 보기 편한것을 알고 있기 때문에 그런 설정을 위해서 몇가지 추가적인 설정 코드를 넣어야 했다.        **4. Custom Format 만들기 **    
[https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters ](https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters)
  여기에 가면 Custom Format을 만드는 내용이 나온다. 자세히 보면 알겠지만 Thread Safe 한것을 만들것인가 하는 부분에 대한 내용인데, advanced 부분을 기반코드로 해서 만들었다. 스레드 관련해서 보고 싶은 분들은 한번 읽어 보시면 될것 같다. 일단 기본적으로 3가지 로거들은 DDLogFormatter 형의 변수인 logFormatter 를 가지고있어서 포맷을 지정할수가 있다. 그렇기 때문에 DDLogFormatter 를 상속받는 클래스를 만들면 되는데, 사실상 포맷을 지정하는 부분은 formatLogMessage: 메소드 부분이다.      위의 코드를 보면 쉽게 이해할수 있는데 로그를 찍게 되면 내부적으로 DDLogMessage 객체가 전달 받게 되는데 이 객체에는 로그 메시지 뿐만 아니라 시간, 로그 레벨, 호출 함수, 클래스, 줄번호 등을 가지고 있어서 그런것들을 필요에 따라서 NSString 형으로 넣어 주면 된다. 생각보다 어렵지 않을 것이다. 본인이 필요한 정보에 맞게 넣어 주면 된다. 그리고 나서 만든 로거, 여기서는 LoggerFormatter 라는 클래스의 객체를 만들어서 만든 로거들에게 연결해 주면 된다.        **5. DDFileLogger **   파일에 남길때가 왔다. DDLogFileManagerDefault를 사용하기로 했는데 이것의 역할은 파일이 남는 디렉토리를 지정할수 있다. 디렉토리를 itunes 로 뽑아야 하기 때문에 app의 Document 경로를 로그파일을 남기는 위치로 설정했고 DDLogFileManagerDefault 생성시 해당 위치를 넘겨주면 된다. DDFileLogger를 생성하면서 앞에서 만든 DDLogFileManagerDefault 객체를 넘겨주면서 생성하면 된다. 그렇게 되면 일단 로그파일이 어디에 남을것인지에 대해서 지정한 것이다. 기타 파일 사이즈나, 로그 파일의 몇개 남길것인지 등등은 레퍼런스를 참고하면 된다.        **6. DEBUG 와 RELEASE **   로그를 ITUNES로 뽑는것은 성공했는데, Release 에서도 그러면 당연 안될것이기 때문에 logger.h 에서 DEBUG 인지를 체크해서 로그레벨을 다르게 주도록 하였고 로그레벨에 따라서 파일로거를 추가할지 안할지를 결정하였다. 생각보다 로거를 세팅하는 작업이 빡세긴 하지만 신기하기도 하고 재밌었다.     위의 만들어둔 부분의 아래의 필자의 github 링크에서 받아서 쓸수 있다. 기본 저장소에서 fork 받았고 Lumberjack 디렉토리 안에 위에서 설명한 logger.h, LoggerFormatter.h, LoggerFormatter.m 그리고 AppDelegate.m 에서 사용한 예제 소스코드를 넣어두었다. 이상한 부분이 있으면 알려주시길.   
[https://github.com/AhnSeongHyun/CocoaLumberjack](https://github.com/AhnSeongHyun/CocoaLumberjack) 
  ** ** ** ** **Reference ** [1] http://hiddenviewer.tistory.com/15