合理设置及使用系统日志

合理使用系统日志

日志常用级别

软件中总免不了要使用日志,一般都提供了以下几个日志级别:

  • Verbose
  • Debug
  • Info
  • Warning
  • Error
  • Fatal

一个比一个等级高,谈谈自己的一些看法,以便交流使用。

Verbose

一般用于开发阶段调试功能的时候可以设置和打开Verbose级别的日志,可以看到更详细的参数处理,甚至详细的原始数据;
开发调试过程中一些详细信息,不应该编译进产品中,只在开发阶段debug版本使用,release版本屏蔽。
Verbose等级的Log,请不要在user版本中出现,可以使用if分支来控制;如 if (isEng) { LOGV(); }

Debug

一般来说,用于调试的信息,编译进产品,但可以在运行时临时打开或关闭。
这个级别的信息,可以用于开发阶段系统调试,便于解决分析问题,可以记录比如关键变量的值,数据处理或函数调用的结果等。
比Verbose级别稍高,一般用于追踪确认详细的函数调用关系或者处理结果。
Debug等级的log,默认不开启,开发调试时或分析定位问题时可以打开。

Info

一般用来记录系统运行中的关键运行信息,可以针对运维人员。
可以用来作为系统运行日志来存储,并可以作为以后调查取证、日志审计、责任划分等的依据。
记录关键、必要信息,运行时一般打开。

Warning

Warning用来记录系统运行中出现的非预期情况,或者不符合正常业务逻辑,但不影响系统运行、且可以恢复到正常业务状态的提示信息。

Error

Error用来记录系统运行中出现了无法继续完成相关业务的关键信息;如用户方面输入不合法、操作错误,系统缺少必要的运行条件如权限、资源限制等。

Fatal

Fatal用来记录致命错误,如服务不可用,系统异常,无法正常开展业务,系统服务终止等。

使用日志注意事项

  1. 不要直接使用printf或者cout,或System.out/System.err直接输出到终端,请使用封装的日志记录(如syslog)接口记录到文件或远程服务器;
  2. debug/info级别的log,如果信息本身需要再次调用其他接口(如getxxx())进行实时计算的,需要加if分支,否则即使日志不输出也会触发调用getxxx()消耗系统资源;
  3. 注意error和Warning级别的区别,导致业务不正常服务的,用error级别;预期会发生的异常,并且已经有了应对的处理流程,使用Warning级别;
  4. 在系统里调用外部的地方,记录请求的接口、参数、返回结果、花费时间(如有必要,用于定位性能问题)、处理异常等;
  5. 在系统里出现异常的地方,记录异常的堆栈,如果可以,尽量通过异常的日志能还原当时的情景;
  6. 有些代码在编写时就知道几乎不会执行到或者不希望被执行到、以及一些基本不会走到的else块,这些地方需要记录下核心日志;
  7. 日志配置Rolling,可以根据实际情况配置按天、按小时进行轮转,生成新的日志文件;
  8. 重要方法入口,关键业务流程前后及处理的结果等,推荐记录log;
  9. Log的内容一定要确保不会因为Log语句的问题而抛出异常造成中断;
  10. 日志信息中尽量包含数据和描述:easy to read, easy to parse;如果难以把信息字符串化或字符串化代价太高,可以考虑只输出原始值,但是要有可以根据信息的原始值查询对应解析字符串的辅助表格。
  11. 避免不分日志重要性,添加过多不必要的日志,影响系统性能;避免在循环中添加日志,必要时尽量想办法降低输出频率,如记录变量值,只有在变量值变化才会输出,或者为了监控消息是否正常也要做适当的过滤,比如增加计数,当相同的日志出现100次才会输出一次。
  12. 日志有系统时间、PID信息、TAG标记;要记录收发的关键消息、关键逻辑处理、关键异常等;
  13. 日志中不要直接显示函数名及用户隐私类信息如用户密码,电话号码等,确有必要的需要加上部分mask,只显示其末尾几个字符;

        总之,日志设置和添加的原则是简而明,便于跟踪和分析问题,不影响系统性能。

