Log4j无缝升级到Log4j2+Slf4j

log4j的项目升级log4j2 0.背景 虽然大部分的java项目使用的都是logback,但是仍然有很多开源项目使用log4j,例如kafka、zookeeper。但是log4j已经于2012年停止更新,并且log4j扫出如下安全漏洞: https://rnd-vulncenter.huawei.com/vuln/toViewOfficialDetail?cveId=CVE-2020-9488 https://rnd-vulncenter.huawei.com/vuln/toViewOfficialDetail?cveId=CVE-20 阅读详情

修改记录

20190627:
1修改日志文件切分配置错误:配置的切分标签必须在内
另外:filePattern不要用变量Properties引用变量名,那样启动会检测不到里面的%d{yyyy-MM-dd}会报错.

<!-- 反例 -->
<RollingFile name="error_log" fileName="${rolling_fileName}" filePattern="${basePath}/${loggz}/hrapp-%d{yyyy-MM-dd}.log">
    <!-- 其他配置略-->       
	<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
	<SizeBasedTriggeringPolicy size="20 MB"/>
 </RollingFile>

<!-- 正例 -->
<RollingFile name="error_log" fileName="${rolling_fileName}" filePattern="${basePath}/${loggz}/hrapp-%d{yyyy-MM-dd}.log">
    <!-- 其他配置略-->
    <Policies>       
		<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
		<SizeBasedTriggeringPolicy size="20 MB"/>
	</Policies>
 </RollingFile>

2另外发现当windows环境下配置的不是完整日志输出文件路径导致自动切分日志规则不生效的问题
具体配置如下:
log4j2.xml配置里配置的属性

<!--不完整的路径,在tomcat所在目录的所在盘下生成路径:D:\opt\maxtech\tomcat_logs\projectname,启动tomcat会有日志文件,但是动态规则的拆分日志(按日期/大小等规则)不生效了. -->
<property name="basePath">/opt/maxtech/tomcat_logs/projectname</property>
<!--改为以下全路径(可以用变量,tomcat路径之类的变量) -->
<property name="basePath">D:\opt\maxtech\tomcat_logs\projectname</property>

Step1: 修改maven项目的pom.xml

  1. 移除原有项目log4j的依赖内容模块
  2. 加入以下内容,属性部分加入
 <properties>
         <!--设置Log4j2 跟 slfj0-->
         <log4j.version>2.11.2</log4j.version>
         <slf4j.version>1.7.26</slf4j.version>
    </properties>
  1. 添加log4j2和slf4j的依赖
        <!--slf4j的依赖-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!--log4j2 的依赖-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <!--用于与sfl4j保持桥接-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-web</artifactId>
            <version>${log4j.version}</version>
            <scope>runtime</scope>
        </dependency>
        <!--  用来无缝切换Log4j到log4j2的中间层 注意版本号要跟用的log4j2的版本号一致 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-1.2-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>

Step2:删除原有Log4j的配置

	<!-- 加载LOG4J -->
<!--	<context-param>-->
<!--		<param-name>log4jConfigLocation</param-name>-->
<!--		<param-value>/WEB-INF/log4j.xml</param-value>-->
<!--	</context-param>-->

Step3:添加Log4j2配置文件

