Java小白学习如何打日志

一、JAVA打日志的基础
以前自己自学的时候 , 排查问题只会写下面的代码:
try { // doSomething} catch (Exception e) { e.printStackTrace();}----------// 查看某个数据的值时:System.out.println(xxxx);去到公司就发现上面的代码全不见了 , 剩下的是:
LOGGER.info("begin to run Java3y:{}", id);----LOGGER.error("excepiton occurs when run Java3y {}, exception{}", id, e.toString());如果使用e.printStackTrace();的话 , 打印在控制的信息分析不方便:

Java小白学习如何打日志

文章插图
 
而我们将信息分等级和时间记录在服务器的磁盘上 , 有问题了就可以根据对应的信息去查找相关的日志(这样排查起来是十分方便的):
Java小白学习如何打日志

文章插图
 
我们再来看一下一般的日志长什么样的:
Java小白学习如何打日志

文章插图
 
例如:现在有人来反馈某某某用户好像收不到短信 , 给出发送时间和用户ID , 我们就可以在日志上找出该用户在我们系统的发送状态(例如图上的:state:81 , 我们就认为是发送成功状态)
那么 , 问题来了 , 我们在哪打日志?《手册》上其实已经给出了答案:
谨慎地记录日志 。生产环境禁止输出 debug 日志;有选择地输出 info 日志;如果使
用 warn 来记录刚上线时的业务行为信息 , 一定要注意日志输出量的问题 , 避免把服务器磁盘
撑爆 , 并记得及时删除这些观察日志 。
大量地输出无效日志 , 不利于系统性能提升 , 也不利于快速定位错误点 。记录日志时请思考:这些
日志真的有人看吗?看到这条日志你能做什么?能不能给问题排查带来好处?
1.1什么叫做 打点 ?
打日志最常见的就是用来打印出程序执行时的相关信息 , 用于快速定位问题和排查问题 。我一开始也是这么理解的 , 但是其实还可以延伸一下 。
我现在搞的那个系统 , 我们还使用日志在系统的执行链路上打点 。比如说 , 我现在要推送一条通知消息 , 通知消息其实就是下面这种:
Java小白学习如何打日志

文章插图
 
这个过程大概是如此的:
  • 首先别人调用我的RPC提供的接口(或者我自己调用自己的接口) , 发现这是一个通知消息 。于是我组装成对应的Task , 异步放到消息队列中
  • 另一个系统从消息队列中取出Task , 对这个Task进行业务的处理(比如说是否夜间屏蔽 , 是否强制发送等等) , 然后调用HTTP接口把这个Task交给下游
  • 下游做的事其实也很多 , 整块链路很长(比如要调用SDK的库 , Android和IOS又做不同的处理)

Java小白学习如何打日志

文章插图
 
而我们又希望在推送完了之后能统计出一些指标(曝光量 , 点击率 , 转化率)等等 。于是乎 , 就需要在一些关键的位置上打一个日志(专业点叫做打点)
在整块链路都打通了以后 , 将这些点位(日志)收集起来 , 放到实时流式处理平台(storm/flink)上清洗/过滤 。如果是实时需要用到的放到redis , 离线的放在Hive 。
二、手册规范
2.1 使用门面模式的日志框架
【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API , 而应依赖使用日志框架
SLF4J 中的 API , 使用门面模式的日志框架 , 有利于维护和各个类的日志处理方式统一 。
门面模式我之前也写过一篇笔记:三分钟学会门面模式!
其实说白了就是希望抽象出一层API , 能够在切换具体日志框架的时候不需要大面积更改 。
这个我们可以按学JDBC的时候去理解:
无论我是接入MySQL、Oracle还是SQL Server , 但我的接口永远都是那一套 , 切换数据库时不需要更改我的Java API
看了一下公司的项目 , 采用的是SLF4J+Logback
2.2 调用RPC接口使用Throwable类拦截
【强制】在调用 RPC、二方包、或动态生成类的相关方法时 , 捕捉异常必须使用 Throwable


推荐阅读