您的位置:首页 > 移动开发 > IOS开发

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

2017-03-17 14:35 621 查看
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为需要新建的文件夹的绝对路径
{
//创建文件夹
[[
9249
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)
{

}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息