【JAVA】Log4j、Logback、JUL日志文件详解(保姆篇),以及如何去掉控制台没用的日志案例分享

在这里插入图片描述


更多相关内容可查看

日志记录是软件开发中不可或缺的一部分。它不仅帮助开发者调试程序,还能提供系统运行状态的实时反馈。深入了解 log.config 文件,它是配置日志记录行为的核心组件。通过具体示例,学习如何编写、修改和使用日志配置文件。

主要是看烦了一些没用的日志疯狂输出

什么是 log.config 文件?

log.config 文件是用于配置日志记录系统的文件,它定义了日志的格式、级别、输出位置等参数。配置文件的结构和语法取决于你使用的日志框架。常见的日志框架包括 Log4j、Logback 和 Java Util Logging (JUL)。

1. 日志框架分类

  • Log4j

    Log4j 是 Apache 提供的一个日志框架,它允许开发者根据需要配置日志输出。Log4j 的配置文件通常是 XML、JSON 或者Properties 格式。

  • Logback

    Logback 是 Log4j 的继任者,由同一作者开发。它提供了更高效的日志记录能力和更灵活的配置选项。Logback 的配置文件通常是
    XML 格式。

  • Java Util Logging (JUL)

    JUL 是 Java 标准库中的日志框架。它的配置文件通常是 Properties 格式。


2. 配置文件示例

Log4j 配置文件示例

<Configuration>
    <Appenders>
        <Console name="ConsoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="ConsoleAppender"/>
        </Root>
    </Loggers>
</Configuration>

Logback 配置文件示例

<configuration>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="debug">
        <appender-ref ref="console"/>
    </root>
</configuration>

Java Util Logging 配置文件示例

handlers= java.util.logging.ConsoleHandler
.level= INFO
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

3. 修改示例

Log4j 修改示例

假设我们需要将日志级别改为 info 并添加一个文件输出的 appender:

<Configuration>
    <Appenders>
        <Console name="ConsoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"/>
        </Console>
        <File name="FileAppender" fileName="app.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="ConsoleAppender"/>
            <AppenderRef ref="FileAppender"/>
        </Root>
    </Loggers>
</Configuration>

Logback 修改示例

将日志级别修改为 info 并添加一个文件输出的 appender:

<configuration>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="file" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="file"/>
    </root>
</configuration>

Java Util Logging 修改示例

添加一个文件 handler 并将日志级别修改为 info

handlers= java.util.logging.ConsoleHandler, java.util.logging.FileHandler
.level= INFO
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.FileHandler.level = INFO
java.util.logging.FileHandler.pattern = app.log
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

4. 打印示例

在不同框架中打印日志的方式略有不同:

Log4j

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class LogExample {
    private static final Logger logger = LogManager.getLogger(LogExample.class);

    public static void main(String[] args) {
        logger.info("This is an info message");
        logger.debug("This is a debug message");
    }
}

Logback

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogExample {
    private static final Logger logger = LoggerFactory.getLogger(LogExample.class);

    public static void main(String[] args) {
        logger.info("This is an info message");
        logger.debug("This is a debug message");
    }
}

Java Util Logging

import java.util.logging.Logger;

public class LogExample {
    private static final Logger logger = Logger.getLogger(LogExample.class.getName());

    public static void main(String[] args) {
        logger.info("This is an info message");
        logger.fine("This is a debug message");
    }
}

5. 配置文件Logback示例(详细看注释)

