应用中日志的优雅使用(整合log4j2与SLF4J)

这篇具有很好参考价值的文章主要介绍了应用中日志的优雅使用(整合log4j2与SLF4J)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

应用中日志的优雅使用(整合log4j2与SLF4J)

一些基础原则(来自阿里java开发手册)

  1. 应用中不可直接使用日志系统( Log4j、 Logback) 中的 API,而应依赖使用日志框架( SLF4J、 JCL–Jakarta Commons Logging) 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

    日志框架( SLF4J、 JCL–Jakarta Commons Logging)的使用方式(推荐使用 SLF4J)

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    private static final Logger logger = LoggerFactory.getLogger(Test.class);
    
  2. 所有日志文件至少保存 15 天,因为有些异常具备以“周” 为频次发生的特点。 对于当天日志,以“应用名.log” 来保存,保存在/home/用户名/software/应用名/logs/目录下,过往日志格式为: {logname}.log.{保存日期}.gz,日期格式: yyyy-MM-dd

  3. 在日志输出时,字符串变量之间的拼接使用占位符的方式 。

    LOGGER.info("SparkApp state: {}.", handle.getState().toString());
    
  4. 对于trace/debug级别的日志输出,必须进行日志级别的开关判断。

    if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("hadoopConfDir=[{}].", hadoopConfDir);
                LOGGER.debug("yarnConfDir=[{}].", hadoopConfDir);
                LOGGER.debug("javaHome=[{}].", javaHome);
                LOGGER.debug("sparkHome=[{}].", sparkHome);
                LOGGER.debug("appReSourcePath=[{}].", appReSourcePath);
                LOGGER.debug("appMainClass=[{}].", appMainClass);
                LOGGER.debug("hadoopUserName=[{}].", hadoopUserName);
                LOGGER.debug("retryMaxCount[{}].", retryMaxCount);
    }
    
  5. 禁止直接使用System.outSystem.err输出日志或使用e.printStackTrace()打印异常堆栈。

    标准日志输出与标准错误输出文件每次 Jboss 重启时才滚动,如果大量输出送往这两个文件,容易造成文件大小超过操作系统大小限制。

  6. 异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么通过关键字 throws 往上抛出。

    logger.error("inputParams:{} and errorMessage:{}", 各类参数或者对象 toString(), e.getMessage(), e);
    
  7. 除非是海外项目或者国外服务器,需要全部英文。国内使用中文进行输出和注释,避免词不达意或解释歧义的情况。

使用实例 整合log4j2与SLF4J

结合使用的原理:通过SLF4J的api调用log4j2的api,再由log4j2的api调用log4j2的core。

gradle引入依赖

	// >>>>>>日志依赖>>>>>>
	// log4j2的日志实现核心包,其依赖了log4j-api(log4j2的日志门面)
    implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.20.0'
    // log4j2和slf4j的连接包,版本与log4j2核心包一致
    implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.20.0'
	// slf4j的日志门面
    implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'

创建log4j2.xml配置文件。

log4j2加载配置文件机制:

  1. Log4j将检查"log4j2.configurationFile"系统属性,如果设置了,将尝试使用与文件扩展名匹配的ConfigurationFactory来加载配置。请注意,这并不局限于本地文件系统中的某个位置,可能包含一个URL。
  2. 如果没有设置系统属性,属性ConfigurationFactory将在classpath中寻找log4j2-test.properties
  3. 如果没有找到这样的文件,YAML ConfigurationFactory将在classpath中寻找log4j2-test.yamllog4j2-test.yml
  4. 如果没有找到这样的文件,JSON ConfigurationFactory将在classpath中寻找log4j2-test.jsonlog4j2-test.jsn
  5. 如果没有找到这样的文件,XML ConfigurationFactory将在classpath中寻找log4j2-test.xml
  6. 如果不能找到测试文件,属性ConfigurationFactory将在classpath中寻找log4j2.properties
  7. 如果不能找到属性文件,YAML ConfigurationFactory将在classpath上寻找log4j2.yamllog4j2.yml
  8. 如果YAML文件无法定位,JSON ConfigurationFactory将在classpath上寻找log4j2.jsonlog4j2.jsn
  9. 如果不能找到JSON文件,XML ConfigurationFactory将尝试在classpath上找到log4j2.xml
  10. 如果不能找到配置文件,将使用DefaultConfiguration。这将导致日志输出到控制台。

