Ios自定义日志打印以及捕捉崩溃日志并存入文件

来源:互联网 发布:三星手机手电筒软件 编辑:程序博客网 时间:2024/06/06 18:10

1.调用ios提供的NSSetUncaughtExceptionHandler方法捕捉崩溃信息,如:NSSetUncaughtExceptionHandler (&chUncaughtExceptionHandler);,其中参数“&chUncaughtExceptionHandler”为方法的地址。

2.上述方法并不能catch所有崩溃情况,如内存访问错误。它会抛出signal信号,所以还需做signal处理

3.在程序路入口处设置崩溃信息捕捉[CHLoggersetDefaultUncaughtExceptionHandler];

4.输出其他异常,如:[[CHLoggershareInstance]error:@"%s timeOut:%@ exp:%@",__func__,_timeOutStr, [exreason]];

具体实现如下:

首先定义一个CHLogger类,文件代码如下

CHLogger.h

#import <Foundation/Foundation.h>@interface CHLogger : NSObject+(CHLogger *)shareInstance;+ (void)setDefaultUncaughtExceptionHandler;-(void)error:(NSString *)format,...;-(void)info:(NSString *)format,...;-(void)debug:(NSString *)format,...;#pragma mark -捕捉崩溃日志void chUncaughtExceptionHandler(NSException *exception);#pragma mark -signal处理void SignalHandler(int signal);#pragma mark -上传日志文件-(void)uploadLogFile:(NSString *)taskId logDate:(NSString *)logDate logType:(NSString *)logType;@end

CHLogger.m

#import "CHLogger.h"#define LOG_TIME_FORMAT @"yyyy-MM-dd HH:mm:ss.SSS"#define LOG_QUEUE_ID "log_queue"static CHLogger *_instance=nil;static dispatch_queue_t queue_log;static NSUncaughtExceptionHandler *_handler;@implementation CHLogger@synthesize _logLevel;+(CHLogger *)shareInstance{    @synchronized(self)    {        if(_instance==nil)        {            _instance=[[self alloc]init];                        queue_log = dispatch_queue_create(LOG_QUEUE_ID, DISPATCH_QUEUE_SERIAL);        }            }    return _instance;}#pragma mark -设置crash+ (void)setDefaultUncaughtExceptionHandler{     NSSetUncaughtExceptionHandler (&chUncaughtExceptionHandler);    signal(SIGABRT, SignalHandler);    signal(SIGILL, SignalHandler);    signal(SIGSEGV, SignalHandler);    signal(SIGFPE, SignalHandler);    signal(SIGBUS, SignalHandler);    signal(SIGPIPE, SignalHandler);    }#pragma mark -获取崩溃日志void chUncaughtExceptionHandler(NSException *exception){        // 异常的堆栈信息    NSArray *stackArray = [exception callStackSymbols];    // 出现异常的原因    NSString *reason = [exception reason];    // 异常名称    NSString *name = [exception name];    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];    [formatter setDateFormat:LOG_TIME_FORMAT];    NSString *time = [formatter stringFromDate:[NSDate date]];    NSString *exceptionInfo = [NSString stringWithFormat:@"%@Exception reason:%@\nException name:%@\nException stack:%@", time, name, reason, stackArray];        [self writeLogfile:exceptionInfo fileName:LOG_CRASH]; }void SignalHandler(int signal){    //拦截signal}-(void)debug:(NSString *)format,...{       if(self._logLevel < LOG_LEVEL_DEBUG)    {        return ;    }    if (format != NULL)    {        @try {            CFStringRef param = (__bridge CFStringRef)format;            va_list args;            va_start(args, format);            CFStringRef s = CFStringCreateWithFormatAndArguments(NULL, NULL, param, args);            va_end(args);            if (s != NULL)            {                NSString *msg = [NSString stringWithFormat:@"%@\n", (__bridge NSString *)s];                              [self printMsg:[self formatLogMsg:msg]];            }        } @catch (NSException *exception) {                  }            }}-(NSString *)formatLogMsg:(NSString *)formatText{    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];    [formatter setDateFormat:LOG_TIME_FORMAT];    NSString *time = [formatter stringFromDate:[NSDate date]];    NSMutableString *msg = [NSMutableString stringWithFormat:@"%@ ", time];    [msg appendString:formatText];        return msg;}-(void)info:(NSString *)format,...{     if(self._logLevel < LOG_LEVEL_INFO)    {        return ;    }    if (format != NULL)    {        @try {            CFStringRef param = (__bridge CFStringRef)format;            va_list args;            va_start(args, format);            CFStringRef s = CFStringCreateWithFormatAndArguments(NULL, NULL, param, args);            va_end(args);            if (s != NULL)            {                NSString *msg = [NSString stringWithFormat:@"%@\n", (__bridge NSString *)s];                               [self printMsg:[self formatLogMsg:msg]];            }        } @catch (NSException *exception) {                   }    }}-(void)error:(NSString *)format,...{       if(self._logLevel < LOG_LEVEL_ERROR)    {        return ;    }    if (format != NULL)    {        @try {            CFStringRef param = (__bridge CFStringRef)format;            va_list args;            va_start(args, format);            CFStringRef s = CFStringCreateWithFormatAndArguments(NULL, NULL, param, args);            va_end(args);            if (s != NULL)            {                NSString *msg = [NSString stringWithFormat:@"%@\n", (__bridge NSString *)s];                              [self printMsg:[self formatLogMsg:msg]];            }        } @catch (NSException *exception) {                   }    }}-(NSString *)createLogFileName{    NSString *date = [PubMethod getFormatStrFromDate:[NSDate date] formatStr:TIME_FORMAT_TEXT_D];    NSString *fileName = [NSString stringWithFormat:@"%@.log", date];        return fileName;}-(void)printMsg:(NSString *)msg{    dispatch_async(queue_log, ^{        [self writeLogfile:msg fileName:[self createLogFileName]];    });}#pragma mark -输出日志+ (void)writeLogfile:(NSString *)msg fileName:(NSString *)fileName{    @try    {        NSString *homePath = [_instance getLogFileDir];        if (![[NSFileManager defaultManager] fileExistsAtPath:homePath])//判断createPath路径文件夹是否已存在,此处createPath为需要新建的文件夹的绝对路径        {            //创建文件夹            [[NSFileManager defaultManager] createDirectoryAtPath:homePath withIntermediateDirectories:YES attributes:nil error:nil];        }        NSString *filePath = [homePath stringByAppendingPathComponent:fileName];                NSFileManager *fileManager = [NSFileManager defaultManager];                if(![fileManager fileExistsAtPath:filePath]) //如果不存在        {            [msg writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];                    }                NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:filePath];                [fileHandle seekToEndOfFile];  //将节点跳到文件的末尾                NSData* stringData  = [msg dataUsingEncoding:NSUTF8StringEncoding];                [fileHandle writeData:stringData]; //追加写入数据                [fileHandle closeFile];    }    @catch(NSException *e)    {    }}}



0 0
原创粉丝点击