前言
鉴于项目中呈现的一些问题,不好排查,光靠服务器的日志记载不太能精确的定位问题,本地日志的记载无疑是辅助性比较强的。
封装一个日志搜集的类,完成日志信息文件保存本地,日志保存天数设置、过期日志主动删去,日志信息文件可紧缩(提供紧缩文件保存路径,可根据上传服务器方式独自装备)简略记载一下。
完成逻辑
1、日志记载保存在本地
首要明确一个问题,记载日志需求将字符串转成数据(NSData)保存在本地,NSData写入本地会对本地的文件进行覆盖,所以只有当文件不存在第一次写入的时分用这种方式,如果要将日志内容追加到日志文件里面,运用NSFleHandle来处理。
#pragma mark - 获取参数
NSMutableString* parmaStr = [NSMutableString string];
// 声明一个参数指针 va_list paramList;
// 获取参数地址,将paramList指向logStr
va_start(paramList, logStr);
id arg = logStr;
@try {
// 遍历参数列表
while (arg) {
[parmaStr appendString:arg];
// 指向下一个参数,后面是参数类似
arg = va_arg(paramList, NSString*);
}
} @catch (NSException *exception) {
[parmaStr appendString:@"【记载日志反常】"];
} @finally {
// 将参数列表指针置空
va_end(paramList);
}
#pragma mark - 写入日志
// 异步执行
dispatch_async(dispatch_queue_create("writeLog", nil), ^{
// 获取当时日期做为文件名
NSString* fileName = [self.dateFormatter stringFromDate:[NSDate date]];
NSString* filePath = [NSString stringWithFormat:@"%@%@",self.basePath,fileName];
// [时刻]-[模块]-日志内容,时刻格式自定义
NSString* timeStr = [self.timeFormatter stringFromDate:[LogManager getCurrDate]];
NSString* writeStr = [NSString stringWithFormat:@"[%@]-[%@]-%@\n",timeStr,module,parmaStr];
// 写入数据
[self writeFile:filePath stringData:writeStr];
NSLog(@"写入日志:%@",filePath);
});
/**
* 写入字符串到指定文件,默认追加内容
*
* **@param** filePath 文件路径
* **@param** stringData 待写入的字符串
*/
- (**void**)writeFile:(NSString*)filePath stringData:(NSString*)stringData{
// 待写入的数据
NSData* writeData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
NSData *ungzipData = [writeData gunzippedData];
// NSFileManager 用于处理文件
BOOL createPathOk = YES;
if (![[NSFileManager defaultManager] fileExistsAtPath:[filePath stringByDeletingLastPathComponent] isDirectory:&createPathOk]) {
// 目录不存先创立
[[NSFileManager defaultManager] createDirectoryAtPath:[filePath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];
}
if(![[NSFileManager defaultManager] fileExistsAtPath:filePath]){
// 文件不存在,直接创立文件并写入
[writeData writeToFile:filePath atomically:NO];
}else{
// NSFileHandle 用于处理文件内容
// 读取文件到上下文,并且是更新形式
NSFileHandle* fileHandler = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
// 跳到文件末尾
[fileHandler seekToEndOfFile];
// 追加数据
[fileHandler writeData:ungzipData];
// 关闭文件
[fileHandler closeFile];
}
}
2、日志记载保存时刻约束
下面方法只是删去了未紧缩前的文件,紧缩后的文件过期同样需求删去,逻辑相同,此处不再赘述。
// 获取日志目录下的一切文件
NSArray* files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath: self.basePath error: nil];
for (NSString* file in files) {
NSDate* date = [self.dateFormatter dateFromString:file];
if (date) {
NSTimeInterval oldTime = [date timeIntervalSince1970];
NSTimeInterval currTime = [[LogManager getCurrDate] timeIntervalSince1970];
NSTimeInterval second = currTime - oldTime;
int day = (int)second / (24 * 3600);
if (day >= LogMaxSaveDay) {
// 删去该文件
[[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@",self.basePath,file] error: nil];
NSLog(@"[%@]日志文件已被删去!",file);
}
}
}
3、日志文件紧缩
一般的紧缩功用采用zip紧缩即可,本文运用ZipArchive。项目地址:github.com/ZipArchive/…
此处留意一个点:被紧缩文件最好与紧缩文件同名,否则会导致生成不了紧缩文件。
主张:未紧缩文件和紧缩文件存放在不同的目录下,或许更方便办理
// 紧缩包文件路径
NSString *dateStr = [**self**.dateFormatter stringFromDate:[NSDate date]];
NSString * zipFile = [NSString stringWithFormat:@"%@%@.zip",**self**.zipBasePath, dateStr];
NSString* filePath = [**self** getLogPathWithDate:**nil**];
BOOL createPathOk = **YES**;
if (![[NSFileManager defaultManager] fileExistsAtPath:[zipFile stringByDeletingLastPathComponent] isDirectory:&createPathOk]) {
// 目录不存先创立
[[NSFileManager defaultManager] createDirectoryAtPath:[zipFile stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];
}
// 创立一个zip包
BOOL created = [SSZipArchive createZipFileAtPath:zipFile withFilesAtPaths:@[filePath]];
if ([[NSFileManager defaultManager] fileExistsAtPath:zipFile]) {
// NSLog(@"有文件");
} else {
// NSLog(@"没有文件");
}
return created;
4、写在最后
调用方式能够根据事务需求适当调整,所以在这里只放了中心代码。逻辑很简略,主要看事务想要搜集哪些日志信息。