【项目实战】关于日志,你需要了解这些
2023-09-14 09:04:55 时间
一、日志框架入门介绍
二、日志输出时间(何时输出)
2.1 系统初始化:
系统启动参数、环境变量
2.2 预期外的错误:
异常发生时,要有详尽记录,并通知相关人员介入处理,第一时间作出响应,因为这种错误已经影响系统的正常使用
2.3 可预期的异常:
这类异常应该有效记录起来,通过警告方式反馈给相关人员加以关注,避免频繁发生,最终演化为不可控的错误。
2.4 关键操作:
增删改
2.5 函数:
函数出入口,重点关注入口
2.6 核心业务操作:
核心或者逻辑复杂的代码,建议添加详细的注释,以及较详细的日志。
2.7 流程分支:
在关键代码流程分支上打印日志。
2.8 调用外部接口:
在调用外部接口的时候,需要打印请求参数、响应值相关信息。
三、日志级别
软件中总免不了要使用诸如 Log4net, Log4j, Tracer 等东东来写日志
不管用什么,这些东东大多是大同小异的,一般都提供了以下5种日志级别:
3.1 fatal:致命日志
所谓Fatal,那就是相当严重的了,可以肯定这种错误已经无法修复,并且如果系统继续运行下去的话,可以肯定必然会越来越乱。这时候采取的最好的措施不是试图将系统状态恢复到正常,而是尽可能地保留系统有效数据并停止运行。
3.2 error:错误日志
- 指比较严重的错误,对正常业务有影响,需要运维配置监控的;
- 该级别的错误也需要马上被处理,但是紧急程度要低于fatal级别。
- error应该尽量详细记录。
- 可以进行一些修复性的工作,但无法确定系统会正常的工作下去,系统在以后的某个阶段,很可能会因为当前的这个问题,导致一个无法修复的错误(例如宕机),但也可能一直工作到停止也不出现严重问题。
3.3 warn:警告日志
- 一般的错误,对业务影响不大,但是需要开发关注;
- 该级别日志表示系统可能出现问题,也可能没有。
- 可以使用 warn 日志级别来记录用户输入参数错误的情况
- 此时可进行一些修复性工作,应该还可以把系统恢复到正常状态中来,系统应该可以继续运行下去。
3.4 info:信息日志
- 记录排查问题的关键信息,如调用时间、出参入参等等;
- 该级别日志记录系统的正常运行状态,通过查看info级别的日志,可以很快地对系统中出现的 warn,error,fatal错误进行定位。
- 可以将初始化系统配置、业务状态变化信息,或者用户业务流程中的核心处理记录到info日志中,方便日常运维工作以及错误回溯时上下文场景复现。
- 这个应该用来反馈系统的当前状态给最终用户的,所以,在这里输出的信息,应该对最终用户具有实际意义,也就是最终用户要能够看得明白是什么意思才行。从某种角度上说,Info 输出的信息可以看作是软件产品的一部分(就像那些交互界面上的文字一样),所以需要谨慎对待,不可随便。
3.5 debug:调试日志
- 用于开发DEBUG的,关键逻辑里面的运行时数据;
- 该级别日志的主要作用是对系统每一步的运行状态进行精确的记录。
- 可以将各类详细信息记录到DEBUG里,起到调试的作用,包括参数信息、调试细节信息、返回值信息等
- 级别最低,一般的来说,在系统实际运行过程中,一般都是不输出的。
- 因此这个级别的信息,可以随意的使用,任何觉得有利于在调试时更详细的了解系统运行状态的东东,比如变量的值等等,都输出来看看也无妨。当然,在每一个 Debug 调用之前,一定要加上 If 判断。
四、日志内容
4.1 推荐使用英文内容
推荐输出英文日志内容,作用如下:
- 避免出现日志乱码;
- 使用ELK查询日志更方便
4.2 参数占位,唯一标识在前
- 禁止使用+操作符进行字符串的拼接,因为有一定的性能损耗,建议使用{}占位符;
- 建议将唯一标识放在日志内容前,如:userId、VIN、SN、deviceId等唯一标识,有利于快速定位log
4.3 异常打印
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [${project.name}-${app.name}]
[%thread]%-5level %logger - %msg%n
</pattern>
</encoder>
</appender>
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger =LoggerFactory.getLogger(Person.class);
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Person {}
log.info("{}:Processing trade with , symbol : {} ", id, symbol);
log.info("{}:loginOrLogoutLogList param={}", userId, param);
4.4 禁止做这些
4.4.1 禁止使用e.printStackTrace();
try {
// 业务代码处理
} catch (Exception e) {
e.printStackTrace(); //不要使用e.printStackTrace();
}
4.4.2 异常日志不要只打印一半;
try {
//业务代码处理
} catch (Exception e) {
// 错误
LOG.error('你的程序有异常啦', e.getMessage()); //异常日志不要只打印一半;
}
4.4.3 不要只是一句错误提示;
try {
//业务代码处理
} catch (Exception e) {
// 错误
LOG.error('你的程序有异常啦'); //不要只是一句错误提示;
}
try {
// 业务代码处理
} catch (Exception e) {
log.error("Person study errer,param={},e={}", param, e);
}
4.4.4 不要既打印日志,又抛出异常
try {
//业务代码处理
} catch (Exception e) {
// 错误
LOG.error('你的程序有异常啦'); //不要只是一句错误提示;
throw .new Exception("异常信息");
}
4.4.5 重复日志
避免重复打印日志,会浪费磁盘空间。
如有一行日志清楚表达了意思,避免再冗余打印;
if (user.isVip()) {
log.info("该用户是会员,Id:{}", user, getUserId());
//冗余,可以跟前面的日志合并一起
log.info("开始处理会员逻辑,id:{}", user, getUserId());
//会员逻辑
} else {
//非会员逻辑
}
4.6 禁止输出的信息
- 禁止在日志中输出一些敏感信息,
例如用户密码,身份证、手机号、银行卡、姓名、住址、邮箱等
如需要可以考虑掩码脱敏,以及要保持编码的一致 - 禁止使用System.out.println(“xxxxxxx”)语句;
- 禁止使用e.printStackTrace();
- 禁止无意义打印,如连续的等号、星号或数字:***、=======、-------等
- 禁止循环打印Log
- 避免打印过长的日志内容:如列表、大json、大对象、数据库内容、天气详细信息、新闻列表等
五、日志格式
日志应当包括基本的信息:如
- 当前时间戳(一般毫秒精确度)
- 日志级别
- 线程名字
六、日志脱敏方案
日志里的敏感信息还在打明文?3 种日志脱敏方案任你选
https://blog.csdn.net/JiuQianWan/article/details/127020281
相关文章
- 自然语言交流系统 phxnet团队 创新实训 项目博客 (四)
- 学习Coding-iOS开源项目日志(一)
- 权限管理系统之项目框架搭建并集成日志、mybatis和分页
- 新闻发布项目——后台JSP界面adminManage/newsPage.jsp
- jenkins自动打包部署项目
- Kafka项目实战-用户日志上报实时统计之编码实践
- Log4j日志在java项目中的使用(附工程源码)
- 【GO】K8s 管理系统项目15[API部分--WebShell]
- vue项目目录结构
- 使用nodejs&webpack&vue-cli脚手架工具搭建项目
- Springboot项目怎么设计业务操作日志功能?
- 【项目实战】Java8新特性 —— Lambda表达式与面向函数式编程
- Eclipse中的Web项目自己主动部署到Tomcat
- 面试经典系列七:给你一个web项目,应该如何测试
- 自研开源项目(2)打印日志高层封装应用库caterpillar_log
- 【北京大学】16 TensorFlow1.x的项目实战之图像风格融合与快速迁移
- 【项目实战】分布式定时任务框架XXL-JOB核心源码分析 - 作业监控和日志记录
- 基于OOP设计项目的基本方法