系统初始化时会依赖一些关键配置,根据参数不同会提供不一样的服务。将系统的启动参数记录INFO日志,打印出参数以及服务启动完成状态。
4.2、业务流程与预期不符 系统中结果与期望不符,应当记录日志。常见的合适场景包括外部参数不正确,数据处理问题导致返回码不在合理范围内等等。
4.3、系统核心的关键动作 系统中核心角色触发的业务动作是需要多加关注的,是衡量系统正常运行的重要指标,建议记录INFO级别日志,比如微服务各服务节点交互等。
4.4、 捕获到异常时 这类捕获的异常是系统告知开发人员需要加以关注的,应当记录日志,根据实际情况使用warn或者error级别。
4.5、 外部接口日志 这类日志涉及到与外部系统的交互,事关责任问题,建议将原始数据文件内容写入日志或数据库(如mongodb),核心处理逻辑关键业务数据也尽量写入日志。如果涉及到重发,建议将处理失败的原始数据文件日志写入数据库,以便重发执行。
5、日志使用规约使用@SLF4J中的API进行日志打印。
日志输出必须采用UTF-8字符集,推荐打印日志时输出英文,防止中文不支持而打印出乱码的情况。
不允许记录日志后又抛出异常,因为这样会多次记录日志,只允许记录一次日志,应抛出异常,顶层打印一次日志。
try { // 错误 } catch (Exception e) { log.error("xxxxxx", e); throw e; }
输出Exceptions的全部堆栈信息,但是不能使用e.printStackTrace()
// 错误例子, 丢失掉StackTrace信息 log.error(e.getMessage()); // 错误例子,丢失掉StackTrace信息 log.error(“Bad things : {}“, e.getMessage()); // 正确例子 log.error(“Bad things : {}“,e); // e.printStackTrace()的源码 public void printStackTrace() { printStackTrace(System.err); }禁止system.out 用于日志记录。
线上必须关闭 DEBUG 级别日志。
非正常的情况,需要根据情况选择打印warn 或 error 日志,不能使用错误的日志级别。
try { // ... } catch (Exception e) { // 错误LOG.info("XX 发生异常...", e); } // 用 info 记录 error 日志,日志输出到了 info 日志文件中了,同事拼命地在 error 错误日志文件里面找怎么能找到呢?日志输出,必须使用占位符的方式,因为即使信息不打印,也会执行字符串拼接,造成资源浪费。
日志中不允许出现计算或方法调用,防止在打印日志的时候报错。
输出的POJO类必须重写toString方法,否则只输出对象的hashCode值,没有参考意义。
不记录对于排查故障毫无意义的日志信息,日志信息一定要带有业务信息。
//错误 log.error(“handle failed“); //正确 log.error(“handle failed,id= {}“, id);禁止大量无效重复的日志输出,即通常情况下在程序日志里只记录一些比较有意义的状态数据,参考日志记录时机。
不可以讲敏感业务信息记录入日志文件。
严防日志占满磁盘,定期检查磁盘(确定是否有磁盘告警)。
不要在千层循环中打印日志
for(int i=0; i<2000; i++){ LOG.info("XX"); } // 这个是什么意思,如果你的框架使用了性能不高的 Log4j 框架,那就不要在上千个 for 循环中打印日志, // 这样可能会拖垮你的应用程序,如果你的程序响应时间变慢,那要考虑是不是日志打印的过多了。 6、logback配置参考 配置说明统一使用logback.xml配置,logback.xml 文件放在 classpath 目录下。
所有的jar包中不建议包含logback.xml文件,避免干扰实际的业务系统。
通过在文件logback.xml中引入资源文件log.properties定义logback属性信息,log.properties根据不同的profile放置在不同位置;
<property resource="log.properties"/>log.properties文件
属性命名推荐使用统一使用大写,以下划线分隔,参考
APP_NAME = yourAppName LOG_DIR = /export/home/logs/yourSystem/yourAppName LOG_PATTERN = [%date{yyyy-MM-dd HH:mm:ss.SSS}] %level [%mdc{invokeNo}] %C{0}:%line - %message%n
注意Logger间的继承关系,推荐additivity设置false:
子logger会默认继承父logger的appender,将它们加入到自己的Appender中;除非加上了additivity="false",则不再继承父logger的appender。
子logger只在自己未定义输出级别的情况下,才会继承父logger的输出级别。
将日志输出到文件当中,禁止使用FileAppender,推荐使用提供自动切换功能的RollingFileAppender Log文件位置和命名,目前Log文件的位置统一放在相同目录下面。
文件名 描述/export/home/logs 默认日志路径(所有日志的根路径)
/export/home/logs/${SYSTEM_NAME}/${APP_NAME} log.properties中配置的日志全路径LOG_DIR
${LOG_DIR}/all.log 必选
${LOG_DIR}/ all-%d{yyyy-MM-dd}.log All历史文件命名
${LOG_DIR}/all_error.log 必选
${LOG_DIR}/sql.log 可选