本次示例使用的xml配置文件名为log4j2.xml,Log4j2新版情况是不用配置文件的位置的,默认会自动扫描文件名是log4j2的配置文件(格式可能是xml.yml等)

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="off" monitorInterval="60">
    <Properties>
        <!-- 日志默认存放的位置,这里设置为项目根路径下,也可指定绝对路径 -->
        <!-- ${web:rootDir}是web项目根路径,java项目没有这个变量,需要删掉,否则会报异常 ;${sys:catalina.home}默认是tomcat的根目录,根据需要调整,可以设置项目服务器绝对路径-->
        <property name="basePath">${sys:catalina.home}/WebAppLogs/你希望文件夹名(可以是项目名+log)</property>
        <property name="loggz">loggz</property>
        
        <!-- <property name="basePath">d:/qfxSpringMVCMybaitsDemoLogs</property> -->

        <!-- 控制台默认输出格式,"%-5level":日志级别,"%l":输出完整的错误位置,是小写的L,因为有行号显示,所以影响日志输出的性能 -->
        <property name="console_log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %l - %m%n</property>
        <!-- 日志文件默认输出格式,不带行号输出(行号显示会影响日志输出性能);%C:大写,类名;%M:方法名;%m:错误信息;%n:换行 -->
        <property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %C.%M - %m%n</property>

        <!-- 日志默认切割的最小单位 -->
        <property name="every_file_size">20MB</property>
        <!-- 日志默认输出级别 -->
        <property name="output_log_level">INFO</property>

        <!-- 日志默认存放路径(所有级别日志) -->
        <!--<property name="rolling_fileName">${basePath}/all.log</property>-->
        <!--&lt;!&ndash; 日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 &ndash;&gt;-->
        <property name="rolling_filePattern">${basePath}/${loggz}/all-${date:yyyy-MM-dd}-%i.log.gz</property>
        <!--&lt;!&ndash; 日志默认同类型日志,同一文件夹下可以存放的数量,不设置此属性则默认为7个 &ndash;&gt;-->
        <property name="rolling_max">50</property>

        <!-- Info日志默认存放路径(Info级别日志) -->
        <property name="info_fileName">${basePath}/info-${date:yyyy-MM-dd}.log</property>
        <!-- Info日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
        <property name="info_filePattern">${basePath}/${loggz}/info-${date:yyyy-MM-dd}-%i.log.gz</property>
        <!-- Info日志默认同一文件夹下可以存放的数量,不设置此属性则默认为7个 -->
        <property name="info_max">30</property>

        <!-- Warn日志默认存放路径(Warn级别日志) -->
        <property name="warn_fileName">${basePath}/warn-${date:yyyy-MM-dd}.log</property>
        <!-- Warn日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
        <property name="warn_filePattern">${basePath}/${loggz}/warn-${date:yyyy-MM-dd}-%i.log.gz</property>
        <!-- Warn日志默认同一文件夹下可以存放的数量,不设置此属性则默认为7个 -->
        <property name="warn_max">30</property>

        <!-- Error日志默认存放路径(Error级别日志) -->
        <property name="error_fileName">${basePath}/error-${date:yyyy-MM-dd}.log</property>
        <!-- Error日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
        <property name="error_filePattern">${basePath}/${loggz}/error-${date:yyyy-MM-dd}-%i.log.gz</property>
        <!-- Error日志默认同一文件夹下可以存放的数量,不设置此属性则默认为7个 -->
        <property name="error_max">30</property>

        <!-- 控制台显示的日志最低级别 -->
        <property name="console_print_level">DEBUG</property>

    </Properties>

    <!--定义appender -->
    <appenders>
        <!-- 用来定义输出到控制台的配置 -->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 设置控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="${console_print_level}" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 设置输出格式,不设置默认为:%m%n -->
            <PatternLayout pattern="${console_log_pattern}"/>
        </Console>

        <!--&lt;!&ndash; 打印root中指定的level级别以上的日志到文件 &ndash;&gt;-->
        <!--<RollingFile name="RollingFile" fileName="${rolling_fileName}" filePattern="${rolling_filePattern}">-->
            <!--<PatternLayout pattern="${log_pattern}"/>-->
            <!--<SizeBasedTriggeringPolicy size="${every_file_size}"/>-->
            <!--&lt;!&ndash; 设置同类型日志,同一文件夹下可以存放的数量,如果不设置此属性则默认存放7个文件 &ndash;&gt;-->
            <!--<DefaultRolloverStrategy max="${rolling_max}" />-->
            <!--&lt;!&ndash; 匹配INFO以及以上级别 &ndash;&gt;-->
            <!--<Filters>-->
                <!--<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>-->
            <!--</Filters>-->
        <!--</RollingFile>-->

        <!-- 打印INFO级别的日志到文件 -->
        <RollingFile name="InfoFile" fileName="${info_fileName}" filePattern="${info_filePattern}">
        <!--设置输出日志的编码格式,根据需求自行调整.-->
            <PatternLayout charset="UTF-8"  pattern="${log_pattern}"/>
            <Policies>
            	<SizeBasedTriggeringPolicy size="${every_file_size}"/>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
            <DefaultRolloverStrategy max="${info_max}" />
            <!-- 匹配INFO级别 -->
            <Filters>
                <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </RollingFile>

        <!-- 打印WARN级别的日志到文件 -->
        <RollingFile name="WarnFile" fileName="${warn_fileName}" filePattern="${warn_filePattern}">
            <PatternLayout charset="UTF-8"  pattern="${log_pattern}"/>
            <Policies>       
				<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
				<SizeBasedTriggeringPolicy size="20 MB"/>
			</Policies>
            <DefaultRolloverStrategy max="${warn_max}" />
            <!-- 匹配WARN级别 -->
            <Filters>
                <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </RollingFile>

        <!-- 打印ERROR级别的日志到文件 -->
        <RollingFile name="ErrorFile" fileName="${error_fileName}" filePattern="${error_filePattern}">
            <PatternLayout charset="UTF-8"  pattern="${log_pattern}"/>
            <Policies>       
				<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
				<SizeBasedTriggeringPolicy size="20 MB"/>
			</Policies>
            <DefaultRolloverStrategy max="${error_max}" />
            <!-- 匹配ERROR级别 -->
            <Filters>
                <ThresholdFilter level="FATAL" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </RollingFile>
    </appenders>

    <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <!-- 设置对打印sql语句的支持 -->
        <logger name="java.sql" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>


        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.springframework" level="info"></logger>
        <logger name="org.mybatis" level="info"></logger>

        <!-- 第三方日志系统 -->

        <logger name="org.springframework.core" level="info" additivity="true">
        </logger>
        <logger name="org.springframework.beans" level="info">
        </logger>
        <logger name="org.springframework.context" level="info">
        </logger>
        <logger name="org.springframework.web" level="info">
        </logger>

        <!--建立一个默认的root的logger-->
        <root level="${output_log_level}">
            <!--<appender-ref ref="RollingFile"/>-->
            <appender-ref ref="Console"/>
            <appender-ref ref="InfoFile" />
            <appender-ref ref="WarnFile" />
            <appender-ref ref="ErrorFile"/>
        </root>
    </loggers>
