1.背景
为在线教育部提供高效、安全、易用的日志组件。
2.功能介绍
2.1 日志格式化
目前输出的日志格式如下:
日志级别/[YYYY-MM-DD HH:MM:SS MS] TinyLog-Tag: |线程| 代码文件名:行数|函数名|日志输出内容
-
触发flush到文件的时机:
- 每15分钟定时触发;
- mmap buffer满时触发。
-
日志清理时机:
组件init时,会自动清理过期日志,目前默认保留7天日志。
2.2 支持压缩加密
日志组件可通过接口设置是否压缩以及加密。
- 压缩模式为:zlib默认压缩模式;
- 加密模式为:RSA+AES流式加密。
2.3 支持日志上传和打包
调用日志上传和打包接口时,日志组件会根据传入参数时间将所需文件按照统一格式进行压缩打包。
2.4 支持FancyLog
在相应场景调用FancyLog接口,日志上传到后台后,可查看根据调用顺序绘制出来的流程图。
2.5 支持日志脱敏
可支持以下数据的脱敏:
- 大陆手机号
- 18位身份证号
- 邮箱号
- 自定义替换关键词:正则表达式、$(###)和${###}
$(###) 和${###} 区别是,前者为非贪婪匹配,后者为贪婪匹配,示例如下:
SensitiveConvertor *convertor = [[SensitiveConvertor alloc] initReplacerWithPattern:@"我不是$(###),"];
NSString *convertString = [convertor replace:@"我不是潘金莲,我是李雪莲,"];
//output: 我不是******,我是李雪莲,
SensitiveConvertor *convertor = [[SensitiveConvertor alloc] initReplacerWithPattern:@"我不是${###},"];
NSString *convertString = [convertor replace:@"我不是潘金莲,我是李雪莲,接下来"];
//output: 我不是******,接下来
3.使用说明
3.1 日志接口
组件内已经预定义好了一些宏,可以直接使用:
- 接口列表
#pragma mark -- TinyLog
#define TinyLogVerbose(TAG, fmt, ...)
#define TinyLogInfo(TAG, fmt, ...)
#define TinyLogDebug(TAG, fmt, ...)
#define TinyLogWarning(TAG, fmt, ...)
#define TinyLogError(TAG, fmt, ...)
#pragma mark -- TLog
#define TLogVerbose(fmt, ...)
#define TLogInfo(fmt, ...)
#define TLogDebug(fmt, ...)
#define TLogWarning(fmt, ...)
#define TLogError(fmt, ...)
- 使用示例:
TinyLogInfo(@"ABCmouse", @"This is a test msg (%@) With A TAG.", @"test111");
TLogInfo(@"This is a test msg (%@) without A TAG.", @"test222");
3.2 参数设置接口
- 接口列表
#pragma mark 参数设置接口
// 是否打开控制台,类型为bool。默认关闭
- (void)enableLogConsole:(BOOL)enable;
// 是否压缩,类型为bool。默认压缩
- (void)enableLogCompress:(BOOL)enable;
// 是否加密,类型为bool。默认加密
- (void)enableLogEncrypt:(BOOL)enable;
// 单个日志文件大小限制,类型为int。单位为MB。默认为-1,不限制
- (void)setLogSingleSizeLimit:(int)logSingleSizeLimit;
// 设置日志级别
- (void)setLogLevel:(TLogPriority)logPriority;
- 使用示例:
[[TinyLog shareInstance] enableLogConsole:YES];
// 其他接口调用方式类似,根据接口说明传入参数调用即可。
3.3 初始化接口
#pragma mark 初始化接口
// TinyLog初始化接口
- (void)setAppkey:(NSString *)appkey;
// 设置用户ID
- (void)setIdentifyID:(NSString *)identifyID;
// !!!必须设置,不然无法上传日志
- (void)setTinyChannel:(id<ITinyChannel>)tinyChannel;
3.4 日志上传及打包接口
#pragma mark 日志上传接口
//上报区间内的
- (void)uploadFileBegin:(long long)beginTime end:(long long)endTime;
// 上报 指定某一天的
- (void)uploadFileDate:(NSDate *)date;
// 上报 前 hours 小时的
- (void)uploadFileHous:(NSInteger)hours;
#pragma mark 日志打包接口
//上报区间内的
- (NSString *)getFileBegin:(long long)beginTime end:(long long)endTime;
// 上报 指定某一天的
- (NSString *)getFileDate:(NSDate *)date;
// 上报 前 hours 小时的
- (NSString *)getFileHous:(NSInteger)hours;
3.5 记录crash日志接口
#pragma mark 记录crash日志接口
- (void)setCrashLogWithID:(int)crashID crashContent:(NSString *)crashContent;
3.6 tinylog内部错误打印接口
#pragma mark tinylog内部错误打印接口
+ (void)setLogExceptionReporter:(id <LogExceptionReporterDelegate>)exceptionReporter;
+ (id <LogExceptionReporterDelegate>)getLogger;
调用示例:
@interface YourClass ()<LogExceptionReporterDelegate>
// ...
@end
@implementation YourClass
- (void)YourMethod {
// ...
[TinyLog setLogExceptionReporter:self];
// ...
}
- (void)exceptionReporter:(int)errCode ErrMsg:(NSString *)errMsg {
NSLog(@"%d(%@)", errCode, errMsg);// TODO
}
- (void)onCrashNotify:(int)crashID {
NSLog(@"onCrashNotify(%d)", crashID);
}
3.6 FancyLog接口
- 接口列表
/*场景相关*/
+ (void)loadScene:(NSString *)sceneName;
+ (void)loadSceneSuccess:(NSString *)sceneName;
+ (void)loadSceneFailed:(NSString *)sceneName;
/*操作相关*/
+ (void)swithBack:(NSString *)msg;
+ (void)switchFront:(NSString *)msg;
+ (void)click:(NSString *)msg;
/*出现异常*/
+ (void)exception:(NSException *)exception Msg:(NSString *)msg;
+ (void)crash:(NSException *)exception Msg:(NSString *)msg;
/*过程*/
+ (void)processStart:(NSString *)msg;
+ (void)processing:(NSString *)msg;
+ (void)processEnd:(NSString *)msg;
/*自定义事件*/
+ (void)event:(NSString *)event;
- 调用示例
// ...
// 根据实际场景调用接口
[FancyLog loadScene:@"This is A Test Secene"];
// ...
3.7 日志脱敏接口
- 接口列表
#pragma mark -- 转换接口
/// 日志脱敏配置接口1
/// @param converPhone 是否需要对手机号进行脱敏,YES:需要,NO:不需要
/// @param convertIDCard 是否需要对身份证号进行脱敏,YES:需要,NO:不需要
/// @param convertEmail 是否需要对邮箱号进行脱敏,YES:需要,NO:不需要
/// @param customPattern 自定义关键字,支持正则、$(###)、${###}
- (id)initWithConvertPhone:(BOOL)converPhone ConvertIDCard:(BOOL)convertIDCard ConvertEmail:(BOOL)convertEmail CustomPattern:(NSString *)customPattern;
/// 转换接口
/// @param originString 待脱敏的字符串
/// @return 脱敏后的字符串
- (NSString *)convert:(NSString *)originString;
#pragma mark -- 替换接口
/// 日志脱敏配置接口2
/// @param pattern 自定义关键字,支持正则、$(###)、${###}
- (id)initReplacerWithPattern:(NSString *)pattern;
/// 替换接口
/// @param originString 待脱敏的字符串
/// @return 脱敏后的字符串
- (NSString *)replace:(NSString *)originString;
- 调用示例
SensitiveConvertor *convertor1 = [[SensitiveConvertor alloc] initWithConvertPhone:YES ConvertIDCard:YES ConvertEmail:YES CustomPattern:@"我不是${###},"];
NSString *convertString1 = [convertor1 convert:@"我的手机号是18011112222,身份证号是110101199001011234,邮箱号是tinylog@qq.com,我不是潘金莲,我是李雪莲,接下来"];
SensitiveConvertor *convertor2 = [[SensitiveConvertor alloc] initReplacerWithPattern:@"我不是$(###),"];
NSString *convertString2 = [convertor2 replace:@"我不是潘金莲,我是李雪莲,"];
4.其他
4.1 日志文件解密
-
在线解密
调用上传接口后,日志会上传到http://tiny.edu.woa.com/log- 点击下载按钮,可下载解密解压后的日志文件
- 点击在线查看按钮,可在线查看解密解压后的日志内容
-
本地解密
调用打包接口后,根据返回的文件路径,使用本地解密工具解密,具体使用方法可参考Tinylog本地解密工具
4.2 Crash场景处理
如果希望能将Crash堆栈也写进日志文件里,可在崩溃监听回调函数中调用TinyLog的写日志接口,以RQD的崩溃监听回调函数为例:
int app_crash_handler_callback() {
// ...
// 获取sdk生成的crash.log
NSString *crashLog = [[CrashReporter sharedInstance] getCrashLog];
TLogError(@"crash log:%@", crashLog);
// 或者调用 [[TinyLog shareInstance] setCrashLogWithID:_crashID crashContent:crashLog];
return 0;
}
// ...
[[CrashReporter sharedInstance] setUserCrashHandlerCallback:app_crash_handler_callback];