java 各种日志框架 日志门面 关系总结
logback官网手册(英文):https://logback.qos.ch/manual/index.html
logback 中文手册:http://www.logback.cn/
日志实现: jul,log4j,log4j2,logback
日志门面: jcl, slf4j
-
log_jul: jul方式的日志记录
-
log_jul_jcl: 通过jcl日志门面,使用jul方式的日志记录
-
log_jul_slf4j: 通过slf4j日志门面,使用jul方式的日志记录
-
log_log4j: log4j方式的日志记录
-
log_log4j_jcl: 通过jcl日志门面,使用log4j方式的日志记录
-
log_log4j_slf4j:通过slf4j日志门面,使用log4j方式的日志记录
-
log_log4j2: log4j2方式的日志记录
-
log_log4j2_jcl: 通过jcl日志门面,使用log4j2方式的日志记录
-
log_log4j2_slf4j:通过slf4j日志门面,使用log4j2方式的日志记录
-
log_logback: 通过slf4j日志门面,使用logback方式的日志记录
-
log_jcl_to_slf4j_log4j: jcl门面实现转slf4j门面,log4j方式的日志记录
-
log_jcl_to_slf4j_log4j2: jcl门面实现转slf4j门面,log4j2方式的日志记录
-
log_jcl_to_slf4j_logback: jcl门面实现转slf4j门面,logback方式的日志记录
-
log_jul_to_slf4j_log4j: jul方式 转slf4j门面,log4j(log4j2/logback方式省略测试)方式的日志记录
-
log_log4j_to_slf4j_logback: log4j方式 转slf4j门面,logback方式的日志记录
1. log_jul: jul方式的日志记录 logging.properties

