spring引入log4j2日志框架
Posted 技术趋势
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring引入log4j2日志框架相关的知识,希望对你有一定的参考价值。
log4j2是什么?
可参考:https://baike.baidu.com/item/log4j/480673?fr=aladdin
log4j2可以用干什么?解决什么问题?
API文档:http://logging.apache.org/log4j/2.x/log4j-api/apidocs/index.html
log4j、slf4j、log4j2、logback之间的关系
相关配置说明
Appenders
Appender负责将LogEvents传递到目的地。每个Appender都必须实现Appender接口。大多数Appender继承自AbstractAppender,它增加了Lifecycle和Filterable支持。生命周期允许组件在配置完成后完成初始化并在关闭期间执行清理。Filterable接口允许组件附加过滤器,在事件处理期间对其进行筛选。Appender通常只负责将事件数据写入目标目标。在大多数情况下,他们将格式化事件的责任委托给布局。一些appender包装其他appender,以便他们可以修改LogEvent,处理Appender中的故障,根据高级Filter条件将事件路由到从属Appender
(1)AsyncAppender:引用其他Appender,被引用的Appender可以做到异步输出日志。
(2)CassandraAppender:可以将消息写入Cassandra数据库。
(3)ConsoleAppender:日志写入到标准输出,如System.out或System.error
(4)FailoverAppender:引用一组Appender,如果主的Appender失败则备用Appender开始起作用,直到主Appender恢复正常。
(5)FileAppender:将日志写入文件,比较常用。
(6)FlumeAppender:将日志以event的形式写入flume。
有三种模式:
a.远程客户端模式:模拟flume远程客户端,以avro_event的方式向agent发送消息。
b.内置flume agent模式:直接将event写入flume channel。
c.persist模式:将event写入本地BerkeleyDB,然后通过异步的方式将event发送到flume。
(7)JDBCAppender:使用JDBC连接将数据写入传统数据库。
(8)JMS Appender:将格式化后的日志写入JMS Destination。
(9)HttpAppender:发送日志到一个Http服务,必须使用Layout来格式化日志。
(10)KafkaAppender:将数据发送到kafka的topic,log4j的event对应kafka的record。
(11)MemoryMappedFileAppender:是一种特殊的日志写入方式,将日志写入内存以减少读写磁盘带来的IO开销,提升性能。
(12)NoSQLAppender:可以将数据写入nosql数据库,目前支持MongoDB和CouchDb。
(13)RandomAccessFileAppender:和FileAppender类似,但是使用了ByteBuffer+RandomAccessFile的方式来代替BufferedOutputStream
(14)RewriteAppender:允许LogEvent在其他appender处理之前先由RewriteAppender处理。
(15)RollingFileAppender:配置文件滚动生成策略,按照策略生成新的日志文件。
(16)RollingRandomAccessFileAppender:和RollingFileAppender类似,使用了ByteBuffer+RandomAccessFile的方式代替BufferedOutputStream。
(17)RoutingAppender:路由appender,可以分发Logevent到多个子Appender。
(18)SMTPAppender:将日志以邮件的形式发送,用在错误监控或者报警上。
(19)SocketAppender:将logevent发送到远程机器上,可以使用TCP或者UDP协议。
Layout
layout是指输出Logevent的布局,常见的比如输出日志的级别、时间、类名、线程等信息。Log4j2支持的Layout有如下几种:
(1)CSV Layouts。日志输出为csv文件,如log.info(a,b,c)会输出到csv文件对应的三列。
(2)HTML Layout。将日志输出为html页面,每个Logevent对应table里面的一行。
(3)JSON Layout。将日志输出为json格式。
(4)Pattern Layout。较为常用,通过使用一些匹配规则来确定日志输出格式。
(5)RFC5424 Layout。消息型的Appender经常用这种layout。
(6)Serialized Layout。使用java自身的序列化工具将Logevent序列化成byte array,但因为java固有的安全性问题,这种方式不再被推荐。
(7)Syslog Layout。将日志格式化为BSD syslog格式。
(8)XML Layout。格式化为xml。
配置文件优先级
log4j2.properties>log4j2.yaml>log4j2.json>log4j2.xml>defaultConfiguration
代码下载:https://gitee.com/hong99/spring/issues/I1N1DF
代码实现
项目代码结构(非spring纯log4j2)
引入相关JAR包(版本为最新)
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.3</version>
</dependency>
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* @Auther: csh
* @Date: 2020/7/26 14:17
* @Description:纯log4j2打印
*/
public class Log4j2App {
private static final Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
public static void main(String[] args) {
logger.trace("trace message");
logger.debug("debug message");
logger.info("info message");
logger.warn("warn message");
logger.error("error message");
logger.fatal("fatal message");
}
}
结果
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
15:22:53.174 [main] ERROR - error message
15:22:53.176 [main] FATAL - fatal message
由于上面没有配置log4j2的相关配置,所以打印了 ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
简单配置文件(基于File)
simple-log4j.xml
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
/**
* @Auther: csh
* @Date: 2020/7/29 15:58
* @Description:通过java读取配置文件
*/
public class SimpleXmiLog4j {
public static void main(String[] args) throws Exception{
//TODO 注意该路基在每台电脑上面可能不一样!
File file =new File("D:\ideaWorkSpace\spring\src\main\resources\log4j\simple-log4j.xml");
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
final ConfigurationSource source = new ConfigurationSource(in);
Configurator.initialize(null, source);
Logger logger = LogManager.getLogger("myLogger");
logger.trace("trace message");
logger.debug("debug message");
logger.info("info message");
logger.warn("warn message");
logger.error("error message");
logger.fatal("fatal message");
}
}
结果
15:59:59.491 [main] INFO myLogger - info message
15:59:59.494 [main] WARN myLogger - warn message
15:59:59.495 [main] ERROR myLogger - error message
15:59:59.495 [main] FATAL myLogger - fatal message
简单配置文件(基于xml的简单配置)
项目结构
导入maven包
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.13.3</version>
</dependency>
simple-log4j.xml
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<!--将系统打印所有日志-->
<Logger name="com.hong" level="DEBUG">
<AppenderRef ref="Console" />
</Logger>
<Logger name="org.springframework" level="info">
<AppenderRef ref="Console" />
</Logger>
<Root level="debug">
<!--这儿为trace表示什么都可以打印出来了,其他几个级别分别为:TRACE、DEBUG、INFO、WARN、ERROR和FATAL -->
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
配置 web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1" metadata-complete="true">
<display-name>Spring MVC Application</display-name>
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>classpath:log4j/simple-log4j.xml</param-value>
</context-param>
<!-- log4j2-begin -->
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<!-- log4j2-end -->
<servlet>
<servlet-name>HelloWeb</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloWeb</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
public class HomeController {
private static Logger log = LogManager.getLogger(HomeController.class.getName());
public String home(ModelMap model) {
log.info("进入了首页!");
model.addAttribute("message","Hello home");
return "home";
}
}
14:45:28.468 [http-nio-80-exec-1] INFO com.hong.spring.mvc.controller.HomeController - 进入了首页!
14:45:28.468 [http-nio-80-exec-1] INFO com.hong.spring.mvc.controller.HomeController - 进入了首页!
14:45:29.143 [http-nio-80-exec-2] INFO com.hong.spring.mvc.controller.HomeController - 进入了首页!
14:45:29.143 [http-nio-80-exec-2] INFO com.hong.spring.mvc.controller.HomeController - 进入了首页!
14:45:29.473 [http-nio-80-exec-3] INFO com.hong.spring.mvc.controller.HomeController - 进入了首页!
14:45:29.473 [http-nio-80-exec-3] INFO com.hong.spring.mvc.controller.HomeController - 进入了首页!
将日志写入文件中
新增log4j2-now.xml(将日志写入d盘中)
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<Configuration status="WARN" monitorInterval="30">
<!--全局属性-->
<Properties>
<Property name="APP_NAME">spring</Property>
<!--设置日志文件存储路径为tomcat/logs/${APP_NAME}-->
<Property name="LOG_FILE_PATH">D:/logs/${APP_NAME}</Property>
<!--<Property name="LOG_FILE_PATH">./logs/${APP_NAME}</Property>-->
<!--设置日志输出格式-->
<Property name="PATTERN_FORMAT">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n</Property>
</Properties>
<!--配置输出源-->
<Appenders>
<!--输出到控制台-->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${PATTERN_FORMAT}"/>
</Console>
<File name="applicationLog" fileName="${LOG_FILE_PATH}/MyTestLog.txt" immediateFlush="false" append="true">
<PatternLayout pattern="%d{yy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</File>
<!--输出info日志到文件,filePattern旧日志另存文件名-->
<RollingFile name="RollingInfoFile" fileName="${LOG_FILE_PATH}/info.log"
filePattern="${LOG_FILE_PATH}/$${date:yyyyMM}/info-%d{yyyyMMdd}-%i.log.gz">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<Filters>
<ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<pattern>${PATTERN_FORMAT}</pattern>
</PatternLayout>
<Policies>
<!-- rollover on startup, daily and when the file reaches 10 MegaBytes -->
<!--当系统重启/日期更新/超过100M将会覆盖文件-->
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
<!--输出警告日志到文件-->
<RollingFile name="RollingWarnFile" fileName="${LOG_FILE_PATH}/warn.log"
filePattern="${LOG_FILE_PATH}/$${date:yyyyMM}/warn-%d{yyyyMMdd}-%i.log.gz">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<Filters>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<pattern>${PATTERN_FORMAT}</pattern>
</PatternLayout>
<Policies>
<!-- rollover on startup, daily and when the file reaches 10 MegaBytes -->
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
<!--输出错误日志到文件-->
<RollingFile name="RollingErrorFile" fileName="${LOG_FILE_PATH}/error.log"
filePattern="${LOG_FILE_PATH}/$${date:yyyyMM}/error-%d{yyyyMMdd}-%i.log.gz">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<pattern>${PATTERN_FORMAT}</pattern>
</PatternLayout>
<Policies>
<!-- rollover on startup, daily and when the file reaches 10 MegaBytes -->
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<Logger name="org.springframework" level="INFO"/>
<Logger name="org.mybatis" level="INFO"/>
<Logger name="com.hong.spring" level="info" additivity="true">
<appender-ref ref="applicationLog" />
</Logger>
<!-- LOG everything at INFO level -->
<Root level="ALL">
<AppenderRef ref="applicationLog" />
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingInfoFile"/>
<AppenderRef ref="RollingWarnFile"/>
<AppenderRef ref="RollingErrorFile"/>
</Root>
</Loggers>
</Configuration>
修改web.xml
<context-param>
<param-name>log4jConfiguration</param-name>
<!--简单配置-->
<!--<param-value>classpath:log4j/simple-log4j.xml</param-value>-->
<!--较全配置-->
<param-value>classpath:log4j/log4j2-now.xml</param-value>
</context-param>
结果
[2020-07-31 03:17:39,714] Artifact spring:war: Artifact is deployed successfully
[2020-07-31 03:17:39,714] Artifact spring:war: Deploy took 6,880 milliseconds
2020-07-31 15:17:40.019 INFO com.hong.spring.mvc.controller.HomeController 17 home - 进入了首页!
2020-07-31 15:17:40.041 ERROR com.hong.spring.mvc.controller.HomeController 18 home - error进入了首页!
2020-07-31 15:17:40.649 INFO com.hong.spring.mvc.controller.HomeController 17 home - 进入了首页!
2020-07-31 15:17:40.650 ERROR com.hong.spring.mvc.controller.HomeController 18 home - error进入了首页!
2020-07-31 15:17:40.933 INFO com.hong.spring.mvc.controller.HomeController 17 home - 进入了首页!
2020-07-31 15:17:40.934 ERROR com.hong.spring.mvc.controller.HomeController 18 home - error进入了首页!
代码下载:https://gitee.com/hong99/spring/issues/I1N1DF
最后
相关文献:
http://logging.apache.org/
https://blog.csdn.net/edward0830ly/article/details/8250412
https://juejin.im/post/5c11c831e51d4511624d1b59
http://www.slf4j.org/manual.html
以上是关于spring引入log4j2日志框架的主要内容,如果未能解决你的问题,请参考以下文章