首页 > 编程语言 >JAVA 项目中日志的正确使用姿势

JAVA 项目中日志的正确使用姿势

时间:2023-10-15 17:22:35浏览次数:57  
标签:姿势 JAVA log symbol user debug 日志 id

什么是日志

日志:记录程序的运行轨迹,方便查找关键信息,也方便快速定位解决问题。

日志的作用

1、排查和定位错误的手段
日志的作用就是在测试、生产环境没有 Debug 调试工具时开发和测试人员定位问题的手段。日志打得好,就能根据日志的轨迹快速定位并解决线上问题,反之,日志输出不好,不仅无法辅助定位问题反而可能会影响到程序的运行性能和稳定性
2、为程序提供可修复的手段
例如 Mysql binlog,可以用户我们做缓存一致性,redo log 重做日志、中继日志用户做主从备份
3、问题监控、状态监控、安全审计

常见日志框架

Logging
这是 Java 自带的日志工具类,在 JDK 1.5 开始就已经有了,在 java.util.logging 包下
commons-logging
commons-logging 是日志的门面接口,它也是Apache 最早提供的日志门面接口,用户可以根据喜好选择不同的日志实现框架,而不必改动日志定义,这就是日志门面的好处,符合面对接口抽象编程。
Slf4j
slf4j,英文全称为“Simple Logging Facade for Java”,为java提供的简单日志Facade。Facade门面,更底层一点说就是接口。它允许用户以自己的喜好,在工程中通过slf4j接入不同的日志系统。
重点:这也是我们的工程项目使用的最多的一种日志框架,他基于门面设计模式,为我们提供了一种优雅切换日志框架的手段 (参考 Spring Boot 自动装配原理)

常见的日志级别

error:错误日志,指比较严重的错误,对正常业务有影响,需要运维配置监控的;
warn:警告日志,一般的错误,对业务影响不大,但是需要开发关注(网络连接超时、系统资源预警);
info:信息日志,记录排查问题的关键信息,如调用时间、出参入参等等;
debug:用于开发 DEBUG 的,关键逻辑里面的运行时数据;
trace:最详细的信息,一般这些信息只记录到日志文件中。

logback 日志配置文件

注意事项
1、注意配置打印日志格式需要包含信息:时间、线程ID、traceId (链路追踪 ID)、spandID (链路跨度 ID)等相关信息

            <pattern>%black(控制台-) %green userId-[%X{userId}] %red(%d{yyyy-MM-dd HH:mm:ss}) %highlight(%-5level) [%X{traceId}/%X{spanId}]
                %green[%thread] %boldMagenta(%logger{10})
                [%file:%line] %cyan(%msg%n)
            </pattern>

2、需要对不同业务或者不同模块的日志进行分类处理
3、测试和开发环境需要关闭控制台日志打印

    <!-- 控制台输出日志级别 -->
    <root level="info">
        <springProfile name="dev">
            <appender-ref ref="STDOUT"/>
        </springProfile>
    </root>

4、更改日志存储方式为异步存储模式

    <appender name="ASYNC_FILING" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 设置为不丢失日志,默认如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,默认值为256 -->
        <queueSize>1000</queueSize>
        <appender-ref ref="syslog"/>
    </appender>

5、在使用日志框架时最好使用 SL4J 这种门面日志框架

日志的正确使用姿势

1、明确日志的作用:排查 BUG、分析问题;在这个的前提下我们应该避免打印无效的日志信息
错误示例

if(user.isVip()){
  
  log.info("该用户是会员,Id:{}",user,getUserId());
  
  //冗余,可以跟前面的日志合并一起
  log.info("开始处理会员逻辑,id:{}",user,getUserId());
  
  //会员逻辑
}

正确示例

if(user.isVip()){
  
  log.info("该用户是会员,Id:{}",user,getUserId());
  //会员逻辑
}

2、低日志级别的打印,需要使用开关判断例如 Debug、Trace
错误使用姿势

logger.debug("Processing trade with id:" + id + " and symbol:" + symbol);  

正确使用姿势

if (log.isDebugEnabled()){
   
    log.debug("userId is:{}", user.getId());
}

低日志级别使用时,进行开关的判断,这样可以避免无效的日志记录从而造成的额外开销
3、日志拼接使用占位符的形式
错误姿势

log.debug("Processing trade with id: " + id + " and symbol: " + symbol);  

使用这种方式会造成额外的字符串拼接产生的额外开销,如果拼接的是一个对象还需要调用他的 toString()方法
正确姿势

log.info("Processing trade with id: {} and symbol : {} ", id, symbol); 

4、静止在线上环境开启 Debug 日志 (很重要哦)
因为一般系统的 debug 日志会很多,并且各种框架中也大量使用 debug 的日志,线上开启 debug 不久可能会打满磁盘,影响业务系统的正常运行。
5、在 throw 异常之后,在他前面不需要在打印日志信息
错误姿势

