日志文件是用于记录系统操作事件的文件集合,可分为事件日志和消息日志。具有处理历史数据、诊断 问题的追踪以及理解系统的活动等重要作用。
在计算机中,日志文件是记录在操作系统或其他软件运行中发生的事件或在通信软件的不同用户之间的 消息的文件。记录是保持日志的行为。在最简单的情况下,消息被写入单个日志文件。
许多操作系统,软件框架和程序包括日志系统。广泛使用的日志记录标准是在因特网工程任务组 (IETF)RFC5424中定义的syslog。 syslog标准使专用的标准化子系统能够生成,过滤,记录和分析日 志消息。
软件开发中,我们经常需要去调试程序,做一些信息,状态的输出便于我们查询程序的运行状况。为了 让我们能够更加灵活和方便的控制这些调试的信息,所有我们需要专业的日志技术。java中寻找bug会 需要重现。调试也就是debug 可以在程序运行中暂停程序运行,可以查看程序在运行中的情况。日志主 要是为了更方便的去重现问题。
系统日志是记录系统中硬件、软件和系统问题的信息,同时还可以监视系统中发生的事件。用户可以通 过它来检查错误发生的原因,或者寻找受到攻击时攻击者留下的痕迹。系统日志包括系统日志、应用程 序日志和安全日志。
系统日志策略可以在故障刚刚发生时就向你发送警告信息,系统日志帮助你在最短的时间内发现问题。
系统日志是一种非常关键的组件,因为系统日志可以让你充分了解自己的环境。这种系统日志信息对于 决定故障的根本原因或者缩小系统攻击范围来说是非常关键的,因为系统日志可以让你了解故障或者袭 击发生之前的所有事件。为虚拟化环境制定一套良好的系统日志策略也是至关重要的,因为系统日志需 要和许多不同的外部组件进行关联。良好的系统日志可以防止你从错误的角度分析问题,避免浪费宝贵 的排错时间。另外一种原因是借助于系统日志,管理员很有可能会发现一些之前从未意识到的问题,在 几乎所有刚刚部署系统日志的环境当中。
问题:
因为软件系统发展到今天已经很复杂了,特别是服务器端软件,涉及到的知识,内容,问题太多。在某 些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业 务逻辑设计。而且框架一般是成熟,稳健的,他可以处理系统很多细节问题,比如,事务处理,安全 性,数据流控制等问题。还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它 是不断升级的,你可以直接享受别人升级代码带来的好处。
JUL(java util logging)、logback、log4j、log4j2
JCL(Jakarta Commons Logging)、slf4j( Simple Logging Facade for Java)
JCL、slf4j
JUL、logback、log4j、log4j2
JUL全称Java util Logging是java原生的日志框架,使用时不需要另外引用第三方类库,相对其他日志框 架使用方便,学习简单,能够在小型应用中灵活使用。

