java日志打印的完全使用指南

目录
  • 一、简介
  • 二、常用日志框架
  • 三、日志级别
  • 四、logback简单介绍
  • 五、常见问题
  • 总结

一、简介

  • 日志打印是java代码开发中不可缺少的重要一步。
  • 日志可以排查问题,可以搜集数据

二、常用日志框架

比较常用的日志框架就是logback, 一些老项目会使用log4j,他们用的都是slf4j-api统一接口。

(1) 使用log4j

log4j使用:
1. slf4j-api-1.5.11.jar
2. slf4j-log4j12-1.5.11.jar
3. log4j-1.2.15.jar
4. log4j.properties

代码中

import  org.slf4j.Logger;
import  org.slf4j.LoggerFactory;
Logger logger = LoggerFactory.getLogger(xx.class);

(2) 使用logback

logback使用:
1. slf4j-api-1.5.11.jar
2. logback-core.jar
3. logback-classic.jar
4. logback.xml

代码同log4j

import  org.slf4j.Logger;
import  org.slf4j.LoggerFactory;
Logger logger = LoggerFactory.getLogger(xx.class);

三、日志级别

TRACE < DEBUG < INFO < WARN < ERROR

日常使用较多的是error, info , debug

四、logback简单介绍

简单介绍下常用的logback,logback优点:

  • 比log4j更快
  • 和log4j使用了同一个接口,slf4j-api,可以非常方便切换
  • 定义了功能非常丰富的appender
  • 支持日志压缩

logback要正确理解xml配置文件

  • configuration:总的父节点
  • property:自定义属性
  • appender:输出控制器,可以输出到控制台,自定义文件等
  • logger:日志级别
  • root:控制器级别

一个例子:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds">

    <contextName>XXXXXXXX</contextName>
    <property name="log.path" value="./log/"/>
    <!-- 日志最大的历史 30天 -->
    <property name="maxHistory" value="30"/>

    <property name="log.pattern"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%-5level] [%logger{30}:%line] %msg%n"/>

    <!--输出到控制台-->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
        <!--LevelFilter: 级别过滤器,根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。-->
        <!--例如:将过滤器的日志级别配置为INFO,所有INFO级别的日志交给appender处理,非INFO级别的日志,被过滤掉。-->
        <!--<filter class="ch.qos.logback.classic.filter.LevelFilter">-->
        <!--<level>INFO</level>-->
        <!--<onMatch>ACCEPT</onMatch>-->
        <!--<onMismatch>DENY</onMismatch>-->
        <!--</filter>-->

        <!--ThresholdFilter: 临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。-->
        <!-- 过滤掉所有低于 DEBUG 级别的日志,留下DEBUG及以上级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 时间滚动输出 level为 INFO 日志 -->
    <appender name="errorFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--LevelFilter: 级别过滤器,根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。-->
        <!--例如:将过滤器的日志级别配置为INFO,所有INFO级别的日志交给appender处理,非INFO级别的日志,被过滤掉。-->
        <!--<filter class="ch.qos.logback.classic.filter.LevelFilter">-->
        <!--<level>INFO</level>-->
        <!--<onMatch>ACCEPT</onMatch>-->
        <!--<onMismatch>DENY</onMismatch>-->
        <!--</filter>-->

        <!--ThresholdFilter: 临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。-->
        <!-- 过滤掉所有低于 DEBUG 级别的日志,留下DEBUG及以上级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>

        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/error.log</file>

        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/error-%d{yyyyMMdd}.%i.log.zip</fileNamePattern>
            <!--日志文件保留天数-->
            <maxHistory>${maxHistory}</maxHistory>
            <!-- 日志总保存量为2GB -->
            <totalSizeCap>2GB</totalSizeCap>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!--文件达到 最大100MB时会被压缩和切割 -->
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 时间滚动输出 level为 INFO 日志 -->
    <appender name="infoFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--LevelFilter: 级别过滤器,根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。-->
        <!--例如:将过滤器的日志级别配置为INFO,所有INFO级别的日志交给appender处理,非INFO级别的日志,被过滤掉。-->
        <!--<filter class="ch.qos.logback.classic.filter.LevelFilter">-->
        <!--<level>INFO</level>-->
        <!--<onMatch>ACCEPT</onMatch>-->
        <!--<onMismatch>DENY</onMismatch>-->
        <!--</filter>-->

        <!--ThresholdFilter: 临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。-->
        <!-- 过滤掉所有低于 DEBUG 级别的日志,留下DEBUG及以上级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>

        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/info.log</file>

        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/info-%d{yyyyMMdd}.%i.log.zip</fileNamePattern>
            <!--日志文件保留天数-->
            <maxHistory>${maxHistory}</maxHistory>
            <!-- 日志总保存量为10GB -->
            <totalSizeCap>2GB</totalSizeCap>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!--文件达到 最大100MB时会被压缩和切割 -->
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 时间滚动输出 level为 INFO 日志 -->
    <appender name="debugFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--LevelFilter: 级别过滤器,根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。-->
        <!--例如:将过滤器的日志级别配置为INFO,所有INFO级别的日志交给appender处理,非INFO级别的日志,被过滤掉。-->
        <!--<filter class="ch.qos.logback.classic.filter.LevelFilter">-->
        <!--<level>INFO</level>-->
        <!--<onMatch>ACCEPT</onMatch>-->
        <!--<onMismatch>DENY</onMismatch>-->
        <!--</filter>-->

        <!--ThresholdFilter: 临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。-->
        <!-- 过滤掉所有低于 DEBUG 级别的日志,留下DEBUG及以上级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>

        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/debug.log</file>

        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/debug-%d{yyyyMMdd}.%i.log.zip</fileNamePattern>
            <!--日志文件保留天数-->
            <maxHistory>${maxHistory}</maxHistory>
            <!-- 日志总保存量为2GB -->
            <totalSizeCap>2GB</totalSizeCap>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!--文件达到 最大100MB时会被压缩和切割 -->
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <logger name="com.baomidou" level="debug"/>

    <root level="info">
        <appender-ref ref="consoleAppender"/>
        <appender-ref ref="errorFileAppender"/>
        <appender-ref ref="infoFileAppender"/>
        <appender-ref ref="debugFileAppender"/>
    </root>