</configuration>

标签解释:
TimeBasedTriggeringPolicy
关键点在于 filePattern后的日期格式,以及TimeBasedTriggeringPolicy的interval,日期格式精确到哪一位,interval也精确到哪一个单位,也就是日志切分的步长,比如如果filePattern最后精确单位是HH,interval=“4”,则间隔4个小时切分日志文件. -
modulateboolean型,说明是否对封存时间进行修正。若modulate=true(默认值),则封存时间将以0点为边界进行偏移计算。比如,modulate=true,interval=4hours,那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,之后的封存时间依次为08:00,12:00,16:00,。。。

SLF4JLog4j2集成原理及生产级日志配置实战 日志框架是Java应用可观测性的基石,SLF4J作为统一门面接口,通过桥接器(binding)解耦日志API与具体实现,实现面向接口编程;Log4j2则凭借Disruptor异步架构、零GC对象复用和复合滚动策略,提供高性能、高可靠日志能力。其技术价值在于保障开发阶段的API稳定性与生产环境的I/O吞吐、磁盘可控、内存安全三重底线。典型应用场景涵盖微服务全链路追踪(MDC)、多环境差异化输出(Console/rolling)、敏感信息动态脱敏(StrLookup),以及Spring Boot等主流框架的日志 阅读详情

相关推荐

Java日志框架核心原理:SLF4J门面与Log4j2实现深度解析

