ios 打印 详细错误日志_Ios自定义日志打印以及捕捉崩溃日志并存入文件

本文介绍了如何在iOS应用中实现自定义的日志打印,并捕获和记录详细的错误及崩溃日志。通过CHLogger类,可以设置未捕获的异常处理器,处理信号异常,并将日志文件上传。日志包括错误、信息和调试级别,以及异常的堆栈信息、原因和名称。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 @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)

{

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值