NSLog 로그 파일 출력

2008.02.25 15:37 from iPhone

CocoaDev에서 내용을 찾아보면 다음과 같은 형식으로 NSLog의 내용을 파일 출력이 가능하다고 한다.

NSArray *searchPaths =
NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libraryFolder = [searchPaths objectAtIndex:0];
NSString *logPath = [[libraryFolder stringByAppendingPathComponent:@"Logs"]
    stringByAppendingPathComponent:
    [[[NSBundle mainBundle] objectForInfoDictionaryKey: @"CFBundleExecutable"]
            stringByAppendingPathExtension:@"log"]];   
freopen([logPath fileSystemRepresentation], "a", stderr);

기존 Cocoa에서 사용되는 방법으로 iPhone에서 로그를 남겨보려고 하면 위 방법으로는 동작하지 않는다. 이는 NSLog의 출력이 stderr이 아니기 때문인 것 같다.

따라서 XLog를 사용하고 printf부분을 fprintf(stderr, ...)으로 변경하면 ~/Library/Logs에 로그가 생성됨을 알 수 있다. (단 디렉터리는 생성되어 있어야 한다.)

XLog.h

extern void XLog(NSString *format, ...);
extern void XFTimeLog(CFAbsoluteTime *time, NSString *format, ...);
 

XLog.m

void _XLog(CFAbsoluteTime *lastTime, NSString *format, va_list argList) {   
    CFAbsoluteTime time = CFAbsoluteTimeGetCurrent();
    static unsigned logcount = 0;
    if (logcount++ % 100 == 0) NSLog(@"logcount: %i", logcount);
    static CFTimeZoneRef zone = nil;
    if (!zone) zone = CFTimeZoneCopyDefault();
    CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(time, zone);
    if (lastTime) {
        double elapsed_time = time - *lastTime;
        unsigned total_sec = elapsed_time;
        double fraction = elapsed_time - (double)total_sec;
        unsigned milli = fraction * 1000.0f;
        unsigned micro = fraction * 1000000.0f;
        micro %= 1000;
        // log elapsed time [sec.ms_us|pid]
        fprintf(stderr, "[%03i.%03i_%03i|%i] ", total_sec, milli, micro, getpid());
    } else {
        unsigned sec = date.second;
        double fraction = date.second - (double)sec;
        unsigned milli = fraction * 1000.0f;
        // log standard time [hours:min:sec.ms|pid]
        fprintf(stderr, "[%02i:%02i:%02i.%03i|%i] ", date.hour, date.minute, sec, milli, getpid());
    }
    CFStringRef log = CFStringCreateWithFormatAndArguments(NULL, NULL, (CFStringRef)format, argList);
    char *ptr = (char *)CFStringGetCStringPtr(log, kCFStringEncodingUTF8);
    if (ptr)    
        fprintf(stderr, "%s\n", ptr);
    else {
        unsigned buflen = CFStringGetLength(log) * 4;
        ptr = malloc(buflen);
        if (CFStringGetCString(log, ptr, buflen, kCFStringEncodingUTF8));
        fprintf(stderr, "%s\n", ptr);
        free(ptr);
    }
    fflush(stderr);
    CFRelease(log);   
}

void XLog(NSString *format, ...) {   
    va_list argList;
    va_start(argList, format);
    _XLog(nil, format, argList);
    va_end(argList);   
}

void XFTimeLog(CFAbsoluteTime *time, NSString *format, ...) {   
    va_list argList;
    va_start(argList, format);
    _XLog(time, format, argList);
    va_end(argList);
    if (time) *time = CFAbsoluteTimeGetCurrent();   
}

Posted by NOP 트랙백 0 : 댓글 0