美文网首页IOS开发小技巧
关于App日志与奔溃信息的简单记录与上传

关于App日志与奔溃信息的简单记录与上传

作者: Stark_Dylan | 来源:发表于2015-09-24 15:42 被阅读1582次
  1. Log日志的写入本地。
///----------------------------------
///  @name 调试输出
///----------------------------------

#import "_pragma_push.h"

#import <Foundation/Foundation.h>

#define DLogOut( ... ) if([DLFrameDebug sharedInstance].enabled)\
[[DLFrameDebug sharedInstance] file:@(__FILE__) line:__LINE__ func:@(__PRETTY_FUNCTION__) format:__VA_ARGS__];

@interface DLFrameDebug : NSObject

@singleton(DLFrameDebug)

/*!
 *  是否打开log
 */
@prop_assign(BOOL, enabled)

/// LogLevel, without in this framework

- (void)file:(NSString *)file line:(NSUInteger)line func:(NSString *)func format:(NSString *)format, ...;

@end

#import "_pragma_pop.h"
#import "DLFrameDebug.h"

@implementation DLFrameDebug

@def_singleton(DLFrameDebug)

- (void)file:(NSString *)file line:(NSUInteger)line func:(NSString *)func format:(NSString *)format, ... {
    
    if ( nil == format || NO == [format isKindOfClass:[NSString class]] )
        return;
    
    va_list args;
    va_start( args, format );
    
    [self file:file line:line func:func format:format args:args];
    
    va_end( args );
}

- (void)file:(NSString *)file line:(NSUInteger)line func:(NSString *)func format:(NSString *)format args:(va_list)params {
    
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    
    @autoreleasepool {
        
        NSMutableString * content = [[NSMutableString alloc] initWithFormat:(NSString *)format arguments:params];
        
        if ( content && content.length )
        {
            NSMutableString * text = [[NSMutableString alloc] init];
            if ( text ) {
                
                [text appendString:content];
                
                if ( [text rangeOfString:@"%"].length )
                {
                    [text replaceOccurrencesOfString:@"%"
                                          withString:@"%%"
                                             options:NSLiteralSearch
                                               range:NSMakeRange(0, text.length)];
                }
                
                if (![[NSFileManager defaultManager] fileExistsAtPath:DL_LOG_PATH]) {
                    
                    [[NSFileManager defaultManager] createFileAtPath:DL_LOG_PATH contents:nil attributes:nil];
                }
                
                NSString * logStr = [NSString stringWithContentsOfFile:DL_LOG_PATH encoding:NSUTF8StringEncoding error:nil];
                
                if (logStr) {
                    
                    logStr = [logStr stringByAppendingFormat:@"\n\n[TIME]:%@\n[FILE]:%@\n[FUNC]:%@\n[LINE]:%ld\n----->\n[INFO]:\n%@\n<-----\n", [NSDate date], file, func, (unsigned long)line, text];
                } else {
                    
                    logStr = text;
                }
                
                [logStr writeToFile:DL_LOG_PATH atomically:YES encoding:NSUTF8StringEncoding error:nil];
                
                fprintf( stderr, "\n\n--->\n[TIME]:%s\n[FUNC]:%s\n[LINE]:%d\n[INFO]:\n%s\n<---\n\n", [NSString stringWithFormat:@"%@", [NSDate date]].UTF8String, func.UTF8String, line, [text UTF8String]);
            }
        }
    }
}

@end

这样, 我们完成了Log日志的本地写入, 上边这种方法只是最普通的办法, 原本打算使用FILE然后重指向stderr的, 嘿嘿想想还是算了。 俗气的才是高大上的。 直接writetofile。

  1. Exception的捕获。

在ApplicationDidFinishLaunch中, 设置异常捕获的方法


    if ([DLFrameDebug sharedInstance].enabled) {
        
        // Add Exception Handler
        NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
    }

并实现这个方法, 使用Log把异常Log到日志中

void UncaughtExceptionHandler(NSException *exception) {
    
    NSArray *callStack = [exception callStackSymbols];
    NSString *reason = [exception reason];
    NSString *name = [exception name];
    NSString *content = [NSString stringWithFormat:@"\n异常错误报告\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[callStack componentsJoinedByString:@"\n"]];
    
    DLogOut(@"%@", content);
}
  1. 是否正常退出

我专门写了一个Manager的单例类, 用来管理这个,要注册响应的应用程序状态的通知.

    // Add Notification For Default Manager
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(UIApplicationDidFinishLaunchingNotification)
                                                 name:UIApplicationDidFinishLaunchingNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(UIApplicationDidEndBackgroundNotification)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(UIApplicationDidBecameActive)
                                                 name:UIApplicationDidBecomeActiveNotification
                                               object:nil];

