美文网首页iOS 开发 iOS DeveloperiOS
iOS 日志相关PART1(NSLog)

iOS 日志相关PART1(NSLog)

作者: 掉了西红柿皮_Kee | 来源:发表于2016-09-26 10:42 被阅读649次
    写在最前面

    恰当的记录用户日志是一门艺术。什么样的信息应该写入日志(通常包括用户行为和错误信息,分开记录),写入日志的信息太少不利于调试,而频繁地记录日志则会影响系统的性能,还会使得日志文件迅速膨胀导致难以查找到需要的信息。对于不同的应用,应该记录的信息是不用的,不过还是有一些通用的规则的。关于日志引擎,有以下几点需要注意:
    1、在开发环境中,应该将日志写入控制台;而在生产环境中,应该将日志写入文件。在调试代码的时候,不输出到控制台就无法在XCode中看到日志。当最好的方式是同时写入控制台和日志文件。
    2、应该分为多种不同的日志级别(错误、警告、信息、详细)。
    3、当某个日志级别被禁用时,相应日志函数的调用开销要非常小。
    4、向控制台或者文件写日志的时候,不可以阻塞调用者线程。
    5、要定期删除日志文件以避免占满磁盘。
    6、日志函数的调用要非常方便,通常使用支持变参的C语法,不建议使用Object-C语法。NSLog的调用凡是非常简单,这一点就值得学习。

    日志参考链接1
    日志参考链接2
    日志参考链接3

    想说的话
    • 在这个向度娘讨教的过程中,我发现如果不想用现有的日志框架:CocoaLumberjack(大神都说这个好用) 的话,最简单的方式就是用iOS自带的首先是日志输出,分为c的printf和标准的NSLog输出,printf会向标准输出(sedout)打印,而NSLog则是向标准出错(stderr),我们需要同时让他们都将日志打印到一个文件中。
      //写入
        freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stdout);
        freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
    
    • 我的方式
    1. 比如说你想在文件中记录页面出现的次数,你可以将NSLog的输出写在-(void)viewDidAppear方法中即可。
      //记录
       [super viewDidAppear];
        NSLog(@"你想记录的东西");
    
    1. 接下来要做的就是log日志的写入操作并保存
      在AppDelegate.m文件中的 didFinishLaunchingWithOptions:方法中写入如下代码:
    //判断是否连接Xcode
       /* if(isatty(STDOUT_FILENO)) {
            return;
        }
        //判断设备是否是模拟器
        UIDevice *device = [UIDevice currentDevice];
        if ([device.model hasSuffix:@"Simulator"]){
            return;
        }*/
        //打印log日志logDic
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        //文件夹路径
        NSString *logDic = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"DBLOG"];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL fileExists = [fileManager fileExistsAtPath:logDic];
        if (!fileExists)
        {
            //创建文件夹logDic
            [fileManager createDirectoryAtPath:logDic withIntermediateDirectories:YES attributes:nil error:nil];
        }
        
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
        [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
        [dateFormatter setDateFormat:@"yyyy-MM-dd"];
        NSString *dateStr = [dateFormatter stringFromDate:[NSDate date]];
        //创建文件
        NSString *logFilePath = [logDic stringByAppendingFormat:@"/%@.log",dateStr];
        //写入
        freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stdout);
        freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
    

    这段代码的主要作用是:使用真机运行应用程序时将所需要的信息日志通过NSLOG写入文件夹。当然写入文件时还可以将错误日志记录并写入文件,如果你不需要记录错误日志将不需要看下面的代码,操作和写入信息的代码类似。

    void UncaughtExceptionHandler(NSException* exception)
    {
        NSString* name = [ exception name ];
        NSString* reason = [ exception reason ];
        NSArray* symbols = [ exception callStackSymbols ]; // 异常发生时的调用栈
        NSMutableString* strSymbols = [ [ NSMutableString alloc ] init ]; //将调用栈拼成输出日志的字符串
        for ( NSString* item in symbols )
        {
            [ strSymbols appendString: item ];
            [ strSymbols appendString: @"\r\n" ];
        }
        
        //将crash日志保存到Document目录下的Log文件夹下
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *logDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"DBLOG"];
        
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if (![fileManager fileExistsAtPath:logDirectory]) {
            [fileManager createDirectoryAtPath:logDirectory  withIntermediateDirectories:YES attributes:nil error:nil];
        }
        
        NSString *logFilePath = [logDirectory stringByAppendingPathComponent:@"UncaughtException.log"];
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
        [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        NSString *dateStr = [formatter stringFromDate:[NSDate date]];
        
        NSString *crashString = [NSString stringWithFormat:@"<- %@ ->[ Uncaught Exception ]\r\nName: %@, Reason: %@\r\n[ Fe Symbols Start ]\r\n%@[ Fe Symbols End ]\r\n\r\n", dateStr, name, reason, strSymbols];
        //把错误日志写到文件中
        if (![fileManager fileExistsAtPath:logFilePath]) {
            [crashString writeToFile:logFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
        }else{
            NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:logFilePath];
            [outFile seekToEndOfFile];
            [outFile writeData:[crashString dataUsingEncoding:NSUTF8StringEncoding]];
            [outFile closeFile];
        }
    }
    
    1. 利用模拟器检测是否在“DBLOG”的文件夹下写入了后缀为.log的日志文件。在任意的模拟机上运行,获取到文件的路径,譬如:


      路径.png

      前往可以看到如下图:


      DBLOG路径下的文件.png 此时已经在此设备的Documents目录下生成了一个名叫“DBLOG”的文件夹来存放log日志。由于我们的日志命名方式我们可以看到今天生成的日志:“2016-09-26.log”,双击可以查看日志的内容。当然日志可以不加后缀,本来就是流的操作,所以无论是传给服务器还是在本地都是可以的,在读取的时候再注意即可。
    作为结束语
    • 利用最常见的NSLog输出已经将日志记录在本地了,但现在并没有对日志的格式进行考究。写的很是粗略,而且在使用的过程中发现实现起来虽然很方便,但是在真机运行时很是浪费系统资源,下一步需要考虑的问题就很多了。。

    生无可怜状。。此PART毕

    相关文章

      网友评论

        本文标题:iOS 日志相关PART1(NSLog)

        本文链接:https://www.haomeiwen.com/subject/rpqqyttx.html