<?xml version="1.0" encoding="utf-8"?>
<!--30 seconds  scan="true" scanPeriod="1 minutes" from common-->
<configuration>
    <!-- 定义一个名为 LOG_HOME 的属性,指定日志文件的存储路径 -->
    <property name="LOG_HOME" value="../logs"/>
    
    <!-- 定义一个名为 metric 的 appender,用于将日志记录到 MetricAppender -->
    <appender name="metric" class="kd.bos.metric.instruments.logback.MetricAppender"></appender>
    
    <!-- 定义一个名为 std 的 appender,用于将日志输出到控制台 -->
    <appender name="std" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 定义控制台日志的布局格式 -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!-- 日志输出的格式:时间、线程、日志级别、日志记录器名称、方法、行号和日志消息 -->
            <pattern>%d{HH:mm:ss} [%thread] %level %logger.%M\(%L\):%m%n</pattern>
        </layout>
    </appender>
    
    <!-- 定义一个名为 kafka 的 appender,用于将日志发送到 Kafka -->
    <appender name="kafka" class="kd.bos.logging.console.slf4j.logback.KafkaAppender">
        <!-- Kafka 主题名称 -->
        <topic>{{clusterName}}-log</topic>
        <!-- Kafka 代理列表 -->
        <brokerList>{{log.kafka.ip_port}}</brokerList>
        <!-- 消息压缩类型 -->
        <compressionType>none</compressionType>
        <!-- 是否同步发送 -->
        <syncSend>false</syncSend>
        <!-- Kafka 消息键序列化器 -->
        <keySerializerClass>org.apache.kafka.common.serialization.StringSerializer</keySerializerClass>
        <!-- Kafka 消息值序列化器 -->
        <valueSerializerClass>org.apache.kafka.common.serialization.StringSerializer</valueSerializerClass>
    </appender>
    
    <!-- 定义一个名为 file 的 appender,用于将日志记录到文件 -->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 定义滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名模式,包括日期和索引 -->
            <FileNamePattern>${LOG_HOME}/log.%d{yyyy-MM-dd}(%i).log</FileNamePattern>
            <!-- 启动时清理旧日志 -->
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
            <!-- 保留日志的最大历史天数 -->
            <maxHistory>5</maxHistory>
            <!-- 定义文件命名和触发策略 -->
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- 文件的最大大小 -->
                <MaxFileSize>10MB</MaxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 定义日志文件的编码和格式 -->
        <encoder>
            <!-- 字符集 -->
            <charset>utf-8</charset>
            <!-- 日志输出的格式 -->
            <pattern>%d{HH:mm:ss} [%thread] %level %logger.%M\(%L\):%m%n</pattern>
        </encoder>
        <!-- 是否追加日志到现有文件 -->
        <append>false</append>
        <!-- 是否使用慎重模式(文件锁定) -->
        <prudent>false</prudent>
    </appender>
    
    <!-- 定义特定的 logger 配置,控制日志输出到哪些 appender -->
    <logger name="org.javaswift.joss.command.impl.core.AbstractCommand" additivity="false" level="OFF">
        <!-- 将日志输出到 std appender -->
        <appender-ref ref="std"/>
    </logger>
    <logger name="org.ehcache" additivity="false" level="OFF">
        <!-- 将日志输出到 std appender -->
        <appender-ref ref="std"/>
    </logger>
    <logger name="org.apache" additivity="false" level="ERROR">
        <!-- 将日志输出到 std appender -->
        <appender-ref ref="std"/>
    </logger>
    <logger name="kd.bos.dc.utils.AccountUtils" additivity="false" level="ERROR">
        <!-- 将日志输出到 kafka appender -->
        <appender-ref ref="kafka"/>
    </logger>
    <logger name="kd.bos.license" additivity="false" level="ERROR">
        <!-- 将日志输出到 std appender -->
        <appender-ref ref="std"/>
    </logger>
    
    <!-- 定义 root logger 配置 -->
    <root name="DB" additivity="false" level="INFO">
        <!-- 将日志输出到 std appender -->
        <appender-ref ref="std"/>
    </root>
    <root level="INFO">
        <!-- 将日志输出到 file appender -->
        <appender-ref ref="file"/>
    </root>
</configuration>

关键概念解释:

  • Appender: 日志的输出方式,可以是控制台、文件、远程服务器等。
  • Logger: 负责记录日志的对象。可以为不同的类或包指定不同的日志级别和输出方式。
  • Root Logger: 默认的日志记录器,如果没有指定更具体的 logger,会使用 root logger 的配置。
  • PatternLayout: 用于定义日志输出的格式。
  • RollingFileAppender: 支持日志文件滚动(基于时间和大小)。

6. 减少控制台输出方法(Logback)

  1. 调整日志级别:
    rootlogger 节点下调整 level 属性来设置日志的级别。日志级别从高到低依次为 ERRORWARNINFODEBUGTRACE。设置为较高的级别可以减少日志输出。例如:

    <root level="ERROR">
        <appender-ref ref="std"/>
    </root>
    

    这样,控制台上只会输出 ERROR 级别的日志,而忽略 INFODEBUGTRACE 级别的日志。

  2. 禁用不需要的日志记录器:
    logger 节点中,将一些特定的日志记录器的日志级别设置为 OFF。如果还有其他不希望输出日志的记录器,可以继续添加类似的配置。例如:

    <logger name="com.example.unwanted" additivity="false" level="OFF">
        <appender-ref ref="std"/>
    </logger>
    

    这将禁用 com.example.unwanted 包中的所有日志输出到控制台。

  3. 去掉不需要的 appender:
    如果有些 appender 不需要,特别是那些输出到控制台的 appender,可以将它们移除。例如,如果你不希望日志输出到控制台,可以将 std 相关的配置删除或注释掉:

    <!--
    <appender name="std" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{HH:mm:ss} [%thread] %level %logger.%M\(%L\):%m%n</pattern>
        </layout>
    </appender>
    -->
    

    记得同时调整 root 和其他 loggerappender-ref 配置,以避免引用已删除的 appender

  4. 配置文件中的日志级别:
    在配置文件中设置 level 属性为 ERROR 可以帮助你过滤掉 INFODEBUG 级别的日志:

    <root level="ERROR">
        <appender-ref ref="std"/>
    </root>
    
  5. 检查 Logback 的继承性:
    确保你理解了 additivity 属性的作用。默认情况下,日志记录器会继承 root 记录器的配置。如果你希望禁用某些记录器的输出,可以设置 additivity="false",确保日志不会被继承。

  6. 调整 pattern:
    如果日志格式中的一些信息不需要,也可以修改 pattern 来调整输出格式。例如:

    <pattern>%d{HH:mm:ss} %level %logger: %m%n</pattern>
    

    这样可以减少每条日志的冗余信息,从而使日志更加简洁。

上述内容是用了一个我目前用到的Logback的做了一个示例,其实道理都是一样的,会配一个其他也自然就会了,去掉一些没用的日志,对于排查问题是有很大的帮助的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来一杯龙舌兰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值