总结:
用户使用Logger来进行日志记录,Logger持有若干个Handler,日志的输出操作是由Handler完成的。 在Handler输出日志前,会经过Filter的过滤,判断哪些日志级别过滤放行哪些拦截,Handler会将日志内容输出到指定位置(日志文件、控制台等)。Handler在输出日志时会使用Layout,将输出内容进 行排版。
public void test1(){
//1.创建日志记录器对象
Logger logger = Logger.getLogger("com.linging.jul.JULTest");
//2.日志输出
logger.severe("severe msg");
logger.warning("warning msg");
logger.info("info msg"); //默认级别
logger.config("config msg");
logger.fine("fine msg");
logger.finer("finer msg");
logger.finest("finest msg");
logger.log(Level.ALL,"all msg");
//占位符输出
String s1 = "这是第一个参数";
String s2 = "这是第二个参数";
logger.log(Level.INFO,"info msg: {0},{1}",new Object[]{s1,s2});
}
在入门案例中,只输出了比默认级别高的日志信息,下面就来自定义日志级别配置。
//输出日志到控制台
public void test1() throws IOException {
//1.创建日志记录器对象
Logger logger = Logger.getLogger("com.linging.jul.JULTest");
//2.自定义日志级别
//2.1关闭系统日志默认配置
logger.setUseParentHandlers(false);
//2.2创建handler对象 输出到控制台
ConsoleHandler consoleHandler = new ConsoleHandler();
//2.3创建formatter对象
SimpleFormatter simpleFormatter = new SimpleFormatter();
//2.4进行关联
consoleHandler.setFormatter(simpleFormatter);
logger.addHandler(consoleHandler);
//2.5设置日志级别
logger.setLevel(Level.ALL);
consoleHandler.setLevel(Level.ALL);
//3.日志输出
logger.severe("severe msg");
logger.warning("warning msg");
logger.info("info msg"); //默认级别
logger.config("config msg");
logger.fine("fine msg");
logger.finer("finer msg");
logger.finest("finest msg");
}
public void test2() throws IOException {
//1.创建日志记录器对象
Logger logger = Logger.getLogger("com.linging.jul.JULTest");
//2.自定义日志级别
//2.1关闭系统日志默认配置
logger.setUseParentHandlers(false);
//2.3创建formatter对象
SimpleFormatter simpleFormatter = new SimpleFormatter();
//true 追加
//输出日志到文件
//目录不存在,不会自动创建
FileHandler fileHandler = new FileHandler("./java.log");
System.out.println(fileHandler);
//FileHandler fileHandler = new FileHandler("C:/Users/Linging/Desktop/java.log",true);
fileHandler.setFormatter(simpleFormatter);
logger.addHandler(fileHandler);
//设置日志级别
logger.setLevel(Level.ALL);
fileHandler.setLevel(Level.ALL);
//输出日志
logger.severe("severe msg");
logger.warning("warning msg");
logger.info("info msg"); //默认级别
logger.config("config msg");
logger.fine("fine msg");
logger.finer("finer msg");
logger.finest("finest msg");
}
JUL中Logger之间存在父子关系,这种父子关系通过树状结构存储,JUL在初始化时会创建一个顶层 RootLogger作为所有Logger父Logger,存储上作为树状结构的根节点。并父子关系通过路径来关联。
public void test1 () throws IOException {
//日志记录器对象父子关系
Logger logger = Logger.getLogger("com.linging.jul.JULTest");
Logger logger1 = Logger.getLogger("com.linging.jul");
System.out.println(logger.getParent() == logger1);
// 所有日志记录器对象的顶级父元素 class为java.util.logging.LogManager$RootLogger name为"
System.out.println("logger1 parent:" + logger1.getParent() + ",name:" + logger1.getParent().getName());
//2.自定义日志级别
//2.1关闭系统日志默认配置
logger1.setUseParentHandlers(false);
//2.2创建handler对象 输出到控制台
ConsoleHandler consoleHandler = new ConsoleHandler();
//2.3创建formatter对象
SimpleFormatter simpleFormatter = new SimpleFormatter();
//2.4进行关联
consoleHandler.setFormatter(simpleFormatter);
logger1.addHandler(consoleHandler);
//2.5设置日志级别
logger1.setLevel(Level.ALL);
consoleHandler.setLevel(Level.ALL);
//3.日志输出
logger1.severe("severe msg");
logger1.warning("warning msg");
logger1.info("info msg"); //默认级别
logger1.config("config msg");
logger1.fine("fine msg");
logger1.finer("finer msg");
logger1.finest("finest msg");
}
默认配置文件路径$JAVAHOME\jre\lib\logging.properties
public void test2() throws IOException {
//去读自定义配置文件
InputStream is = JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
System.out.println(is);
//获取日志管理器
LogManager logManager = LogManager.getLogManager();
//通过日志管理器加载配置文件
logManager.readConfiguration(is);
Logger logger = Logger.getLogger("com.linging.jul.JULTest");
logger.severe("severe msg");
logger.warning("warning msg");
logger.info("info msg"); //默认级别
logger.config("config msg");
logger.fine("fine msg");
logger.finer("finer msg");
logger.finest("finest msg");
}
logging.properties
#RootLogger 使用的处理器(获取时设置) 可以设置多个
handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler
#RootLogger日志等级
.level= ALL
#文件处理器
#输出日志文件路径,目录不存在,不会自动创建
java.util.logging.FileHandler.pattern = ./logs/java%u.log
#输出日志文件限制大小 (50000字节)
java.util.logging.FileHandler.limit = 50000
#输出日志文件限制个数 1个
java.util.logging.FileHandler.count = 1
#输出日志格式
#java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
#输出日志文件,是否追加
java.util.logging.FileHandler.append = true
#指定编码
java.util.logging.FileHandler.encoding = UTF-8
#控制台处理器
#输出日志级别
java.util.logging.ConsoleHandler.level = ALL
#输出日志格式
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
#com.xyz.foo.level = SEVERE