日志是Java应用可观测性的基石,其本质是一套标准化的事件记录与分级输出机制。SLF4J作为统一门面接口,解耦了日志API与具体实现(如Log4j2Logback),通过绑定器(Binding)在运行时动态选择实现,实现面向接口编程。这种分层设计不仅提升可维护性,更支撑企业级日志治理——包括异步高性能写入、多维度上下文(MDC)、滚动归档与安全防护。Log4j2凭借LMAX Disruptor异步架构和CVE-2021-44228漏洞后的加固演进,成为高吞吐、强安全场景首选;而SLF4J的桥接机制则保障了

weixin_34112181的博客 299

使用桥接器在不改变源码的情况下实现从log4j日志框架转变为slf4j+logback日志框架

一、搭建log4j日志框架环境并输出日志格式 1.1导入log4j依赖 导入apache下的log4j的jar包 <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> 导入测试包,用于测试日志输出 ..

lisfsfs的博客 1149

SpringBoot项目如何优雅替换Logback为Log4j2?5步搞定性能提升

本文详细介绍了如何将SpringBoot项目中的默认日志框架Logback优雅替换为高性能的Log4j2。通过5个关键步骤——深度评估、依赖治理、配置重构、代码适配与验证监控,开发者可以平滑完成迁移,有效解决高并发场景下的日志性能瓶颈,显著提升系统吞吐量并降低延迟。

p4q5r6s7t的博客 530

log4j如何转为slf4j+log4j

第一步maven项目可直接删除之前依赖的log4j jar包非maven项目无需删除配置文件无需删除第二步maven项目直接添加slf4j-log4j12依赖,jar包版本自行选择,该依赖会自动下载log4jslf4j-api,slf4j-log4j12三个jar包&lt;!--slf4j-log4j--&gt; &lt;dependency&gt; &lt;groupId&gt;org...

wanan_1001 4442

log4j2换成logback

log4j2 logback 日志转换

u011618288的博客 1548

java log4j api_Java日志框架——JCL(Log4J,Java Logging API )转SLF4J

一、应用场景有很多以前的项目采用JCL,Log4J,Java Logging API等作为日志框架,现在如果想改成使用流行的SLF4J日志框架,但是不能改变项目代码,该如何做?这就是jcl-over-slf4j(针对的是原来使用JCL),log4j-over-slf4j(针对的是原来使用Log4J),jul-to-slf4j(针对的是原来使用Java Logging API)等转换方案产生的原因所...

weixin_28893705的博客 866

记录log4j2升级遇到问题