什么时候应该输出日志

  • 当你遇到问题的时候,只能通过debug功能来确定问题,你应该考虑打日志,良好的系统,是可以通过日志进行问题定位的。
  • 调试过程中,当你碰到if…else 或者 switch这样的分支时,要在分支的首行输出日志,用来确定进入了哪个分支;调试使用的Verbose级别超详细日志不应直接出现在产品代码,可以考虑使用 if (DEBUG) { LOGV("verbose debug log"); }
  • 经常以功能为核心进行开发,在提交代码前,应可以确定通过日志能看到整个流程;
  • 对于debug日志,必须判断是否为debug级别后,才进行使用:if (isDebugEnabled()) { log output; };
  • 对于关键业务,或有日志审计需求的,使用Info以上级别记录关键信息,能完整体现业务流程或用户操作流程与响应结果。

Info、Warning、Error等级的Log禁止作为普通的调试信息使用,这些等级的Log是系统出现问题时候的重要分析线索,如果随意使用,将给Log分析人员带来极大困扰。
Android Log的tag命名,使用Activity名称或者类、模块的名称,不要出现自己的姓名拼音或其他简称。在c++/c代码中调用ALOGD等宏函数,参数没有传入tag,需要在文件头部#define LOG_TAG "YOUR_TAG_NAME"
Log的内容,不要出现公司名称、个人名称或相关简称,Log内容不要出现无意义的内容,如连续的等号或星号或连续的数字等,Log内容要方便其他分析Log的人员查看。
Log输出的频率需要控制,例如1s输出一次的周期性重复Log,尽量只在eng版本使用,user版本如需开启,请默认关闭,或使用计数器每到达一定计数才输出一次,并把中间经过的次数输出。

不同级别的log使用举例

error

影响到业务正常运行、当前请求正常运行的异常情况:

  • 打开配置文件失败
  • 所有第三方对接的异常(包括第三方返回错误码)
  • 所有影响功能使用的异常

warning

不应该出现但是不影响程序、当前请求正常运行的异常情况:

  • 有容错机制的时候出现的错误情况
  • 找不到配置文件,但是系统能自动创建配置文件
  • 即将接近临界值的时候,例如:缓存池占用达到警告线
  • 业务异常的记录,比如:当接口抛出业务异常时,应该记录此异常

info

系统运行信息:

  • Service方法中对于系统/业务状态的变更
  • 主要逻辑中的分步骤
  • 外部接口部分调用情况
  • 客户端请求参数(REST/WS)
  • 调用第三方时的调用参数和调用结果

说明
并不是所有的service都进行出入口打点记录,单一、简单service是没有意义的(job除外,job需要记录开始和结束)。
对于复杂的业务逻辑,需要进行日志打点,以及埋点记录,比如用户下订单逻辑,以及OrderAction操作(业务状态变更)。
对于向外部提供的接口,使用info记录入参。
如果所有SOA架构的service,可以看成是一个外部接口提供方,必须记录入参。
调用其他第三方服务时,所有的出参和入参是必须要记录的(因为你很难追溯第三方模块发生的问题)。

debug

  • 可以填写所有的想知道的相关信息(但不代表可以随便写,debug信息要有意义,最好有相关参数)。
  • 生产环境需要关闭DEBUG信息。
  • 如果在生产情况下需要开启DEBUG,需要使用开关进行管理,不能一直开启。

verbose

对于特别详细的系统运行信息,业务代码中不要使用(除非有特殊用意)。
只在个人开发时单独调试使用,自验ok后应该加独立开关控制或移除相关代码,不应在系统运行时输出。


参考资料:
https://blog.csdn.net/chen213wb/article/details/78507371
https://blog.csdn.net/qq_31332467/article/details/77198158
https://www.jianshu.com/p/8551fe9c6354
https://blog.csdn.net/weixin_38303684/article/details/78912274
http://m.sohu.com/a/334470645_100212268

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值