Log4j是Apache下的一款开源的日志框架,通过在项目中使用 Log4J,我们可以控制日志信息输出到控制台、文件、甚至是数据库中。我们可以控制每一条日志的输出格式,通过定义日志的输出级别,可以 更灵活的控制日志的输出过程。方便项目的调试。
导入依赖:
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
public void test(){
//初始化系统配置,不需要配置文件
BasicConfigurator.configure();
//创建日志记录器对象
Logger logger = Logger.getLogger(Log4jTest.class);
//输出日志 六个日志级别
logger.fatal("严重错误,一般会造成系统崩溃和程序终止运行");
logger.error("错误信息,但不会影响系统运行");
logger.warn("警告信息,可能会发生问题");
logger.info("程序运行信息,数据库的连接、网络、IO操作等");
logger.debug("调试信息,一般在开发阶段使用,记录程序的变量、参数等");
logger.trace("追踪信息,记录程序的所有流程信息");
}
每个Logger都被了一个日志级别(log level),用来控制日志信息的输出。日志级别从高到低分 为:
还有两个特殊的级别:
注:一般只使用4个级别,优先级从高到低为 ERROR > WARN > INFO > DEBUG
Log4J 主要由 Loggers (日志记录器)、Appenders(输出端)和 Layouts(日志格式化器)组成。其中 Loggers 控制日志的输出级别与日志是否输出
Appenders 指定日志的输出方式(输出到控制台、文件 等)
Layouts 控制日志信息的输出格式。
日志记录器,负责收集处理日志记录,实例的命名就是类“XX”的full quailied name(类的全限定名), Logger的名字大小写敏感,其命名有继承机制:例如:name为org.apache.commons的logger会继承 name为org.apache的logger。
Log4J中有一个特殊的logger叫做“root”,他是所有logger的根,也就意味着其他所有的logger都会直接 或者间接地继承自root。root logger可以用Logger.getRootLogger()方法获取。
但是,自log4j 1.2版以来, Logger 类已经取代了 Category 类。对于熟悉早期版本的log4j的人来说, Logger 类可以被视为 Category 类的别名。