一.背景 1.项目原来使用jdk6、tomcat6、maven2.2日志使用log4j2没有任何问题,由于升级项目jdk8、tomcat8、maven3.2.5之后日志一行都不出并且没有任何保存信息。 2.项目中是通过代码配置加载log4j2的,servlet2.5以上版本会自己加载log4j2.xml无需配置 public class InitListener implements ServletContextListener { private Logger log = LogManager.getL

nbdebuyaobuyao的博客 777

SpringBoot - 日志系统 SLF4j + Log4j2

SpringBoot 接入日志系统 目录SpringBoot 接入日志系统概述组件依赖配置 概述 上一篇搭建了VS Code的SpringBoot环境。 现在开始搭建SpringBoot日志系统。 SpringBoot常用的日志组件: 一、抽象层:SLF4j (对所有日志实现层的规范封装,这样可以无缝切换各种实现层) 二、实现层:Log4jLogback,Log4j2 Log4j:已弃用,2015年已停止更新。 Logback:SpringBoot默认使用。 Log4j2Log4j升级,集成了Logba

Rain's Blog 582

Zookeeper的服务器的log4j升级log4j2升级方案(忽略配置化兼容问题)

洛神灬殇正在上传…重新上传取消2022年10月24日 18:15 · 阅读 1333目前希望可以升级将Zookeeper中log4j的版本升级log4j2版本,并且要避开相关的log4j2的安全隐患问题,此时需要考虑的就是针对于如何将无缝衔接log4j2的版本jar包的安装呢?我们接下来观察一下看看问题所在。目前我采用的环境是windows环境,不过也同样对其他操作系统有效,毕竟万变不离其宗嘛。windows目录Linux目录首先我们需要进行替换相关的lib包信息,我们需要将相关的zookeeper中所

BASK2312的博客 1769

Mybatis日志Log4jLogback

它实现了日志事件的处理和分发,以及日志的格式化和输出等核心功能。Logback是由Log4j创始人Ceki Gülcü开发的后继项目,旨在解决Log4j的问题,并提供更好的性能和可靠性,因此Logback可以被视为Log4j升级版。使用 Slf4j 可以让你的应用程序与具体的日志实现库解耦,从而可以灵活地切换和配置不同的日志库,例如 Log4jLogback等。3、查看日志输出:在控制台窗口的选项卡中,您将看到应用程序的日志输出,您可以滚动查看日志消息,以及根据需要过滤和搜索特定的日志消息。

云域A的博客 3099

Log4j 2:日志管理的升级之道

Log4j 2凭借其API与实现分离、异步日志、自动配置重载等诸多优势,在日志管理领域脱颖而出。它不仅提供了丰富的组件和灵活的配置方式,还支持多种API,能够满足不同项目的需求。通过本文的介绍和示例演示,相信开发者们对Log4j 2有了更深入的了解,可以将其应用到实际项目中,提升日志管理的效率和质量。

m0_62153576的博客 421

Java日志门面框架--SLF4J

sl4j日志框架视频学习记录

trh_csdn的博客 1633

log4j2 + slf4j 项目实践

End of Life On August 5, 2015 the Logging Services Project Management  Committee announced that Log4j 1.x had reached end of life. For  complete text of the announcement please see the Apache Blog. Us...

继续,Let's Go! 660

Logback --- (一) 日志框架原理

随着软件开发的不断发展,日志框架已经成为软件开发中不可或缺的一部分。它们通过提供丰富的日志管理功能、强大的问题追踪与定位能力、提高代码的可读性和可维护性、支持性能监控与优化以及保障安全性等方面,为软件开发、调试和运维工作提供了强有力的支持。因此,在开发新的应用程序或维护现有系统时,使用日志框架是一个明智的选择。

qq_65701921的博客 1806

SLF4J入门指南:Java日志统一的终极解决方案

SLF4J(Simple Logging Facade for Java)是Java领域一款**终极日志统一解决方案**,它作为日志门面框架,能够无缝整合各类日志实现(如Log4jLogback、JUL等),帮助开发者轻松解决项目中的日志管理难题。无论是小型应用还是大型系统,SLF4J都能提供简单、灵活且高效的日志处理能力。 ## 📌 为什么选择SLF4J?核心优势解析 ### 1. 日志

gitblog_00486的博客 582

深入理解SLF4J日志接口与版本1.7.7解析

SLF4J(Simple Logging Facade for Java)是一个Java平台上的简单日志门面(Facade),它为不同日志系统提供了一个统一的接口,使得开发者可以使用SLF4J接口而不需要在代码中绑定到具体的日志实现。这样做有一个明显的优势:可以在运行时切换日志框架,不必重新编译代码。此外,SLF4J还能使系统保持对日志实现的独立性,使得在项目维护和升级过程中更为灵活。

weixin_32242475的博客 895

Logback与SLF4J配置:实例详解与应用

SLF4J(Simple Logging Facade for Java),即Java简单日志门面,是一个为Java程序设计提供日志系统的抽象层。它本身并不提供日志记录的实现,而是在运行时动态绑定不同的日志框架,如Logback、Log4j和java.util.logging等。这种设计允许开发人员在不同的实现之间切换,而无需修改日志记录的代码。Logback作为SLF4J日志门面框架的默认实现之一,它的起源要追溯到Log4j

weixin_35649491的博客 913

浅谈日志门面

1.日志框架简介 jul:j.u.l是java.util.logging包的简称,是JDK在1.4版本中引入的Java原生日志框架。 Log4j:Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式; 通过定义每...

jiangsir_sub的博客 2811
上一篇: idea无法使用Browse repositories安装插件问题解决办法(2018版idea)
下一篇: Log4j2切面AOP拦截exception
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值