zoukankan      html  css  js  c++  java
  • iOS 日志系统 本地日志打包上传到服务器

    日志系统主要包含两个部分
    1.本地保存
    我们知道NSLog打印的日志一般都是直接输出到控制台,开发人员可以在控制台直接看到实时打印的log,既然可以在控制台输出,那么能否将日志输出到其他地方呢,比如说自己定义的text文件?答案是肯定的 ,在iOS中可以通过一些方法将文件重定向到指定输出位置:

        freopen([filePath cStringUsingEncoding:NSASCIIStringEncoding],"a+", stdout);
        freopen([filePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
    

    实现了上述方法,就可以将log重定向到指定的filePath中了,既然文件中保存到了本地,那么怎么处理,怎么加密完全看你们公司的业务需求咯

    2.日志上传
    日志上传首先需要将本地日志打包成zip格式的文件,这样可以减小上传的size,通过ZipArchive将日志文件打包好,通过afnetworking的 formData将文件上传了

        [formData appendPartWithFileURL:url name:@"zipFile" fileName:[NSString stringWithFormat:@"%@.zip",[self getCurrentTime]] mimeType:@"multipart/form-data" error:nil];
    
    

    具体部分实现代码如下:

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface LogServer : NSObject
    
    +(instancetype)shareInstance;
    
    ///开启写日志
    -(void)writeLog;
    
    ///上传日志
    -(void)uploadLog;
    
    ///清空本地日志
    -(void)clearLog;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    
    #import "LogServer.h"
    #import <ZipArchive/ZipArchive.h>
    
    #define MaxCount   30    //只保留最近的30条数据
    #define MaxSize    (1024*4)   //4M
    
    @interface LogServer (){
        NSString *filePath_;  //文件存放路径
    }
    
    @end
    
    static LogServer * instance = nil;
    
    @implementation LogServer
    
    +(instancetype)shareInstance{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [[LogServer alloc] init];
            [instance initLogServer];
        });
        return instance;
    }
    
    -(void)initLogServer{
        NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
        //初始化log路径
        filePath_ = [path stringByAppendingPathComponent:@"Log"];
        NSFileManager *manager = [NSFileManager defaultManager];
        if (![manager fileExistsAtPath:filePath_]) {
            //如果Log文件夹不存在,就创建文件夹
            [manager createDirectoryAtPath:filePath_ withIntermediateDirectories:YES attributes:nil error:nil];
        }
    }
    
    -(void)writeLog{
        // Do any additional setup after loading the view.
        //如果文件有zip格式则直接移除掉 可能是上次打包上传的
        [self removeZipFile];
        
        //如果文件夹中的文件超过最大限制 咋移除旧数据
        [self removeExpireFile];
        
        //加密文件
        [self encryptLastFile];
    
        //将日志写入到文件中
        NSString *filePath = [filePath_ stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.text",[self fileNameAtTime]]];
        freopen([filePath cStringUsingEncoding:NSASCIIStringEncoding],"a+", stdout);
        freopen([filePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
        
        NSLog(@"filePath:%@",filePath);
        //异常日志报告
        NSSetUncaughtExceptionHandler(&caughtExceptionHandler);
    }
    
    -(void)uploadLog{
        //将需要上传的文件加密zip格式上传到服务器
        NSArray *sortArray = [self sortFileAscending];
        if (sortArray.count > 0) {
            ZipArchive *zip = [[ZipArchive alloc] init];
            NSString *path = [filePath_ stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.zip",[self fileNameAtTime]]];
            BOOL ret = [zip CreateZipFile2:path];
            if (ret) {
                //便利所有文件内容
                for (int i = sortArray.count - 1; i>=0; i--) {
                    NSString *fileName = sortArray[i];
                    NSString *filePath = [filePath_ stringByAppendingPathComponent:fileName];
                    [zip addFileToZip:filePath newname:fileName];
                    //判断zip文件大小 如果文件大小大于最大限制 则停止剩余文件的压缩
                    long long zipSize = [self getFileSize:path];
                    if (zipSize > MaxSize) {
                        break;
                    }
                }
                [zip CloseZipFile2];
                //将zip文件上传到服务器
        
    //            afnetworking  文件上传到指定服务器即可
            }
        }
    }
    
    -(void)clearLog{
        NSFileManager *manager = [NSFileManager defaultManager];
        if ([manager fileExistsAtPath:filePath_]) {
            NSError *error = nil;
            [manager removeItemAtPath:filePath_ error:&error];
            if (error) {
                NSLog(@"日志清空失败:%@",error);
            }else{
                NSLog(@"日志清空成功");
            }
        }
    }
    
    #pragma mark - private
    #pragma mark 异常处理日志
    void caughtExceptionHandler(NSException *exception){
        /**
         *  获取异常崩溃信息
         */
        NSArray *callStack = [exception callStackSymbols];
        NSString *reason = [exception reason];
        NSString *name = [exception name];
        NSString *content = [NSString stringWithFormat:@"========异常错误报告========
    name:%@
    reason:
    %@
    callStackSymbols:
    %@",name,reason,[callStack componentsJoinedByString:@"
    "]];
        NSLog(@"%@",content);
    }
    
    #pragma mark 获取文件大小
    -(long long)getFileSize:(NSString *)path{
        unsigned long long fileLength = 0;
        NSNumber *fileSize;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if([fileManager fileExistsAtPath:path]){
            NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:path error:nil];
            
            if ((fileSize = [fileAttributes objectForKey:NSFileSize])) {
                fileLength = [fileSize unsignedLongLongValue]; //单位是 B
            }
            return fileLength / 1024;
        }
        return 0;
    }
    
    #pragma mark 用时间创建文件名
    -(NSString *)fileNameAtTime{
        NSDate *date = [NSDate date];
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"yyyy-MM-dd-HH-mm-ss";
        NSString *timeStr = [formatter stringFromDate:date];
        
        return timeStr;
    }
    
    #pragma mark 加密文件内容
    -(void)encryptLastFile{
        //这里根据自己的需要将文件内容进行加密
        NSFileManager *manager = [NSFileManager defaultManager];
        NSArray *sortArray = [self sortFileAscending];
        if (sortArray.count > 0) {
            NSString *lastPath = sortArray.lastObject;
            NSString *lastFilePath = [filePath_ stringByAppendingPathComponent:lastPath];
            NSData *data = [manager contentsAtPath:lastFilePath];
            NSString *base64String = [data base64EncodedStringWithOptions:0];
            //
            [base64String writeToFile:lastFilePath atomically:YES];
        }
    }
    
    #pragma mark 移除过期数据
    -(void)removeExpireFile{
        NSFileManager *manager = [NSFileManager defaultManager];
        //将文件中数据排序
        NSArray *sortFileArray = [self sortFileAscending];
        if(sortFileArray.count > MaxCount){
            NSInteger count = sortFileArray.count - MaxCount;
            //因为是升序排在前面的都是比较老的数据 移除前面的count个数据即可
            for (int i = 0; i < count; i++) {
                NSString *path = sortFileArray[i];
                NSString *filePath = [filePath_ stringByAppendingPathComponent:path];
                [manager removeItemAtPath:filePath error:nil];
            }
        }
    }
    
    #pragma mark 移除zip格式文件
    -(void)removeZipFile{
        NSFileManager *manager = [NSFileManager defaultManager];
        if ([manager fileExistsAtPath:filePath_]) {  //如果文件夹存在
            NSArray *filesArray = [manager contentsOfDirectoryAtPath:filePath_ error:nil];
            NSString *filePath = filePath_;
            [filesArray enumerateObjectsUsingBlock:^(NSString *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                if (![obj containsString:@".text"]) {
                    NSString *nPath = [filePath stringByAppendingPathComponent:obj];
                    [manager removeItemAtPath:nPath error:nil];
                }
            }];
        }
    }
    
    #pragma mark 将文件夹中的文件按照创建时间进行排序
    -(NSArray *)sortFileAscending{
        //拿到文件
        NSFileManager *manager = [NSFileManager defaultManager];
        if ([manager fileExistsAtPath:filePath_]) {  //如果文件夹存在
            NSArray *filesArray = [manager contentsOfDirectoryAtPath:filePath_ error:nil];
            NSString *filePath = filePath_;
            //便利文件夹中的所有文件
            NSArray *array = [filesArray sortedArrayUsingComparator:^NSComparisonResult(NSString*  _Nonnull file1, NSString *  _Nonnull file2) {
                //file1 file2全路径
                NSString *file1Path = [filePath stringByAppendingPathComponent:file1];
                NSString *file2Path = [filePath stringByAppendingPathComponent:file2];
                
                //file1 file2 Info
                NSDictionary *file1Dict = [[NSFileManager defaultManager] attributesOfItemAtPath:file1Path error:nil];
                NSDictionary *file2Dict = [[NSFileManager defaultManager] attributesOfItemAtPath:file2Path error:nil];
                
                //file1CreatTime file2CreatTime
                NSDate *file1Date = [file1Dict objectForKey:NSFileCreationDate];
                NSDate *file2Date = [file2Dict objectForKey:NSFileCreationDate];
                //升序
                return [file1Date compare:file2Date];
            }];
            return  array;
        }
        return nil;
    }
    
    
    @end
    
    
  • 相关阅读:
    个人笔记 1.3.net 3.5新特性
    个人笔记 1.2.net 2.0新特性
    面试了,web标准能简单说下吗?w3c,,错了
    SEO网络营销热门关键词排名较好的反向链接
    eWebEditor在ie8下上传失效
    个人笔记 1.4.net 3.0新特性
    个人笔记 1.5.http状态值
    MOSS项目开发(5) 会议还是会议
    MOSS项目开发 周记(第二周)
    MOSS项目开发 周记(第五周)
  • 原文地址:https://www.cnblogs.com/qqcc1388/p/11058622.html
Copyright © 2011-2022 走看看