(日志框架之log4j2的使用) log4j2概述 log4j2是Apache基金会下的日志框架,它是对log4j的升级版,提供了更好的性能和扩展性。 主要特性: 1.高性能:Log4j2采用异步写入和零拷贝技术,提供了
(日志框架之log4j2的使用)
log4j2概述
log4j2是Apache基金会下的日志框架,它是对log4j的升级版,提供了更好的性能和扩展性。
主要特性:
1.高性能:Log4j2采用异步写入和零拷贝技术,提供了比其他日志框架更高的性能。 2.灵活的配置:Log4j2支持多种配置方式,包括XML、JSON、YAML等格式,并且可以实现动态配置和热更新。 3.扩展性:Log4j2提供了插件机制,允许开发者自定义Appender、Layout、Filter等组件来扩展其功能。 4.多种输出目标:Log4j2支持多种输出目标,包括控制台、文件、数据库、网络等,可以满足不同场景下的需求。 5.异常处理:Log4j2可以捕获并记录异常信息,并提供了可定制的异常处理器,方便开发者对异常信息进行处理。 6.支持日志级别:Log4j2支持多个日志级别,包括TRACE、DEBUG、INFO、WARN、ERROR、FATAL,可以根据需求来选择合适的级别。 7.上下文信息:Log4j2可以记录上下文信息,如线程ID、请求ID等,方便排查问题。官网:https://logging.apache.org/log4j/2.x/index.html
GitHub: https://github.com/apache/logging-log4j2
Log4j2的基本使用
目前市面上最主流的日志门面是SLF4J,虽然Log4j2也是日志门面,因为它的日志实现功能非常强大,性能优越。所以大家一般还是将Log4j2看作是日志的实现,使用Slf4j + Log4j2组合。
引入依赖
<!--log4j2日志门面--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.11.1</version> </dependency> <!--log4j2日志实现--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.11.1</version> </dependency>测试代码
public class Log4j2 { //定义日志记录器对象 public static final Logger LOGGER = LogManager.getLogger(Log4j2.class); @Test public void test() { LOGGER.fatal("fatal"); LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("inf"); LOGGER.debug("debug"); LOGGER.trace("trace"); } }有条ERROR 日志,是因为没有添加日志配置文件
ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2 19:35:21.484 [main] FATAL cn.ybzy.Log4j2 - fatal 19:35:21.488 [main] ERROR cn.ybzy.Log4j2 - error使用slf4j作为日志的门面,使用log4j2作为日志的实现
<!--log4j2日志实现--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.11.1</version> </dependency> <!--使用slf4j作为日志门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.26</version> </dependency> <!--使用log4j2的适配器进行绑定--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.9.1</version> </dependency>Log4j2配置
<?xml version="1.0" encoding="UTF-8"?> <!--tatus:日志框架输出的日志级别 monitorInterval:自动加载配置文件的间隔时间,不低于 5 秒--> <Configuration status="debug" monitorInterval="5"> <!--属性配置管理--> <properties> <property name="LOG_HOME">d:/logs</property> </properties> <!--日志处理--> <Appenders> <!--控制台输出appender SYSTEM_OUT:黑色字体 SYSTEM_ERR:红色字体--> <Console name="Console" target="SYSTEM_ERR"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n"/> </Console> <!--日志文件输出 appender--> <File name="file" fileName="${LOG_HOME}/myfile.log"> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %m%n"/> </File> <Async name="Async"> <AppenderRef ref="file"/> </Async> <!--使用随机读写刘的日志文件输出 appender,性能提高--> <RandomAccessFile name="accessFile" fileName="${LOG_HOME}/myAcclog.log"> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %m%n"/> </RandomAccessFile> <!--按照一定规则拆分的日志文件的 appender--> <RollingFile name="rollingFile" fileName="${LOG_HOME}/myrollog.log" filePattern="${LOG_HOME}/$${date:yyyy-MM-dd}/myrollog-%d{yyyy-MM-dd-HH-mm}-%i.log"> <!--日志级别过滤器--> <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/> <!--日志消息格式--> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %msg%n"/> <Policies> <!--在系统启动时,触发拆分规则,产生一个新的日志文件--> <OnStartupTriggeringPolicy/> <!--按照文件大小拆分,10MB --> <SizeBasedTriggeringPolicy size="10 MB"/> <!--按照时间节点拆分,规则根据filePattern定义的--> <TimeBasedTriggeringPolicy/> </Policies> <!--在同一个目录下,文件的个数限定为 30个,超过进行覆盖--> <DefaultRolloverStrategy max="30"/> </RollingFile> </Appenders> <!--logger 定义--> <Loggers> <!--自定义异步logger对象 includeLocation="false":关闭日志记录的行号信息,以免影响性能 additivity="false":不在继承rootlogger对象--> <AsyncLogger name="cn.ybzy" level="trace" includeLocation="false" additivity="false"> <AppenderRef ref="Console"/> </AsyncLogger> <!--使用 rootLogger 配置 日志级别 level="trace"--> <Root level="trace"> <!--指定日志使用的处理器--> <AppenderRef ref="Console"/> <!--使用异步 appender--> <AppenderRef ref="Async"/> </Root> </Loggers> </Configuration>Log4j2异步日志
log4j2最大的特点就是异步日志,其性能的提升主要也是从异步日志中受益,Log4j2提供了两种实现方式,一个是通过AsyncAppender,一个是通过AsyncLogger,分别对Appender组件和Logger组件。
<!--异步日志依赖--> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.3.4</version> </dependency>AsyncAppender方式
<?xml version="1.0" encoding="UTF-8"?> <!--tatus:日志框架输出的日志级别 monitorInterval:自动加载配置文件的间隔时间,不低于 5 秒--> <Configuration status="debug" monitorInterval="5"> <!--属性配置管理--> <properties> <property name="LOG_HOME">d:/logs</property> </properties> <!--日志处理--> <Appenders> <!--日志文件输出 appender--> <File name="file" fileName="${LOG_HOME}/myfile.log"> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %m%n"/> </File> <Async name="Async"> <AppenderRef ref="file"/> </Async> </Appenders> <!--使用 rootLogger 配置 日志级别 level="trace"--> <Root level="trace"> <!--使用异步 appender--> <AppenderRef ref="Async"/> </Root> </Loggers> </Configuration>AsyncLogger方式
官方推荐的异步方式。它可以使得调用Logger.log返回的更快。有两种选择:全局异步和混合异步。
全局异步
全局异步 : 所有的日志都异步的记录,在配置文件上不用做任何改动,只需要添加一个log4j2.component.properties 配置
log4j2.component.properties
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector混合异步
混合异步 : 可以在应用中同时使用同步日志和异步日志,这使得日志的配置方式更加灵活。
cn.ybzy日志是异步的,root日志是同步的。 <?xml version="1.0" encoding="UTF-8"?> <!--tatus:日志框架输出的日志级别 monitorInterval:自动加载配置文件的间隔时间,不低于 5 秒--> <Configuration status="debug" monitorInterval="5"> <!--日志处理--> <Appenders> <!--控制台输出appender SYSTEM_OUT:黑色字体 SYSTEM_ERR:红色字体--> <Console name="Console" target="SYSTEM_ERR"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n"/> </Console> </Appenders> <!--logger 定义--> <Loggers> <!--自定义异步logger对象 includeLocation="false":关闭日志记录的行号信息 additivity="false":不在继承rootlogger对象--> <AsyncLogger name="cn.ybzy" level="trace" includeLocation="false" additivity="false"> <AppenderRef ref="Console"/> </AsyncLogger> <!--使用 rootLogger 配置 日志级别 level="trace"--> <Root level="trace"> <!--指定日志使用的处理器--> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>