异常日志记录 DDLog

项目中如果想把异常捕获再写入文件,有个十分容易使用的库DDLog.

首先导入库,在git上下载。

一:在项目初始化指定全局LogLeve ,一般在xxxapp.m中

staticconstint ddLogLevel = LOG_LEVEL_VERBOSE;

二:

复制代码
 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{NSExceptionHandler *exceptionHandler = [NSExceptionHandler defaultExceptionHandler] ;exceptionHandler.delegate = self;exceptionHandler.exceptionHandlingMask = NSLogAndHandleEveryExceptionMask;DBSDDFileLogger *fileLogger = [[DBSDDFileLogger alloc] init];fileLogger.maximumFileSize = 1;  //  1024*1 KBfileLogger.rollingFrequency = 1;       // 60*60*60 SecondsfileLogger.logFileManager.maximumNumberOfLogFiles = 4;[DDLog addLogger:fileLogger];
}
复制代码
- (BOOL)exceptionHandler:(NSExceptionHandler *)sender shouldLogException:(NSException *)exception mask:(unsigned int)mask
{[self printStackTrace:exception];return YES;
}
复制代码
- (void)printStackTrace:(NSException *)e//要写入log文件的信息
{NSString *stack = [[e userInfo] objectForKey:NSStackTraceKey];NSMutableArray *args = [NSMutableArray arrayWithCapacity:20];if (stack) {NSTask *ls = [[NSTask alloc] init];NSString *pid = [[NSNumber numberWithInt:[[NSProcessInfo processInfo] processIdentifier]] stringValue];[args addObject:@"-p"];//-p
        [args addObject:pid];[args addObjectsFromArray:[stack componentsSeparatedByString:@"  "]];// Note: function addresses are separated by double spaces, not a single space.[ls setLaunchPath:@"/usr/bin/atos"];//xcrun atos
        [ls setArguments:args];// [ls launch];NSPipe *pipe;pipe = [NSPipe pipe];[ls setStandardOutput: pipe];NSFileHandle *file;file = [pipe fileHandleForReading];[ls launch];NSData *data;data = [file readDataToEndOfFile];NSString *string;string = [[NSString alloc] initWithData: dataencoding: NSUTF8StringEncoding];NSString *strFormat = [NSString stringWithFormat:@"\n\n*************************exception begin\nexception time: %@\n%@\n*************************exception end\n\n",[NSDate date] ,string];DDLogCError(strFormat);} else {DDLogCError(@"No stack trace available.");}
}
复制代码

 

三 。两个自定义类。这里的DBSDDFileLogger继承于DDFileLogger,目的在于自定义log文件的路径。如下:

复制代码
#import "DBSDDFileLogger.h"
#import "DBSDDLogFileManagerDefault.h"
#define DBSLogDir @"DBstudio/Files/Logs"
@implementation DBSDDFileLogger
- (id)init{DBSDDLogFileManagerDefault *defaultLogFileManager = [[DBSDDLogFileManagerDefault alloc] initWithLogsDirectory:[self getDBSCacheLogsDir]];return [self initWithLogFileManager:defaultLogFileManager];
}
- (NSString*)getDBSCacheLogsDir{NSString *dir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)objectAtIndex:0];NSString *cachedLogDir=[dir stringByAppendingPathComponent:DBSLogDir];return cachedLogDir;
}
复制代码

 DBSDDLogFileManagerDefault 继承自  DDLogFileManagerDefault 目的在于自定义log文件的路径

复制代码
@implementation DBSDDLogFileManagerDefault
- (NSString *)generateShortUUID{NSDate *date = [[NSDate alloc] init];NSDateFormatter *threadUnsafeDateFormatter = [[NSDateFormatter alloc] init];[threadUnsafeDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];NSString *dateFormatString = @"yyyy-MM-dd";[threadUnsafeDateFormatter setDateFormat:dateFormatString];NSString *filename = [threadUnsafeDateFormatter stringFromDate:date];return filename;
}
- (NSString *)createNewLogFile{NSString *logsDirectory = [self logsDirectory];int index = 1;NSString *fileName = [NSString stringWithFormat:@"dbs-log-%@.txt", [self generateShortUUID]];do{NSString *filePath = [logsDirectory stringByAppendingPathComponent:fileName];if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]){[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];// Since we just created a new log file, we may need to delete some old log files
            [super deleteOldLogFiles];NSLog(@"create file:%@",fileName);return filePath;}else{NSString *strFile = [filePath stringByDeletingPathExtension];NSString *strFileName = [strFile lastPathComponent];NSString *strFileNameFormat = [self isContainCharacter:strFileName];if (strFileNameFormat) {strFileName = strFileNameFormat;}fileName =[NSString stringWithFormat:@"%@(%d).%@",strFileName,index,[filePath pathExtension]];index++;}} while(YES);
}- (NSString*)isContainCharacter:(NSString*)fileName{NSString *strCharachter = @"(";NSRange foundPer=[fileName rangeOfString:strCharachter options:NSCaseInsensitiveSearch];if(foundPer.length>0) {NSRange rang;rang.location = 0;rang.length = foundPer.location;NSString *strRes = [fileName substringWithRange:rang];return strRes;}else {return nil;}
}- (BOOL)isLogFile:(NSString *)fileName{if (fileName && [fileName length]>3) {NSRange rang;rang.location = [fileName length] - 4;rang.length = 4;NSString *strTmpName = [fileName substringWithRange:rang];if ([strTmpName isEqualToString:@".txt"]) {rang.location = 0;rang.length = 4;strTmpName = [fileName substringWithRange:rang];if ([@"dbs-" isEqualToString:strTmpName]) {return YES;}}}return NO;
}
复制代码

 

 

好了,test一下

复制代码
- (IBAction)test:(id)sender {//@try {NSMutableArray *array = [NSMutableArray array];[array addObject:nil];//}//@catch (NSException *exception) {//@throw exception;//}//@finally {//}
}