示例:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <!-- 变量配置  -->
    <Properties>
        <!-- 日志目录,prd环境取值改为/opt/logs/monitor -->
        <Property name="log_path">/home/china-unicorn/logs/monitor</Property>
        <Property name="logfile">china-unicorn</Property>
        <Property name="layout_pattern">[%d][%p][%t][%c:%L] %m%n</Property>
        <Property name="file_pattern">${log_path}/${logfile}.log-%d{yyyy-MM-dd}-%i.gz</Property>
    </Properties>

    <!-- appender配置 -->
    <Appenders>
        <!-- 控制台 -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${layout_pattern}"/>
        </Console>
        <!-- 每天滚动文件 -->
        <RollingFile name="DailyRollingFile" fileName="${log_path}/${logfile}.log"
                     filePattern="${file_pattern}">
            <PatternLayout pattern="${layout_pattern}"/>
            <policies>
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20 MB"/>
            </policies>
            <!--i的滚动大小限制是100-->
            <DefaultRolloverStrategy max="100">
                <Delete basePath="${log_path}">
                    <IfFileName glob="${logfile}-*.log.gz">
                        <!--目标路径下满足文件名命名要求的文件,保留天数或者路径下文件总大小-->
                        <IfAny>
                            <IfLastModified age="7d"/>
                            <IfAccumulatedFileSize exceeds="500 MB"/>
                        </IfAny>
                    </IfFileName>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="DEBUG">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="DailyRollingFile"/>
        </Root>
    </Loggers>
</Configuration>

创建TestLog.java

package com.donny.bigdata.test;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;

/**
 * @author 1792998761@qq.com
 * @date 2023/4/3 19:47
 */
public class TestLog {
    private static final Logger LOGGER = LoggerFactory.getLogger(TestLog.class);

    static {
        // 初始化log4j2日志-- 采用将自定义配置文件路径的方式
        LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
        File file = new File("conf/log4j2.xml");
        context.setConfigLocation(file.toURI());
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("log4j2初始化完毕");
        }
    }

    public static void main(String[] args) {
        LOGGER.info("中文");
    }
}

结果

[2023-04-04 14:58:06,719][DEBUG][main][com.donny.bigdata.test.TestLog:23] log4j2初始化完毕
[2023-04-04 14:58:06,719][INFO][main][com.donny.bigdata.test.TestLog:28] 中文

Gradle下日志包的冲突

利用dependencies,打印出依赖树。

命令式gradle :${modulename}:dependencies,${modulename}是个占位符,里面用模块名(project)替换。或者使用IDEA开发也可以通过执行项目Gradle面板中Tasks->help->dependencies任务,也打印出该模块对应的依赖树。

依赖树中包含以下部分

  • annotationProcessor
  • compileClasspath
  • compileOnly
  • default
  • implementation
  • mainSourceElements
  • runtimeClasspath
  • runtimeElements
  • runtimeOnly
  • testAnnotationProcessor
  • testCompileClasspath
  • testCompileOnly
  • testImplementation
  • testResultsElementsForTest
  • testRuntimeClasspath
  • testRuntimeOnly

部分举例展示:

compileClasspath - Compile classpath for source set 'main'.
+--- org.apache.logging.log4j:log4j-core:2.20.0
|    \--- org.apache.logging.log4j:log4j-api:2.20.0
+--- org.slf4j:slf4j-api:1.7.25
+--- org.apache.logging.log4j:log4j-slf4j-impl:2.20.0
|    +--- org.apache.logging.log4j:log4j-api:2.20.0
|    \--- org.slf4j:slf4j-api:1.7.25
+--- com.sun.mail:jakarta.mail:2.0.1
|    \--- com.sun.activation:jakarta.activation:2.0.1
...
...
...

implementation - Implementation only dependencies for source set 'main'. (n)
+--- org.apache.logging.log4j:log4j-core:2.20.0 (n)
+--- org.slf4j:slf4j-api:1.7.25 (n)
+--- org.apache.logging.log4j:log4j-slf4j-impl:2.20.0 (n)
+--- com.sun.mail:jakarta.mail:2.0.1 (n)
+--- jakarta.mail:jakarta.mail-api:2.0.1 (n)
+--- io.netty:netty-all:4.1.90.Final (n)
+--- org.elasticsearch.client:elasticsearch-rest-high-level-client:6.7.2 (n)
+--- org.elasticsearch.client:transport:6.7.2 (n)
+--- org.elasticsearch.client:elasticsearch-rest-client:6.7.2 (n)
+--- org.elasticsearch.client:elasticsearch-rest-client-sniffer:6.7.2 (n)
+--- org.apache.hadoop:hadoop-client:2.7.3 (n)
+--- org.apache.spark:spark-core_2.11:2.3.3 (n)
+--- org.apache.kafka:kafka-clients:1.0.0 (n)
+--- org.apache.hbase:hbase-client:1.1.2 (n)
+--- org.apache.hive:hive-jdbc:1.2.1 (n)
+--- com.clickhouse:clickhouse-jdbc:0.4.0 (n)
\--- org.apache.zookeeper:zookeeper:3.4.6 (n)
...
...
...

runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.logging.log4j:log4j-core:2.20.0
|    \--- org.apache.logging.log4j:log4j-api:2.20.0
+--- org.slf4j:slf4j-api:1.7.25
+--- org.apache.logging.log4j:log4j-slf4j-impl:2.20.0
|    +--- org.apache.logging.log4j:log4j-api:2.20.0
|    +--- org.slf4j:slf4j-api:1.7.25
|    \--- org.apache.logging.log4j:log4j-core:2.20.0 (*)
+--- com.sun.mail:jakarta.mail:2.0.1
|    \--- com.sun.activation:jakarta.activation:2.0.1
+--- jakarta.mail:jakarta.mail-api:2.0.1
...
...
...

在其中寻找冲突的包。

处理方式
  1. 优先排除冲突依赖

        implementation("org.apache.hadoop:hadoop-client:2.9.1") {
            exclude group: 'org.slf4j', module: 'slf4j-log4j12'
        }
    
  2. 强制使用某个依赖文章来源地址https://www.toymoban.com/news/detail-407908.html

    configurations.all {
        resolutionStrategy {
            force 'org.slf4j:slf4j-api:1.7.25'
        }
    }
    