log.error("IO exception", e);
throw new MyException(e);

正确姿势

throw new MyException(e);

过滤敏感日志信息

日志记录中的敏感信息:手机号、身份证号、邮箱号、真实姓名、银行卡号等
基于之定义日志组件,对日志进行脱敏操
开源项目:https://github.com/houbb/sensitive/tree/master/sensitive-test

统一日志处理

传统的日志打印方式

 private static final Logger log = LoggerFactory.getLogger(IdCardDesensitizationSerializer.class);

或者使用 lombok 为我们提供的 @SL4J 注解都存在几个问题
1、不能对日志进行统一化模板配置
2、如果后续需要对日志进行收集和处理,那么更改范围不可控

为了解决上面所说的两个问题,我们这里可以基于美团的日志处理文章 https://tech.meituan.com/2021/09/16/operational-logbook.html
1、对日志进行统一的处理基于 AOP + SL4J 的方式去对日志与业务进行解耦
2、采用这种方式也可以对日志进行统一化的处理

标签:姿势,JAVA,log,symbol,user,debug,日志,id
From: https://www.cnblogs.com/ayizzz/p/17765843.html

相关文章

  • Java基础 不可变集合详解
    如果不想让别人修改集合中的内容,只想让别人仅能够查询数据,就可以用不可变集合 在List、Set、Map接口中,都存在静态的of方法,可以获取一个不可变的集合eg:List<String>list=List.of("张三","李四");......
  • JAVA中BigDecimal详解
    一、BigDecimal比较大小二、加减乘除运算BigDecimalone=newBigDecimal("0.123");BigDecimaltwo=newBigDecimal("1.23");1、加法:add//加法运算BigDecimalthree=one.add(two);2、减法:subtract//减法运算BigDecimalfour=two.subtract(one);3、乘法:multiply//乘法运算......
  • 数据结构和算法基础(Java语言实现)pdf电子版柳伟卫2021年
    数据结构和算法基础(Java语言实现)pdf电子版下载作者: 柳伟卫出版年: 2021-11ISBN: 9787301325872下l载连接最新Java领域的算法、数据结构方面的知识书籍。越是基础越是重要!......
  • 2023_10_15_DAY_01_JAVA_SE_Java基础知识_中_变量与运算符
    2023_10_15_DAY_01_JAVA_SE_Java基础知识_中_变量与运算符标识符、关键字和保留字标识符在Java语言中,通过标识符来表示一些元素的名字,比如变量名、类名、方法名和包名等。Java中的标识符要符合下面的规则:标识符必须以字母、下划线(_)、数字或美元($)组成;标识符必须由字母、下......
  • 月薪过二万的Java面试
    (文章目录)......
  • 2023_10_15_DAY_01_JAVA_SE_Java基础知识_上
    2023_10_15_DAY_01_JAVA_SE_Java基础知识什么是Java计算机语言是人与计算机之间的通讯语言,分为机器语言、汇编语言、高级语言。Java是一种高级计算机语言,它是由Sun公司(已被Oracle公司收购)于1995年5月推出。Java语言平台Java语言平台包括3个版本,标准版、企业版、微型版。Jav......
  • htmlunit jar包运行去除日志
    情况:htmlunitjar包运势时候,出现了很多日志: 解决办法:main方法中加入:static{LoggerContextloggerContext=(LoggerContext)LoggerFactory.getILoggerFactory();List<Logger>loggerList=loggerContext.getLoggerList();loggerList.forEa......
  • 阿里云邮箱25端口被关闭,改用465端口Java发送邮件
    阿里云出于安全考虑默认关闭25端口,开发的是465端口,我们只讲怎么发送邮件。<dependency><groupId>com.sun.mail</groupId><artifactId>javax.mail</artifactId><version>1.6.2</version></dependency......
  • JavaWeb-初识Servlet
    目录1.Servlet简介2.Tomcat安装配置3.Servlet项目搭建4.Servlet项目运行内容Servlet简介Servlet是什么JavaServlet是运行在Web服务器或应用服务器上的程序,它是作为来自Web浏览器或其他HTTP客户端的请求和HTTP服务器上的数据库或应用程序之间的中间层。使......
  • poi报错org.apache.poi.POIXMLException: java.lang.reflect.InvocationTargetExcepti
    场景使用poi时报错org.apache.poi.POIXMLException:java.lang.reflect.InvocationTargetException报错信息:org.apache.poi.POIXMLException:java.lang.reflect.InvocationTargetExceptionatorg.apache.poi.xssf.usermodel.XSSFFactory.createDocumentPart(XSSFFactory......