</configuration>

五、常见问题

  • 1、日志打的少,不好排查问题?

我们经常会遇到一个生产问题,去看日志,啥都没有,只能重新加日志,发包,再排查问题;
所以我们要养成打日志的习惯,开发环境可以debug看,生产看不了,只能加日志,在开发的时候就把必要的日志加上;
比较重要的是接口的入参,返回,重要节点开始,结束,mq发送接收等。

  • 2、error, info , debug分别都什么时候使用?

error: 捕获异常的时候使用,这个没有异议
info: 比较重要的信息,使用频次不是非常高的场景,比如入参出参
debug: 一个是不是特别重要的信息,但是又不能少,还有数据量大的数据,比如大量mq信息,访问频繁的接口入参出参

  • 3、开启debug好多无用的debug信息怎么办?

把项目的目录定为debug,其它定成info。这样只有本项目的debug日志会打印了
logging.level.root=info
logging.level.cn.mypackage=debug

  • 4、需要自定义日志文件吗?

logback可以把日志写进自定义文件,debug,info,error分开存储,历史数据还能压缩;
按自己项目的需求来,大型项目建议分开存储。

  • 5、springboot启动命令自带的日志和自定义日志文件的日志重复怎么办?

我们一般启动springboot项目命令为:nohup java -jar XXXXXXXX.jar >> XXXXXXX.log 2>&1 &
这个会生成一个日志文件,logback配置也会生成自己的日志文件,就会重复,造成空间浪费,如何取舍?

如果你们公司统一打包脚本的话,就用命令生成的日志文件吧,把logback配置去掉;
如果你们公司自由度比较高,就用logback生成的日志,把命令改成  >/dev/null 就可以了

  • 6、debug日志正确写法?
有些人可能打debug日志直接logger.debug("****");
如果项目的日志级别比较高,就比较浪费性能,可以加一个
if (log.isDebugEnabled()) {
    log.debug("XXXXXXXXXXXXX");
}
  • 7、动态日志级别?
有些公司支持动态配置文件,比如diamond,nacos等,可以修改配置文件的级别,动态生效
logging.level.root=info
#logging.level.root=debug

日常开在info,出了问题开debug找,资源有限可以这样做,不推荐生产使用

总结