在程序退到后台的时候, 设置一下正确退出了、 进入前台的时候设置不正确退出。 这样的话, 程序非正常退出的时候判断一下bool值就可以了。 在上次正常的情况下清理Log文件, 如果没有正常退出那就发送信息到服务器, 并清空。

- (void)UIApplicationDidFinishLaunchingNotification {
    
    // start some application operations
    [self startUp];
}

- (void)UIApplicationDidEndBackgroundNotification {
    
    // Change the Application Exit Status
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:ApplicationExited];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)UIApplicationDidBecameActive {
    
    // check application exit normal
    [self checkApplicationExitedNormal];
 
    // set first launch
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:ApplicationFirstLaunch];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)checkApplicationExitedNormal {
    NSLog(@"%d", [NSUserDefaults boolForKey:ApplicationExited]);
    if (![NSUserDefaults boolForKey:ApplicationExited] && ![NSUserDefaults boolForKey:ApplicationFirstLaunch]) {
        
        // Application first launch
    } else if ([NSUserDefaults boolForKey:ApplicationFirstLaunch] && ![NSUserDefaults boolForKey:ApplicationExited]) {
        
        NSString * logStr = [NSString stringWithContentsOfFile:DL_LOG_PATH encoding:NSUTF8StringEncoding error:nil];
        
        if (logStr) {
            
            [DLServer POST:@"logs.api" param:[@{
                                                @"data" : logStr
                                                } mutableCopy] complete:^(BOOL requestSuccess, id responseObject) {
                
            } error:^(NSError *error) {
                
            }];
        }
        
        [self clearLogFile];
    } else {
        
        // Exited Normal
        [self clearLogFile];
    }
}

- (void)clearLogFile {
    
    NSString * logStr = [NSString stringWithContentsOfFile:DL_LOG_PATH encoding:NSUTF8StringEncoding error:nil];
    if (logStr) {
        
        logStr = @"";
        [logStr writeToFile:DL_LOG_PATH atomically:YES encoding:NSUTF8StringEncoding error:nil];
    }
    
    DLogOut(@"%@, %@", DL_VERSION, DL_APP);
    
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:ApplicationExited];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)startUp {
    
    if ([DLFrameDebug sharedInstance].enabled) {
        
        // Add Exception Handler
        NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
    }
    
    [[DLFrame_ClassLoader classLoader] loadClasses:@[
                                                     
                                                     @"DLOperation"
                                                     
                                                     ]];
}

CopyRight@Dylan 2015-9-24.

相关文章

  • 关于App日志与奔溃信息的简单记录与上传

    Log日志的写入本地。 这样, 我们完成了Log日志的本地写入, 上边这种方法只是最普通的办法, 原本打算使用FI...

  • 错误日志/奔溃日志上传功能

    奔溃日志上传: 注意点:需要自己补充上传后台的内容.奔溃日志会在下次打开APP时自动将日志文件传给后台 错误日志上...

  • DYLD, Library not loaded: /usr/l

    奔溃日志 奔溃表现:iOS12.1 及以下启动奔溃奔溃日志: 解决方法:关闭bitcode,重新打包上传appst...

  • iOS开发日志通过ftp上传的方法

    在开发过程中,需要收集奔溃日志,那怎么做到奔溃日志上传呢,通常集成第三方工具,什么友盟、蒲公英、腾讯之类的统计软件...

  • iOS奔溃日志分析

    iOS奔溃日志分析 前言(扯淡) iOS奔溃日志能够比较有效的分析奔溃的原因,方便我们debug我们的项目。当然现...

  • iOS崩溃时收集崩溃信息

    背景 1.在App上线时我们没有办法log手机的奔溃日志,现在网上有很多第三方收集奔溃日志的方法,常用的例如Cra...

  • iOS友盟奔溃日志工具分析代码定位

    当App接入了友盟SDK进行数据监控后,后台会实时反馈当前App的情况.如果发现线上奔溃信息也会记录在案,并展现奔...

  • android 崩溃日志收集以及上传服务器

    前言 一般情况下app开发完成最后一道工序就是日志收集、奔溃信息查找,我们需要根据打印的错误日志来定位,分析,解决...

  • iOS Crash 文件分析,符号化

    在真机运行、苹果审核等过程中,App 可能出现奔溃。拿到的奔溃日志是如下图所示 这样是看不出问题出自哪里的。 解决...

  • iOS-千奇百怪的奔溃

    App 上线后,我们最怕的应该就是异常奔溃了。常见的奔溃类型分两种:信号可捕获奔溃、信号不可捕获奔溃,前者比较典型...

网友评论

    本文标题:关于App日志与奔溃信息的简单记录与上传

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