package com.logtest; import java.io.IOException; import java.io.InputStream; import java.util.logging.*; /** * @authour cyf * 2023/7/29 6:48 * * 参考地址:https://blog.51cto.com/u_15874356/6097579 */ public class JulTest { public static void main(String[] args) throws IOException { String path = JulTest.class.getName(); //log01(path); //log02(path); //log03(path); //log04(path); log05(path); } /** * 1、默认配置日志输出 * ①获取 Logger 对象 * ②日志记录输出 info(String msg)//直接输出 log(Level level, String msg)//设置日志级别输出 log(Level level, String msg, Object params[])//通过占位符 输出变量值 */ public static void log01(String path){ //1.获取日志记录器对象 //命名:通常使用当前类的全限定类名(包名+类名) Logger logger = Logger.getLogger(path); //2.日志记录输出 //2.1.直接输出日志 logger.info("hello jul"); //2.2.设置级别 输出日志 logger.log(Level.INFO, "level info msg"); //2.3.通过占位符方式 输出变量值 String msg = "hello world"; Integer num = 123; logger.log(Level.INFO, "user message:{0}, {1}", new Object[]{msg, num}); } /** * 2、直接对应日志级别输出 */ public static void log02(String path){ Logger logger = Logger.getLogger(path); //2.日志记录输出 logger.severe("severe"); logger.warning("warning"); logger.info("info");//默认日志输出级别 logger.config("config"); logger.fine("fine"); logger.finer("finer"); logger.finest("finest"); } /** * 3、自定义编码形式日志输出 * ①获取日志记录对象Logger * ②用该对象关闭其系统默认配置 * ③创建Handler * ④创建Formatter * ⑤通过Handler设置Formatter * ⑥通过Logger对象设置Handler(一个Logger对象可以设置多个Handler) * ⑦设置Handler、Logger日志级别 */ public static void log03(String path){ //1.获取日志记录器对象 Logger logger = Logger.getLogger(path); //1.1.关闭系统默认配置 logger.setUseParentHandlers(false); //1.2.自定义配置日志级别(关联处理器&转换器) //1.2.1.创建ConsoleHandler ConsoleHandler consoleHandler = new ConsoleHandler(); //1.2.2.创建简单格式转换对象 SimpleFormatter simpleFormatter = new SimpleFormatter(); //1.2.3.进行关联 consoleHandler.setFormatter(simpleFormatter); logger.addHandler(consoleHandler); //1.3.设置日志具体级别 logger.setLevel(Level.ALL); consoleHandler.setLevel(Level.ALL); //场景FileHandler 文件输出 (手动建好文件夹F:/WorkSpaceSpringBoot/AllLogTest/logs/) FileHandler fileHandler = null; try { fileHandler = new FileHandler("F:/WorkSpaceSpringBoot/AllLogTest/logs/jul.log"); } catch (IOException e) { throw new RuntimeException(e); } //进行关联 fileHandler.setFormatter(simpleFormatter); logger.addHandler(fileHandler); //2.日志记录输出 logger.severe("severe"); logger.warning("warning"); logger.info("info");//默认日志输出级别 logger.config("config"); logger.fine("fine"); logger.finer("finer"); logger.finest("finest"); } /** * 4、Logger对象的父子关系 * ①三个对象:RootLogger、loggerParent 、loggerChild * ②loggerParent.setUseParentHandlers(false);//关闭使用系统默认配置 * ③loggerChild.severe("severe");//日志记录输出 * 注意:由于loggerChild并没有setUseParentHandlers(false),故而此处loggerChild会默认使用loggerParent的自定义配置。 父子关系:由命名的层级决定,如com是com.stone的父对象。 * RootLogger名称:默认其name为""。 */ public static void log04(String path){ Logger loggerChild = Logger.getLogger("com.logtest"); Logger loggerParent = Logger.getLogger("com"); //默认按照 命名目录层级关系 来设置父子关系 System.out.println(loggerParent == loggerChild.getParent());//true //所有日志记录器的顶级父元素 LogManager$RootLogger,默认的name:""。 System.out.println("loggerParent's default parent: " + loggerParent.getParent() + ", name: " + loggerParent.getParent().getName()); //1.1.关闭系统默认配置 loggerParent.setUseParentHandlers(false); //1.2.自定义配置日志级别(关联处理器&转换器) //1.2.1.创建ConsoleHandler ConsoleHandler consoleHandler = new ConsoleHandler(); //1.2.2.创建简单格式转换对象 SimpleFormatter simpleFormatter = new SimpleFormatter(); //1.2.3.进行关联 consoleHandler.setFormatter(simpleFormatter); loggerParent.addHandler(consoleHandler); //1.3.设置日志具体级别 loggerParent.setLevel(Level.ALL); consoleHandler.setLevel(Level.ALL); //2.日志记录输出 //loggerChild会按照loggerParent设置的日志级别输出对应的日志 loggerChild.severe("severe"); loggerChild.warning("warning"); loggerChild.info("info");//默认日志输出级别 loggerChild.config("config"); loggerChild.fine("fine"); loggerChild.finer("finer"); loggerChild.finest("finest"); } /** * 5、加载自定义配置文件 * ①通过类加载器 读取配置文件 * ②创建LogManager对象 * ③通过LogManger加载配置文件 * ④创建日志输出类 * ⑤日志记录输出 */ public static void log05(String path){ //1.通过类加载器 读取配置文件 InputStream inputStream = JulTest.class.getClassLoader().getResourceAsStream("logging.properties"); //2.创建LogManager LogManager logManager = LogManager.getLogManager(); //3.通过LogManger加载配置文件 try { logManager.readConfiguration(inputStream); } catch (IOException e) { throw new RuntimeException(e); } //创建日志记录器 Logger logger = Logger.getLogger(path); //日志记录输出 logger.severe("severe"); logger.warning("warning"); logger.info("info");//默认日志输出级别 logger.config("config"); logger.fine("fine"); logger.finer("finer"); logger.finest("finest"); } }
2. log_jul_jcl: 通过jcl日志门面,使用jul方式的日志记录 commons-logging.properties (默认就是Jdk14Logger 此处可以不用配置)

import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class Jcl_JulTest { /** * jcl门面框架 指定实现 * 通过commons-logging.properties 进行实现框架配置 * org.apache.commons.logging.Log = org.apache.commons.logging.impl.Jdk14Logger * 默认就是 org.apache.commons.logging.impl.Jdk14Logger * JCL动态查找机制进行日志实例化,执行顺序为: * commons-logging.properties---->系统环境变量------->log4j--->jul--->simplelog---->nooplog */ public static void main(String[] args) { //使用日志门面实现 Log log = LogFactory.getLog(Jcl_JulTest.class); System.out.println(log.getClass()); log.info("JCL + Jul 日志门面 日志输出"); } }
<dependencies> <!-- 引入jcl 门面依赖 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> </dependencies>
3. log_jul_slf4j: 通过slf4j日志门面,使用jul方式的日志记录

import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Jul_Slf4jTest { public static void main(String[] args) { ////使用日志门面实现 Logger logger = LoggerFactory.getLogger(Jul_Slf4jTest.class); logger.error("error"); logger.warn("warn"); logger.info("info"); logger.debug("debug"); logger.trace("trace"); // 使用占位符输出日志信息 String name = "lucy"; Integer age = 18; logger.info("{}今年{}岁了!", name, age); // 将系统异常信息写入日志 try { int i = 1 / 0; } catch (Exception e) { // e.printStackTrace(); logger.info("出现异常:", e); } } }
<dependencies> <!-- slf4j 日志门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.7</version> </dependency> <!-- slf4j-jul 桥接器--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>2.0.5</version> </dependency> </dependencies>
4. log_log4j: log4j方式的日志记录 log4j.properties

import org.apache.log4j.Logger; public class Log4jTest { public static void main(String[] args) { //使用log4j日志直接实现 Logger logger = Logger.getLogger(Log4jTest.class.getName()); logger.info("log4j 单独日志框架"); } }
<dependencies> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
5. log_log4j_jcl: 通过jcl日志门面,使用log4j方式的日志记录 log4j.properties

import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class Log4j_Jcl { /** * log4j需要实用配置文件 log4j.properties * commons-logging.properties 指定jcl 实现接口 * @param args */ public static void main(String[] args) { //使用日志门面实现 Log log = LogFactory.getLog(Log4j_Jcl.class); System.out.println(log.getClass()); log.info("JCL日志门面 + log4j日志输出"); } }
<dependencies> <!-- 引入jcl 门面依赖 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <!-- log4j 依赖--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
6. log_log4j_slf4j:通过slf4j日志门面,使用log4j方式的日志记录 log4j.properties

import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Log4j_Slf4jTest { public static void main(String[] args) { ////使用日志门面实现 Logger logger = LoggerFactory.getLogger(Log4j_Slf4jTest.class); logger.debug("sef4j - log4j sef4j日志门面和log4j实现日志 配合"); } }
<dependencies> <!-- slf4j 日志门面 slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.7</version> </dependency> <!-- slf4j-log4j 桥接器--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>2.0.7</version> </dependency> <!-- log4j 核心依赖--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
7. log_log4j2: log4j2方式的日志记录 log4j2.xml

import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class Log4j2Test { public static void main(String[] args) { System.out.println("---------"); Logger logger = LogManager.getLogger("com.test.Log4j2Test"); logger.debug("单纯使用log4j2 进行输出"); } }
<dependencies> <!-- log4j2依赖代码 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.20.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.20.0</version> </dependency> <!-- 使用log4j2的异步日志需要的依赖 --> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.4</version> </dependency> </dependencies>
8. log_log4j2_jcl: 通过jcl日志门面,使用log4j2方式的日志记录 log4j2.xml

import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class Log4j2JclTest { public static void main(String[] args) { //使用日志门面实现 Log log = LogFactory.getLog(Log4j2JclTest.class); System.out.println(log.getClass()); log.info("JCL + Jul 日志门面 日志输出"); } }
<dependencies> <!-- 引入jcl 门面依赖 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <!-- log4j2与jcl 桥接--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jcl</artifactId> <version>2.20.0</version> </dependency> <!-- log4j2--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.20.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.20.0</version> </dependency> <!-- 使用log4j2的异步日志需要的依赖 --> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.4</version> </dependency> </dependencies>
9. log_log4j2_slf4j:通过slf4j日志门面,使用log4j2方式的日志记录 log4j2.xml

import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Log4j2_Slf4jTest { public static void main(String[] args) { ////使用日志门面实现 Logger logger = LoggerFactory.getLogger(Log4j2_Slf4jTest.class); logger.debug("sef4j日志门面 - log4j2实现日志 配合"); } }
<dependencies> <!-- slf4j 日志门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.7</version> </dependency> <!-- slf4j-log4j2 桥接器--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j2-impl</artifactId> <version>2.20.0</version> </dependency> <!-- log4j2--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.20.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.20.0</version> </dependency> <!-- 使用log4j2的异步日志需要的依赖 --> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.4</version> </dependency> </dependencies>
10. log_logback: 通过slf4j日志门面,使用logback方式的日志记录 logback.xml

import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 以下是 logback 的初始化步骤: * logback 会在类路径下寻找名为 logback-test.xml 的文件。 * 如果没有找到,logback 会继续寻找名为 logback.groovy 的文件。 * 如果没有找到,logback 会继续寻找名为 logback.xml 的文件。 * 如果没有找到,将会通过 JDK 提供的 ServiceLoader 工具在类路径下寻找文件 META-INFO/services/ch.qos.logback.classic.spi.Configurator,该文件的内容为实现了 Configurator 接口的实现类的全限定类名。 * 如果以上都没有成功,logback 会通过 BasicConfigurator 为自己进行配置,并且日志将会全部在控制台打印出来。 */ public class LogBackTest { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(LogBackTest.class.getName()); logger.info("logback 日志"); } }
<dependencies> <!-- slf4j 日志门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.7</version> </dependency> <!-- logback核心依赖 https://mvnrepository.com/artifact/ch.qos.logback/logback-core --> <!-- <dependency>--> <!-- <groupId>ch.qos.logback</groupId>--> <!-- <artifactId>logback-core</artifactId>--> <!-- <version>1.4.8</version>--> <!-- </dependency>--> <!-- 与slf4j的桥接器 https://mvnrepository.com/artifact/ch.qos.logback/logback-classic logback-classic 已包含 logback-core --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.4.8</version> </dependency> </dependencies>
11. log_jcl_to_slf4j_log4j: jcl门面实现转slf4j门面,log4j方式的日志记录 log4j.properties

import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class Jcl2Slf4jWithLog4j { public static void main(String[] args) { //使用日志门面实现 Log log = LogFactory.getLog(Jcl2Slf4jWithLog4j.class); System.out.println(log.getClass()); log.info("JCL门面 转slf4j门面 + log4j 日志输出"); } }
<dependencies> <!-- 引入jcl 门面依赖 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <!--=============================================================================--> <!-- 门面转换:jcl 转 slf4j 可以替换掉commons-logging--> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>2.0.7</version> </dependency> <!--=============================================================================--> <!-- slf4j 日志门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.7</version> </dependency> <!-- slf4j-log4j 桥接器--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>2.0.7</version> </dependency> <!-- log4j 核心依赖--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
12. log_jcl_to_slf4j_log4j2: jcl门面实现转slf4j门面,log4j2方式的日志记录 log4j2.xml

import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class Jcl2Slf4j { public static void main(String[] args) { //使用jcl日志门面实现 Log log = LogFactory.getLog(Jcl2Slf4j.class); System.out.println(log.getClass()); log.info("JCL门面 转slf4j门面 + log4j2 日志输出"); } }
<dependencies> <!-- 引入jcl 门面依赖 --> <!-- <dependency>--> <!-- <groupId>commons-logging</groupId>--> <!-- <artifactId>commons-logging</artifactId>--> <!-- <version>1.2</version>--> <!-- </dependency>--> <!--=============================================================================--> <!-- 门面转换:jcl 转 slf4j 可以替换掉commons-logging--> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>2.0.7</version> </dependency> <!--=============================================================================--> <!-- slf4j 日志门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.7</version> </dependency> <!-- slf4j-log4j2 桥接器--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j2-impl</artifactId> <version>2.20.0</version> </dependency> <!-- log4j2--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.20.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.20.0</version> </dependency> <!-- 使用log4j2的异步日志需要的依赖 --> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.4</version> </dependency> </dependencies>
13. log_jcl_to_slf4j_logback: jcl门面实现转slf4j门面,logback方式的日志记录 logback.xml

import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class Jcl2Slf4jWithLogback { public static void main(String[] args) { //使用jcl日志门面实现 Log log = LogFactory.getLog(Jcl2Slf4jWithLogback.class); System.out.println(log.getClass()); log.info("JCL门面 转slf4j门面 + logback 日志输出"); } }
<dependencies> <!-- 引入jcl 门面依赖 --> <!-- <dependency>--> <!-- <groupId>commons-logging</groupId>--> <!-- <artifactId>commons-logging</artifactId>--> <!-- <version>1.2</version>--> <!-- </dependency>--> <!-- 门面转换:jcl 转 slf4j 可以替换掉commons-logging--> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>2.0.7</version> </dependency> <!-- slf4j 日志门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.7</version> </dependency> <!-- logback核心依赖 https://mvnrepository.com/artifact/ch.qos.logback/logback-core --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.4.8</version> </dependency> <!-- 与slf4j的桥接器 https://mvnrepository.com/artifact/ch.qos.logback/logback-classic --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.4.8</version> </dependency> </dependencies>
14. log_jul_to_slf4j_log4j: jul方式 转slf4j门面,log4j(log4j2 和 logback方式省略测试)方式的日志记录 log4j.properties
注意:必须启用以下语句才能生效
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
import org.slf4j.bridge.SLF4JBridgeHandler; import java.util.logging.Level; import java.util.logging.Logger; public class Jul2Self4jWithLog4j { public static void main(String[] args) { log01(Jul2Self4jWithLog4j.class.getName()); } public static void log01(String path){ //jul实现 -> self4j门面 需要执行如下两句 //使用其他框架时,建议在入口类处的static{ }区执行,确保尽早初始化。 SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); //1.获取日志记录器对象 //命名:通常使用当前类的全限定类名(包名+类名) Logger logger = Logger.getLogger(path); System.out.println(logger.getClass()); //2.日志记录输出 //2.1.直接输出日志 logger.info("hello jul"); //2.2.设置级别 输出日志 logger.log(Level.INFO, "level info msg"); //2.3.通过占位符方式 输出变量值 String msg = "hello world"; Integer num = 123; logger.log(Level.INFO, "user message:{0}, {1}", new Object[]{msg, num}); } }
<dependencies> <!-- 门面转换:jul 转 slf4j https://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>2.0.7</version> </dependency> <!-- slf4j 日志门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.7</version> </dependency> <!-- slf4j-log4j 桥接器--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>2.0.7</version> </dependency> <!-- log4j 核心依赖--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
15. log_log4j_to_slf4j_logback: log4j方式 转slf4j门面,logback方式的日志记录 log4j.properties logback.xml
注意:使用log4j-over-slf4j取代log4j,这样log4j接口输出的日志就会通过log4j-over-slf4j路由到SLF4J上

import org.apache.log4j.Logger; public class Log4j2Slf4jWithLogback { public static void main(String[] args) { //使用log4j日志直接实现 Logger logger = Logger.getLogger(Log4j2Slf4jWithLogback.class.getName()); logger.info("log4j 转 slf4j+logback"); } }
<dependencies> <!--log4j 与 slf4j 桥接器--> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>2.0.7</version> </dependency> <!-- log4j这个日志框架删不删都可以,你只要能保证log4j的加载顺序在log4j-over-slf4j后即可。 因为log4j-over-slf4j这个适配器的工作原理是,内部提供了和log4j一模一样的api接口, 因此你在程序中调用log4j的api的时候,你必须想办法让其走适配器的api。 如果你删了log4j这个框架,那你程序里肯定是走log4j-over-slf4j这个组件里的api。 如果不删log4j,只要保证其在classpth里的顺序比log4j前即可!--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- slf4j 日志门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.7</version> </dependency> <!-- logback核心依赖 https://mvnrepository.com/artifact/ch.qos.logback/logback-core --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.4.8</version> </dependency> <!-- 与slf4j的桥接器 https://mvnrepository.com/artifact/ch.qos.logback/logback-classic logback-classic 已包含 logback-core --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.4.8</version> </dependency> </dependencies>
以是各种实现方式需要的配置类,其内容只为运行顺利而配置,这里不做讨论:
log4j.properties
#trace < debug < info < warn < error < fatal log4j.rootLogger=trace, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <!--status属性:用来指定log4j本身的打印日志的级别:OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL--> <Configuration status="INFO" name="MyApp"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} ===== %msg%n" /> </Console> <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{yyyy-MM-dd HH}.log"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <SizeBasedTriggeringPolicy size="500MB"/> </Policies> </RollingFile> <RollingFile name="RollingFile2" fileName="logs/app2.log" filePattern="logs/app2-%d{yyyy-MM-dd HH}.log"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <SizeBasedTriggeringPolicy size="500MB"/> </Policies> </RollingFile> </Appenders> <Loggers> <AsyncLogger name="com.Log4j2Test" level="trace" additivity="false"> <appender-ref ref="RollingFile"/> </AsyncLogger> <AsyncLogger name="RollingFile2" level="trace" additivity="false"> <appender-ref ref="RollingFile2"/> </AsyncLogger> <Root level="debug"> <AppenderRef ref="Console"/> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
logging.properties (jul配置)
# RootLogger 配置顶级父元素指定的默认处理器为: ConsoleHandler
handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler
# RootLogger 顶级父元素默认的日志级别为:ALL
.level= ALL
# 向日志文件输出的 handler 对象
# 指定日志文件输出路径:D:/logs/java%u.log
java.util.logging.FileHandler.pattern = F:/WorkSpaceSpringBoot/AllLogTest/logs/java%u.log
# 指定日志文件内容大小
java.util.logging.FileHandler.limit = 50000
# 指定日志文件数量
java.util.logging.FileHandler.count = 1
# 指定 handler 对象日志消息格式对象 默认为:XMLFormatter,此处修改为:SimpleFormatter
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
# 指定以追加的方式添加日志内容
java.util.logging.FileHandler.append = true
# 向控制台输出的 handler 对象
# 指定 handler 对象的日志级别
java.util.logging.ConsoleHandler.level = ALL
# 指定 handler 对象的日志消息格式对象 SimpleFormatter
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# 指定 handler 对象的字符集
java.util.logging.ConsoleHandler.encoding = UTF-8
# 指定日志消息格式
java.util.logging.SimpleFormatter.format = %1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%n
# 此处设置会使以 com.stone. 开头命名的 Logger 对象采用此配置
# 自定义 Logger 使用
# For example, set the com.stone logger to use ConsoleHandler as handlers
com.stone.handlers = java.util.logging.ConsoleHandler
# For example, set the com.stone logger to only log CONFIG
com.stone.level = CONFIG
# 关闭默认配置
com.stone.useParentHandlers = false
commons-logging.properties (jcl 门面用来指定适配器)
#默认是Jdk14Logger org.apache.commons.logging.Log = org.apache.commons.logging.impl.Jdk14Logger #org.apache.commons.logging.Log = org.apache.commons.logging.impl.Log4JLogger
提示:jul方式输出的日志是红色的,可以判断 jul 方式是否生效
最后的总结:使用logback + slf4j 进行日志框架处理,出自一人之手,衔接更好!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!