到了这里,关于应用中日志的优雅使用(整合log4j2与SLF4J)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Springboot使用自带Logback 与 整合log4j 和 log4j2过程详解

    1、添加依赖 2、logback-spring.xml配置 3、使用   本地日志: 1、添加依赖 2、log4j.properties文件配置  3、配置文件中设置日志 application.yml: 4、使用: 1、添加依赖 2、log4j2.xml配置 3、配置文件中设置日志 application.yml 4、使用: 注意:如果pom.xml中添加有 spring-boot-starter-test 依赖 必

    2024年01月19日
    浏览(51)
  • Java日志系统log4j2的使用配置和异步日志使用

    Apache Log4j2是Log4j的升级版,参考了logback一些优秀的设计,并且修复了logback的一些问题,而且性能上也有了重大提升,主要有: log4j2对Appender提供了一些异常处理机制 参考了logback的设计,提供自动刷新参数配置,可以自动重载配置而不用重启应用 log4j2利用缓冲区和重用对象

    2024年02月02日
    浏览(45)
  • 深入理解 SpringBoot 日志框架:从入门到高级应用——(五)Log4j2配置文件详解

    Log4j2 官方文档:https://logging.apache.org/log4j/2.x/manual/index.html Log4j2 是一个Java日志框架,用于记录应用程序在运行时的信息。它是 Log4j 的升级版本,提供了更快的处理速度,更快的日志记录和更丰富的日志记录功能,并支持异步日志记录,减少了对应用程序性能的影响。它可以

    2024年02月05日
    浏览(45)
  • 深入理解 SpringBoot 日志框架:从入门到高级应用——(六)Log4j2 输出日志到 QQ邮箱

    要实现将 log4j2 输出日志到 QQ 邮箱,需按照以下步骤进行: 在 QQ 邮箱中设置 SMTP 服务,开启 POP3/SMTP 服务,获取 SMTP 服务地址、端口号、登录邮箱账号和密码。 在 Java 项目中添加 Mail 依赖。 在 log4j2.xml 配置文件中,添加 SMTPAppender,指定SMTP服务器地址、端口号、邮箱账号和

    2024年02月09日
    浏览(51)
  • springboot 日志管理之 log4j2

    1、log4j2 简介         Apache Log4j2是对Log4j的升级,它比其前身Log4j 1.x提供了重大改进,并提供了Logback中可用的许多改进,同时修复了Logback架构中的一些问题。 被誉为是目前最优秀的Java日志框架。 2、项中引入 log4j2 的方式 2.1、springboot 项目中 2.2、普通 java 项目中 3、在项

    2024年01月15日
    浏览(47)
  • 【springboot】--集成log4j2日志功能

    springboot2.0版本默认集成logback日志框架,由于项目业务采集各种日志(系统日志、接口调用日志、业务日志)等,需要做一些定制化的业务。为了,这里介绍如何集成log4j2,按照规格输出日志,另外按照要求输出成文件。下面将具体介绍! pom引入

    2024年02月12日
    浏览(57)
  • log4j2同步日志引发的性能问题

    在项目的性能测试中,相关的接口的随着并发数增加,接口的响应时间变长,接口吞吐不再增长,应用的CPU使用率较高。 谁导致的CPU较高,阻塞接口TPS的增长?接口的响应时间的调用链分布是什么样的,有没有慢的点? 1)使用火焰图分析应用的CPU如下,其中log4j2日志占了

    2024年02月08日
    浏览(38)
  • Linux服务器使用Redis作为数据缓存,并用log4j2进行日志记录

    前言 个人网站使用Vue作为前端,SpringBoot作为后端,MySQL作为数据库,但前端每次请求都会从MySQL数据库中读取数据,而MySQL数据库的数据是存储于服务器磁盘中,所以响应速度有一定影响。之前了解过一点Redis数据库,该数据库数据存储于内存中(也可以持久化于磁盘中),数

    2024年02月08日
    浏览(54)
  • Springboot日志框架logback与log4j2

    目录 Springboot日志使用 Logback日志 日志格式 自定义日志格式 日志文件输出 Springboot启用log4j2日志框架 Springboot底层是使用slf4j+logback的方式进行日志记录 trace:级别最低 debug:调试级别的,常用于跟踪程序的进展 info:普通的打印信息(默认的日志级别) warn:警告级别,不影响

    2024年01月19日
    浏览(46)
  • Log4j2 配置日志记录发送到 kafka 中

    前言 log4j2 在 2.11.0 之后的版本,已经内置了 KafkaAppender 支持可以将打印的日志直接发送到 kafka 中,在这之前如果想要集中收集应用的日志,就需要自定义一个 Layout 来实现,相对来说还是比较麻烦的。 官网文档:Log4j – Log4j 2 Appenders 依赖 配置 注意这里有个 syncSend 控制着是

    2024年02月10日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包