序言


相信各位开发人员,运维人员在看日志的时候都很像掐死写程序的人:这日志想表达什么?

我写这篇文章的目的是想分享一些我在这方面总结的一些经验:让其他人能看懂你输出的日志。

日志的本质目的


程序在生产运行过程中不能24小时debug。而大家都清楚,没有程序是完美无瑕的。总会有那么几个未知的bug隐藏在程序中。那么,在这两个前提下,如何能够还原故障发生的现场呢?日志就是为了解决这个问题而诞生的。通常日志分为生产日志和调试日志。两者分别用无不同的作用。生产日志通常打印INFO及以上级别的日志,用于还原故障现场。调试日志用于测试、调试、Bug追踪。

还原故障现场


小学语文学过,描述一件事的四大要素:时间、地点、人物、事件。对于程序日志,也是适用的。现在,让我们通过小学语文知识来描述一个程序异常。

  • 时间:对于这点相信大家都有共识。
  • 地点:异常发生的环境、所有输入。程序的环境通常包括:服务器、环境变量。以一个Web应用来说,其环境还包括:http请求、当前会话状态等。
  • 人物:事件触发者。进程ID、线程ID。
  • 事件:事件的内容。正常情况下,服务器状态的变化等。异常情况下对于Java程序来说,会是一个异常堆栈。而对一个C/C++程序来说,有可能是一个断言失败。

相信上面的几个关键要素,大家都是有所了解的(没有了解请google)。

结合起来就成了:某时间点,服务器doit.net上面的进程1线程1000在服务器的环境变量下、某个http请求在某个会话下发生了一个异常。

还有人看不明白当时发生了什么吗?

抓Bug


通过上述的方法,相信大家已经很清楚故障现场是什么样子了。那么,程序员同学当然是还原故障现场,让程序再重新跑一遍看,到底是什么原因导致的故障了。

当然,基于这个目标现在有很多种手段(调试技术)能够帮助我们抓bug。(友情提示:前端程序员基本可以忽略后面的内容了。)但是,对于那些不能使用调试技术的场景,我想就需要开启调试日志来帮助我们抓Bug了。那么调试日志该如何写才能够帮助我们顺利的抓到Bug呢?

我先讲讲测试。测试一般分为白盒测试和黑盒测试。但是无论黑盒还是白盒,目前主流的用例的设计方法均以分支覆盖法为主,边界值等辅助手段为辅。这是几十年软件工程总结的经验。既然前人已经总结出这么给力的方法论了,那么我们就借鉴之。什么导致程序进入不同的分支呢?——输入。以此为基本点,也就不难得出打印调试日志的关键点了。总结下来应该包括如下内容:

  1. 程序入口的输入;
  2. 每一个决定分支的变量;
  3. 异常信息;
  4. 程序的输出。

 

第一章. 简介

介绍业务背景,文档目的,阅读对象

测试文章模板功能。

 


 第二章. 业务方案

介绍业务架构、业务模块设计

。。。


第三章. 技术方案

技术架构、模块、关键技术设计

。。。


第四章. 硬件方案

硬件、网络设计

。。。