Appender 用来指定日志输出到哪个地方,可以同时指定日志的输出目的地。Log4j 常用的输出目的地 有以下几种:
| 输出端类型 | 作用 |
|---|---|
| ConsoleAppender | 将日志输出到控制台 |
| FileAppender | 将日志输出到文件中 |
| DailyRollingFileAppender | 将日志输出到一个日志文件,并且每天输出到一个新的文件 |
| RollingFileAppender | 将日志信息输出到一个日志文件,并且指定文件的尺寸,当文件大 小达到指定尺寸时,会自动把文件改名,同时产生一个新的文件 |
| JDBCAppender | 把日志信息保存到数据库中 |
布局器 Layouts用于控制日志输出内容的格式,让我们可以使用各种需要的格式输出日志。Log4j常用 的Layouts:
| 格式化器类型 | 作用 |
|---|---|
| HTMLLayout | 格式化日志输出为HTML表格形式 |
| SimpleLayout | 简单的日志输出格式化,打印的日志格式为(info - message) |
| PatternLayout | 最强大的格式化期,可以根据自定义格式输出日志,如果没有指定转换格式,就是用默认的转换格式 |
* log4j 采用类似 C 语言的 printf 函数的打印格式格式化日志信息,具体的占位符及其含义如下: %m 输出代码中指定的日志信息
%p 输出优先级,及 DEBUG、INFO 等
%n 换行符(Windows平台的换行符为 "\n",Unix 平台为 "\n")
%r 输出自应用启动到输出该 log 信息耗费的毫秒数
%c 输出打印语句所属的类的全名
%t 输出产生该日志的线程全名
%d 输出服务器当前时间,默认为 ISO8601,也可以指定格式,如:%d{yyyy年MM月dd日 HH:mm:ss} %l 输出日志时间发生的位置,包括类名、线程、及在代码中的行数。如: Test.main(Test.java:10) %F 输出日志消息产生时所在的文件名称
%L 输出代码中的行号
%% 输出一个 "%" 字符
* 可以在 % 与字符之间加上修饰符来控制最小宽度、最大宽度和文本的对其方式。如:
%5c 输出category名称,最小宽度是5,category<5,默认的情况下右对齐
%-5c 输出category名称,最小宽度是5,category<5,"-"号指定左对齐,会有空格
%.5c 输出category名称,最大宽度是5,category>5,就会将左边多出的字符截掉,<5不 会有空格 %20.30c category名称<20补空格,并且右对齐,>30字符,就从左边交远销出的字符截掉
控制台,文件,数据库
待完善。。。。。
全称为Jakarta Commons Logging,是Apache提供的一个通用日志API。
它是为 "所有的Java日志实现"提供一个统一的接口,它自身也提供一个日志的实现,但是功能非常常弱(SimpleLog)。所以一般不会单独使用它。他允许开发人员使用不同的具体日志实现工具: Log4j, Jdk 自带的日志(JUL) JCL 有两个基本的抽象类:Log(基本记录器)和LogFactory(负责创建Log实例)。

导入依赖:
<dependency>
<groupId>commons-logginggroupId>
<artifactId>commons-loggingartifactId>
<version>1.2version>
dependency>
public void test(){
//创建日志记录器
Log log = LogFactory.getLog(this.getClass());
//输出日志
log.fatal("fatal msg");
log.error("error msg");
log.warn("waring msg");
log.info("info msg");
log.debug("debug msg");
log.trace("trace msg");
}
我们为什么要使用日志门面?
面向接口开发,不再依赖具体的实现类。减少代码的耦合
项目通过导入不同的日志实现类,可以灵活的切换日志框架
统一API,方便开发者学习和使用
统一配置便于项目日志的管理
1.通过LogFactory动态加载实现类。

2.日志门面支持的日志实现数组。
private static final String[] classesToDiscover = {
"org.apache.commons.logging.impl.Log4JLogger",
"org.apache.commons.logging.impl.Jdk14Logger",
"org.apache.commons.logging.impl.Jdk13LumberjackLogger",
"org.apache.commons.logging.impl.SimpleLog"
};
3.获取具体的日志实现
for(int i=0; i<classesToDiscover.length && result == null; ++i) {
result = createLogFromClass(classesToDiscover[i], logCategory, true);
}
缺点:
只支持上述日志实现,如果需要使用其他的日志实现,需要修改源代码。
当我们的系统变的更加复杂的时候,我们的日志就容易发生混乱。随着系统开发的进行,可能会更新不 同的日志框架,造成当前系统中存在不同的日志依赖,让我们难以统一的管理和控制。就算我们强制要 求所有的模块使用相同的日志框架,系统中也难以避免使用其他类似spring,mybatis等其他的第三方框 架,它们依赖于我们规定不同的日志框架,而且他们自身的日志系统就有着不一致性,依然会出来日志 体系的混乱。
所以我们需要借鉴JDBC的思想,为日志系统也提供一套门面,那么我们就可以面向这些接口规范来开 发,避免了直接依赖具体的日志框架。这样我们的系统在日志中,就存在了日志的门面和日志的实现。
常见的日志门面 : JCL、slf4j
常见的日志实现: JUL、log4j、logback、log4j2
日志门面和日志实现的关系:

日志框架出现的历史顺序:
log4j -->JUL–>JCL–> slf4j --> logback --> log4j2
简单日志门面(Simple Logging Facade For Java) SLF4J主要是为了给Java日志访问提供一套标准、规范 的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如log4j和logback等。 当然slf4j自己也提供了功能较为简单的实现,但是一般很少用到。对于一般的Java项目而言,日志框架 会选择slf4j-api作为门面,配上具体的实现框架(log4j、logback等),中间使用桥接器完成桥接。
官方网站: https://www.slf4j.org/
SLF4J是目前市面上流行的日志门面。现在的项目中,基本上都是使用SLF4J作为我们的日志系统。
SLF4J日志门面主要提供两大功能:
1. 日志框架的绑定
2. 日志框架的桥接
导入依赖:
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>1.7.30version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-simpleartifactId>
<version>1.7.28version>
dependency>
编写代码:
private final static Logger logger = LoggerFactory.getLogger(SLF4JTest.class);
@Test
public void test(){
//使用日志信息
logger.error("error msg");
logger.warn("warn msg");
logger.info("info msg"); //默认
logger.debug("debug msg");
logger.trace("trace msg");
//使用占位符
logger.info("错误信息: {},{}","张三","你完了");
}
* 1. 使用SLF4J框架,可以在部署时迁移到所需的日志记录框架。
* 2. SLF4J提供了对所有流行的日志框架的绑定,例如log4j,JUL,Simple logging和NOP。因此可以 在部署时切换到任何这些流行的框架。
* 3. 无论使用哪种绑定,SLF4J都支持参数化日志记录消息。由于SLF4J将应用程序和日志记录框架分离, 因此可以轻松编写独立于日志记录框架的应用程序。而无需担心用于编写应用程序的日志记录框架。
* 4. SLF4J提供了一个简单的Java工具,称为迁移器。使用此工具,可以迁移现有项目,这些项目使用日志 框架(如Jakarta Commons Logging(JCL)或log4j或Java.util.logging(JUL))到SLF4J。
如前所述,SLF4J支持各种日志框架。SLF4J发行版附带了几个称为“SLF4J绑定”的jar文件,每个绑定对应 一个受支持的框架。
使用slf4j的日志绑定流程:
通过maven引入常见的日志实现框架:
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>1.7.27version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>1.7.27version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-jdk14artifactId>
<version>1.7.27version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-jclartifactId>
<version>1.7.27version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-nopartifactId>
<version>1.7.27version>
dependency>
要切换日志框架,只需替换类路径上的slf4j绑定。例如,要从java.util.logging切换到log4j,只需将 slf4j-jdk14-1.7.27.jar替换为slf4j-log4j12-1.7.27.jar即可。
SLF4J不依赖于任何特殊的类装载。实际上,每个SLF4J绑定在编译时都是硬连线的, 以使用一个且只有 一个特定的日志记录框架。例如,slf4j-log4j12-1.7.27.jar绑定在编译时绑定以使用log4j。在您的代码 中,除了slf4j-api-1.7.27.jar之外,您只需将您选择的一个且只有一个绑定放到相应的类路径位置。不要 在类路径上放置多个绑定。以下是一般概念的图解说明。

通常,您依赖的某些组件依赖于SLF4J以外的日志记录API。您也可以假设这些组件在不久的将来不会切 换到SLF4J。为了解决这种情况,SLF4J附带了几个桥接模块,这些模块将对log4j,JCL和 java.util.logging API的调用重定向,就好像它们是对SLF4J API一样。
桥接解决的是项目中日志的遗留问题,当系统中存在之前的日志API,可以通过桥接转换到slf4j的实现