到此这篇关于java日志打印的文章就介绍到这了,更多相关java日志打印内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java工程如何打印程序日志过程解析

    很久之前,有个朋友问我,如果一个老项目让你接手去进行后续维护,你会先从哪里入手.让自己更快地上手项目?当时我没有特别正面去回答这个朋友的问题,我说:一个老项目是否容易上手,一个非常关键的地方就是这个项目的日志是否打得足够好.因为通常来说,一个老项目相对比较稳定了,后续大概率不会有比较大的变更和改动,那么对于这样的项目,核心就是"维稳".但是任何人都无法保证项目在线上运行时不会出线上故障,在出现线上问题或者故障时,如何快速止损就是第一要义,而日志在止损过程中就扮演着非常重要的角色.日志打

  • Java 日志打印的15个好建议

    目录 1. 选择恰当的日志级别 2. 日志要打印出方法的入参.出参 3. 选择合适的日志格式 4. 遇到if...else...等条件时,每个分支首行都尽量打印日志 5.日志级别比较低时,进行日志开关判断 6. 不能直接使用日志系统(Log4j.Logback)中的 API,而是使用日志框架SLF4J中的API. 7. 建议使用参数占位{},而不是用+拼接. 8. 建议使用异步的方式来输出日志. 9. 不要使用e.printStackTrace() 10. 异常日志不要只打一半,要输出全部错误信

  • java日志打印的完全使用指南

    目录 一.简介 二.常用日志框架 三.日志级别 四.logback简单介绍 五.常见问题 总结 一.简介 日志打印是java代码开发中不可缺少的重要一步. 日志可以排查问题,可以搜集数据 二.常用日志框架 比较常用的日志框架就是logback, 一些老项目会使用log4j,他们用的都是slf4j-api统一接口. (1) 使用log4j log4j使用: 1. slf4j-api-1.5.11.jar 2. slf4j-log4j12-1.5.11.jar 3. log4j-1.2.15.jar

  • java启动jar包将日志打印到文本的简单操作

    启动命令: java -jar weichi-1.0.0.jar 将命令打印到1.log上 java -jar weichi-1.0.0.jar > 1.log 补充知识:Java中日志的使用(包含指定日志信息输出到指定地方) 一.前言 对于我们开发者而言,日志存在的意义十分重大:本文主要是自己整理了关于日志的一些知识点,希望能帮助到需要的人,也希望各位能指出我的错误. 二.日志的作用 ① 记录运行信息,方便调试 ② 记录错误信息,方便排查错误 ③ 存储运行记录,方便后期的数据分析 三.日志的主

  • java注解结合aspectj AOP进行日志打印的操作

    在很多系统开发中,我们希望在指定的方法调用之前或者之后能打印出该方法的调用时间以及方法的出参和入参,就可以使用spring的AOP,还可以结合自定义的注解进行进行一些指定参数的打印 例如: 一个分层的架构系统,每层都有自己的指定系统名字,并且每个方法都有自己指定的作用(通过注解指定,在切面的时候取出该参数),而且可以根据注解的指定日志类型(在注解中指定,在切面的时候取出参数进行判断,然后打印相对应的日志格式). 1.首先需要自定义注解: systemName:表示该系统的名称. bizCode:

  • java通过AOP实现全局日志打印详解

    目录 几个常用的切点注解,这次使用了@Before和@Around 切Controller打印请求的接口.参数.返回值以及耗时情况. 切Service打印日志,URL,请求方式,IP,类名,方法 总结 几个常用的切点注解,这次使用了@Before和@Around 1.@Before 前置增强(目标方法执行之前,执行注解标注的内容) 2.@AfterReturning 后置增强(目标方法正常执行完毕后,执行) 3.@Around 环绕增强(目标方法执行前后,分别执行一些代码) 4.@AfterTh

  • Log4j 配置日志打印时区的实现方法

    og4j版本:2.8.1 开发桌面程序时遇到一个问题,idea中日志时间和CMD中jar包运行日志时间都正常,使用exe4j打成的exe运行后,日志的时间都要少8个小时,时区变得不对了 网上找了一圈发现没有类似问题的解决办法,后来终于在stack overflow 中找到相应的解决办法 在log4j2.xml配置文件中,进行如下配置即可 <!-- 输出日志格式 --> <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS}{

  • 浅谈java日志格式化

    1.日志的重要性 不管我们使用何种语言开发,一旦程序发生异常,日志是一个很重要的数据.但是并不是意味着打印的日志越多越好,我们需要的是有用的日志. 曾经参与一个很重要的项目优化,他们的日志没有进行规范,开发.运维也没有把这个事情放在心上.等到压测的时候TPS和响应时间一直上不去.通过jstack分析发现,大部分的log数据在阻塞! 今天我们不讨论具体的日志规范,我从日志中心的角度来聊下LOG的规范 2.日志采集分析 -ELK 目前主流的ELK系统应该都是通过agent端(filebeat/flu

  • 详解Java日志正确使用姿势

    前言 关于日志,在大家的印象中都是比较简单的,只须引入了相关依赖包,剩下的事情就是在项目中"尽情"的打印我们需要的信息了.但是往往越简单的东西越容易让我们忽视,从而导致一些不该有的bug发生,作为一名严谨的程序员,怎么能让这种事情发生呢?所以下面我们就来了解一下关于日志的那些正确使用姿势. 正文 日志规范 命名 首先是日志文件的命名,尽量要做到见名知意,团队里面也必须使用统一的命名规范,不然"脏乱差"的日志文件会影响大家排查问题的效率.这里推荐以"proj

  • 简单了解Java日志脱敏框架sensitive

    这篇文章主要介绍了简单了解Java日志脱敏框架sensitive,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 问题 为了保证用户的信息安全,敏感信息需要脱敏. 项目开发过程中,每次处理敏感信息的日志问题感觉很麻烦,大部分都是用工具类单独处理,不利于以后统一管理,很不优雅. 于是,就写了一个基于 java 注解的日志脱敏工具. github sensitive 项目介绍 日志脱敏是常见的安全需求.普通的基于工具类方法的方式,对代码的入侵性太强.

  • java自定义异常打印内容详解

    本文实例为大家分享了java自定义异常打印内容的具体代码,供大家参考,具体内容如下 背景:在开发中,我们可能会使用到自定义异常,但是,这个自定义异常在打印日志时,往往打印的内容比较多. 1.自定义异常打印内容 可以看到,虽然我们使用的是自定义异常,但是当抛出时,还是会打印出堆栈的全部信息. 2.查看源码 通过查看源码,我们可以得知,当抛出异常时,程序会调用此异常的fillInStackTrace方法,但是,大部分异常都没有对该方法做处理.基本是调用super的方法. 可以看到,此方法的父类实现,

随机推荐