打印时机/位置

  • 请求入口和出口(方法的开头和结尾):在函数或者对外接口的入口/出口处需要打印入口/出口日志,一来方便后续进行日志统计,同时也更加方便进行系统运行状态的监控;
  • 程序异常:在程序出现 exception 的时候,要么选择向上抛出异常,要么必须在 catch 块中打印异常堆栈信息。不过需要注意的是,最好==不要重复打印异常日志==,比如在 catch 块里既向上抛出了异常,又去打印错误日志(对外 rpc 接口函数入口处除外);
  • http 调用或者 rpc 接口调用:在程序调用其他服务或者系统的时候,需要打印接口调用参数和调用结果(成功/失败);
  • 特殊的条件分支:程序进入到一些特殊的条件分支时,比如特殊的 else 或者 switch 分支。比如说年龄小于0的情况,返回一个默认值,但是垓心系需要打印出来,因为前置的某些步骤可能产生了预期之外的数据;
  • 关键执行路径及中间状态:在一些关键的执行路径以及中间状态也需要记录下关键日志信息,比如一个算法可能分为很多步骤,每隔步骤的中间输出结果是什么,需要记录下来,以方便后续定位跟踪算法执行状态;

打印什么内容

  • 执行该方法的参数需要被打印
  • 该方法的执行结果需要被打印

日志级别

  • info:记录系统运行的关键状态、关键业务逻辑或者关键执行节点;
  • warning:用来记录系统运行时的一些非预期情况,顾名思义,是作为一种警示,提醒开发和运维人员需要关注,但是不用人为介入立刻去处理的;
  • error:用来记录系统运行时的一些普通错误,这些错误一旦出现,则表示已经影响了用户的正常访问或者使用,通常意味着需要人为介入处理;
  • fatal :属于系统致命错误,一般出现意味着系统基本等于挂掉了,需要人工立即介入处理;

注意

  • 不要打印太多的日志,这会造成无法获取有效信息的问题

    • 例如某些请求的结果,只展示必要的信息或者在之后的操作中可能用到的关键信息即可;
  • 日志应只出现在主要的功能点和一些可能出现危机的代码里;

    • 比如说请求的一级处理逻辑,里面的详细处理逻辑或者该一级逻辑是包装的二级功能模块部分只打印必要的信息或者将打印的信息级别设置为debug,方便调试即可;

其他

==对于对外 http 接口或者 rpc 接口, 最好对于每个请求都有 requestId ,以便跟踪每个请求后续所有的执行流程==