如果我们要使用SLF4J的桥接器,替换原有的日志框架,那么我们需要做的第一件事情,就是删除掉原 有项目中的日志框架的依赖。然后替换成SLF4J提供的桥接器。
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>log4j-over-slf4jartifactId>
<version>1.7.27version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>jul-to-slf4jartifactId>
<version>1.7.27version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>jcl-over-slf4jartifactId>
<version>1.7.27version>
dependency>
注意问题:
待完善。。。。
Logback是由log4j创始人设计的另一个开源日志组件,性能比log4j要好。
官方网站:https://logback.qos.ch/index.html
Logback主要分为三个模块:
后续的日志代码都是通过SLF4J日志门面搭建日志系统,所以在代码是没有区别,主要是通过修改配置 文件和pom.xml依赖 。
待续。。。。
Apache Log4j 2是对Log4j的升级版,参考了logback的一些优秀的设计,并且修复了一些问题,因此带 来了一些重大的提升,主要有:
官网: https://logging.apache.org/log4j/2.x/
目前市面上主流的日志门面就是SLF4J,虽然Log4j2也是日志门面,因为它的日志实现功能非常强 大,性能优越。所以大家一般还是将Log4j2看作是日志的实现,Slf4j + Log4j2应该是未来的大势所趋。
导入依赖:
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-apiartifactId>
<version>2.11.1version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-coreartifactId>
<version>2.11.1version>
dependency>
springboot框架在企业中的使用越来越普遍,springboot日志也是开发中常用的日志系统。springboot 默认就是使用SLF4J作为日志门面,logback作为日志实现来记录日志。
springboot中的日志:
<dependency>
<artifactId>spring-boot-starter-loggingartifactId>
<groupId>org.springframework.bootgroupId>
dependency>
依赖关系图:

总结:
void loggingTest() {
//springboot默认的日志记录器
Logger logger = LoggerFactory.getLogger(this.getClass());
//打印日志
logger.error("error msg");
logger.warn("warn msg");
logger.info("info msg"); //默认级别
logger.debug("debug msg");
logger.trace("trace msg");
}
properties:
#自定义logger对象日志级别
logging.level.com.linging=trace
#指定日志在控制台的输出格式
logging.pattern.console=[%-5level] %d{yyyy-MM-dd HH:mm:ss} %c [%thread] =======%msg %n
#指定日志的输出文件路径
logging.file=log/springboot.log
#指定日志文件的输出目录,代替上述淘汰路径,默认名字为spring.log
#logging.file.path=log/
#指定日志的输出文件的格日志式
logging.pattern.file=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
或yml
logging:
level:
com.linging: trace #自定义logger对象日志级别
pattern:
console: '[%-5level] %d{yyyy-MM-dd HH:mm:ss} %c [%thread] =======%msg %n' #指定在控制台输出的日志格式
file: '%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n'
file: log/springboot.log #指定日志文件的保存位置
给类路径下放上每个日志框架自己的配置文件;SpringBoot就不使用默认配置的了
| 日志框架 | 配置文件 |
|---|---|
| Logback | logback-spring.xml , logback.xml |
| Log4j2 | log4j2-spring.xml , log4j2.xml |
| JUL | logging.properties |
logback.xml:直接就被日志框架识别了。
加载优先顺序:logback.xml > application.properties > logback-spring.xml
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-log4j2artifactId>
dependency>
| 日志框架 | 配置文件 |
|---|---|
| Logback | logback-spring.xml , logback.xml |
| Log4j2 | log4j2-spring.xml , log4j2.xml |
| JUL | logging.properties |
logback.xml:直接就被日志框架识别了。
加载优先顺序:logback.xml > application.properties > logback-spring.xml
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-log4j2artifactId>
dependency>