iOS日志收集:宏定义NSLog并写入日志中

iOS日志收集:宏定义NSLog并写入日志中_第1张图片

实际开发测试中,经常出现测试提交的问题或反馈在开发端不能复现的问题,通常都是Xcode联调打印日志去排查,而且打印信息可能不具体,所以想到了宏定义NSLog打印更多信息,并且输出到日志中,直接可以从设备上拿到日志去分析,基于以上要求,测试完成了一下功能希望能帮助需要的人、

主要分为两步操作

  • 一.自定义输出

     在pch文件中添加以便我们在整个项目中都是使用,代码如下
    
#ifdef DEBUG
# define GALLog(fmt, ...) NSLog((@"[路径:%s]\n" "[函数名:%s]\n" "[行号:%d] \n" fmt), [[NSString stringWithFormat:@"%s", __FILE__].lastPathComponent UTF8String], __FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define GALLog(fmt,...) NSLog(@"" fmt);
//# define GALLog(...);
#endif

名词解释:

宏 说明
func 打印当前函数或方法,c字符串
LINE 打印当前行号,整数
FILE 打印当前文件路径,c字符串
FUNCTION 打印当前函数或方法(在C++中会包含参数类型),c字符串

举例:


iOS日志收集:宏定义NSLog并写入日志中_第2张图片
宏定义打印

在viewDidLoad中使用自定义的 GALLog(@"123"); 打印信息如图非常详细。

  • 二.将日志写入文件

这一步也非常简单,只需要在AppDelegate.m的didFinishLaunchingWithOptions 中调用以下方法即可。


iOS日志收集:宏定义NSLog并写入日志中_第3张图片
20180517161953389.png

具体代码给出如下:

#pragma mark - 日志收集
- (void)redirectNSlogToDocumentFolder
{
    NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    
    NSDateFormatter *dateformat = [[NSDateFormatter  alloc]init];
    [dateformat setDateFormat:@"yyyy-MM-dd-HH-mm-ss"];
    NSString *fileName = [NSString stringWithFormat:@"LOG-%@.txt",[dateformat stringFromDate:[NSDate date]]];
    NSString *logFilePath = [documentDirectory stringByAppendingPathComponent:fileName];
    
    // 先删除已经存在的文件
    NSFileManager *defaultManager = [NSFileManager defaultManager];
    [defaultManager removeItemAtPath:logFilePath error:nil];
    
    NSLog(@"%@",logFilePath);
    
    // 将log输入到文件
    freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stdout);
    
    freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
}

最终可以在指定的logFilePath中拿到日志如图:


iOS日志收集:宏定义NSLog并写入日志中_第4张图片
屏幕快照 2018-05-17 下午4.42.54.png

重点在于 - freopen
freopen()函数用于文件流的的重定向,一般是将 stdin、stdout 和 stderr 重定向到文件。
所谓重定向,就是改变文件流的源头或目的地。stdout(标准输出流)的目的地是显示器,printf()是将流中的内容输出到显示器;可以通过freopen()将stdout 的目的地改为一个文件(如output.txt),再调用 printf(),就会将内容输出到这个文件里面,而不是显示器。 freopen()函数的原型为: FILE *freopen(char *filename, char *type, FILE *stream);

这里通过这个方法就可以将前面我们打印在控制台的信息全部写去到文件中去,可以通过设备直接拿到日志文件去分析。


注意

通过以上两步就可以实现前面所要求的功能,有几点需要注意的在这里提及一下;
1.这里所写的宏定义输出是在DEBUG模式下可用的,在release模式下我这里还是系统的NSLog输出,使用时可以自己调整。
上面的#if #endif宏定义就是如果定义了DEBUG,那么就使用GALLog输出;否则这段代码就直接忽略不执行.这个Xcode的默认设置,我们可以取消DEBUG模式,开启RELEASE发布模式,如下面的截图所示.
  选择Product->Scheme->Edit Scheme

  

iOS日志收集:宏定义NSLog并写入日志中_第5张图片
A34941E7-3E6D-425D-A93A-F0158845902D.png

2.如果debug模式下在AppDelegate.m的didFinishLaunchingWithOptions 中调用了redirectNSlogToDocumentFolder,那么Xcode控制台是不会打印的,打印信息会全部写入日志文件中,所以这里使用的时候需要注意。
3.拿到的日志我们可以通过接口定期上传到我们自己的服务器。

你可能感兴趣的:(iOS日志收集:宏定义NSLog并写入日志中)