程序运行日志模块设计规则
一、结论
理论目标上,一个完美的程序不需要Log。
但人的认知总是有限的,尤其是对于一个大型的多人协作开发的程序,总是难以避免开发错误。
目前,全自动化 每个函数打印一个有效日志 的处理很难实现,只能实现半自动化日志处理。
在发布版的时候把某些日志代码提取出来并保存到某个文件中,或者注释。
(复制出来保存在日志中会好像,方便查找生产后的因日志模块导致的工程打包问题)
对于一个大型且多人协作开发的程序,日志模块非常重要。可以极大的降低开发周期。
性能不是问题,实在不行,在发布版可以把日志代码注释掉。
二、解决的目标问题举例
bug1,异步加载文件,有概率加载失败,
以日志的方式解决,在加载文件是加关键日志,判断文件是否加载成功。
bug2,带广告的sdk登录异常,token验证失败
原因是,加入广告信息后,token变长,导致被服务器截断。
日志方式解决:在与其它模块通信时,要加带有数据的日志,以便快速确认是哪个模块数据处理有问题。
三、日志规则设计
日志的开关应该 优先考虑远程的设置。每个账号一个日志组合。
需求:
对于每个账号一个日志组合。需要一个设备所安装包的唯一码,(同一个设备重装时则生成新的设备包唯一码),这样可以第一时间控制程序的日志打印情况。而不用等账号的登录,而账号登录时可以关联设备的设备包的唯一码,以便定位玩家的设备唯一码。
(对于绝对的第一次运行的bug,只能根据程序代码中默认关键日志的输出来定位,直到程序连上网络之时)
这些需要程序有本地保存的文件。这样可以手动修改程序日志运行。并且日志里还需要一个强制使用本地日志规则的flag标志。该标志的key,不能在出包时直接写在日志规则文件中,而是根据需要人为的加到 日志规则文件以控制程序日志,且可以随程序代码版本而不同,以防止被恶意使用。
(要连上网才能输出机密数据,否则不要打印机密数据)
具体实现流程:
首先程序启动时去读取 日志规则文件里的 日志规则。包括 日志打印等级,是否强制使用本地日志规则,设备唯一码。
之后,若程序 日志规则文件里 没有设备唯一码时,便生成一个设备唯一码,并保存到 日志规则文件中。
然后在程序看是否有强制使用本地日志规则的标志。若没有,则带上 设备唯一码 去读取远程的日志规则,并更新到本地日志规则文件中。
最后再使用确定的日志规则去控制程序的日志打印情况。
写程序log一定要统一规范,方便后期日志统一处理。
关键流程日志的包含
1、程序开始运行
2、启动时配置文件的加载,关键文件的加载
3、账号登录阶段,和登录时和远程的交互数据,资源下载(要包含url),资源加载,
4、程序状态 转化
日志等级设计
日志当前设计 9 个等级
0000 0001 = 1 = 2^0
1000 0000 = 128 = 2^7
1111 1111 = 255 = 2^7 + 2^6 + ,,,+ 2^0
日志等级 | 程序名称 | 作用 | 备注 |
---|---|---|---|
0 | Close | 关闭日志 | |
1 | OutputToConsole | 是否输出到控制台 | |
2 | OutputToFile | 是否输出到文件 | |
4 | PersonDebug | 初衷是在查找某个 bug 的时候使用 | 需要加一个bug标签,方便从日志中过滤需要的目标日志 |
8 | LogWihtoutStrConnect | 普通的不带字符串连接的日志 | |
16 | LogWithStrConnect | 普通的带有字符串连接的日志 | 字符串连接非常耗时,慎用 |
32 | Warning | 警告 | |
64 | ProgramImportantNode | 程序关键节点日志 | |
128 | Error | 错误 |
日志打印性能测试
测试硬件环境:android平台,cpu,全新一代 晓龙8,8核 最高 3.0GHz。系统,Android 12。
结论1:android平台,一帧33毫秒,建议最多 10 000 个 稳定日志是否输出判断(即,只赋值不拼接字符串,调用函数,bool判断,不包含打印),大约 耗时 183 000 纳秒( 0.183 毫秒 )。
结论2:字符串拼接 和 打印到控制台 都很耗时,只能做多线程 并行日志打印。
(具体测试数据,https://github.com/prescalamity/CSharp_DotNet_Narwhal/tree/main/CSSharpTools)
日志输出到文件,很耗性能,但使用多线程处理规避性能问题
(本文结束,该日志模块设计,若有需要完善的后续完善)