Log4j

1、Log4j 简介

  Log4j 是 Apache 下的一款开源的日志框架,通过在项目中使用 Log4j,我们可以控制日志信息输出到控制台、文件、甚至是数据库中。我们可以控制每一条日志的输出格式,通过定义日志的输出级别,可以更灵活的控制日志的输出方式。

2、Log4j 入门

添加依赖
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

快速入门
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

public class Test {


    public static void main(String[] args) {
        // 初始化配置信息,在入门案例中暂不适用配置文件
        BasicConfigurator.configure();

        // 获取日志记录器对象
        Logger logger=Logger.getLogger(Test.class);
        // 日志记录输出
        logger.fatal("fatal");
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace");
    }
}

3、日志级别

  • fatal:严重错误,一般会造成系统崩溃并终止运行
  • error:错误信息,不会影响系统运行
  • warn:警告信息,可能会发生问题
  • infor:运行信息,数据链接、网络连接、IO 操作等等
  • debug:调试信息,一般在开发中使用,记录程序变量参数传递信息等等
  • trace:追踪信息,记录程序所有的流程信息

4、log4j 组件

  log4j 主要由 Loggers(日志记录器)、Appenders(输出端)和 Layout(日志格式化器)组成。其中 Loggers 控制日志的输出级别与日志是否输出;Appenders 指定日志的输出方式(输出到控制台、文件等);Layout 控制日志信息的输出格式。

Loggers

  日志记录器,负责收集处理日志记录。log4j 中有一个特殊的 logger 叫做 root,它是所有的 logger 的根,也是意味着其他所有的 logger 都会直接或者间接的继承 root,root logger 可以用 Logger.getRootLogger()方法获取。

Appenders

  Appenders 用来指定日志输出到哪个地方,可以同时指定日志的输出目的地。Log4j 常用的输出目的地有以下几种:

输出端类型作用
ConsoleAppender将日志输出到控制台
FileAppender将日志输出到文件中
DailyRollingFileAppender将日志输出到一个日志文件,并且每天输出到一个新的文件
RollingFileAppender将日志信息输出到一个日志文件,并且指定文件的大小,当文件大小达到指定大小时,会自动把文件改名,同时产生一个新的文件
JDBCAppender把日志信息保存到数据库中
Layouts

  布局器 Layouts 用于控制日志输出内容的格式,让我们可以使用各种需要的格式输出日志。Log4j 常用的 Layouts。

格式化器类型作用
HTMLLayout格式化日志输出为 HTML 表格形式
SimpleLayout简单的日志输出格式化,打印的日志格式为(info-message)
PatternLayout最强大的格式化器,可以根据自定义格式输出日志,如果没有指定转换格式,就是用默认的转换格式

  log4j 打印格式化日志信息的占位符含义。

占位符含义
%m输出代码中指定的日志信息
%p输出优先级,及 DEBUG,INFOR 等
%n换行符
%r输出字应用到输出该 log 信息耗费的毫秒数
%c输出打印语句所属类的全名
%t输出产生该日志的线程全名
%d输出服务器当前时间,也可以指定格式,如:%d{yyyy-MM-dd HH🇲🇲ss}
%l输出日志时间发生的位置,包括类名、线程、及在代码中的行数
%F输出日志消息产生时所在的文件名称
%L输出代码中的行号
%%输出一个“%” 字符

  我们可以在 % 与字符之间加上修饰符来控制最小宽度、最大宽度和文本的对其方式,如:

占位符含义
%5c输出 category 名称,最小宽度是 5,category<5,默认的情况下右对齐
%-5c“-”号表示左对齐,用空格填充
%.5c输出 category 名称,最大宽度是 5,category>5,就会将左边多出的字符截掉,<5 不会有空格
+.30ccategory 名称 <20 补空格,并且右对齐,>30 字符,就从左边开始截掉字符

5、log4j 的配置文件

  创建 log4j.properties 文件,由于 log4j 已经淘汰,过于详细的配置信息不做解释,下面的 log4j 简单的配置信息。

# 指定 RootLogger 顶级父元素默认配置信息
# 指定日志级别=trace,使用的 appender 为 console
log4j.rootLogger = ALL,console
# 指定控制台日志输出的 appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定消息格式 layout  例如 org.apache.log4j.HTMLLayout
log4j.appender.console.layout = org.apache.log4j.SimpleLayout
# 指定消息格式的内容
log4j.appender.console.layout.conversionPattern = [%5p]%r %c %t %F %L %d{yyyy-MM-dd HH:mm:ss} %m%n

log4j2

  Apache Log4j2 是对 Log4j 的升级版,参考了 Logback 的一些优秀的设计,并且修复了一些问题,因此带来了一些重大的提升,主要有:

  • 异常处理,在 Logback 中,Appender 中的异常不会被应用感知到,但是在 log4j2 中,提供了一些异常处理机制。
  • 性能提升,log4j2 相较于 log4j 和 logback 都具有很明显的性能提升。
  • 自动重载配置:参考了 Logback 的设计,提供了自动刷新配置参数,最实用的就是我们在生产上可以动态的修改日志的级别而不需要重启应用。
  • 无垃圾机制,Log4j 在大部分情况下,都可以使用其设计的一套无垃圾机制,避免频繁的日志收集导致的 jvm gc。

1、log4j2 入门

  目前市面上最主流的日志门面就是 slf4j,虽然 log4j2 也是日志门面,因为它得到日志实现功能非常强大,性能优越。所以大家一般还是将 log4j2 看作是日志的实现,slf4j + log4j2 应该是未来的大势所趋。(官网)

添加依赖
        <!-- Log4j2 门面 API -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.13.1</version>
        </dependency>
        <!-- Log4j2 日志实现 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.1</version>
        </dependency>
快速入门
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Test {

    // 定义日志记录器对象
    public static final Logger LOGGER = LogManager.getLogger(Test.class);

    public static void main(String[] args) {
        // 日志输出
        LOGGER.fatal("fatal");
        LOGGER.error("error");
        LOGGER.warn("warn");
        LOGGER.info("info");
        LOGGER.debug("debug");
        LOGGER.trace("trace");
    }
}

2、整合 slf4j

添加依赖
        <!-- slf4j 日志门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>
        <!-- 基于 log4j2 的适配器 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.13.1</version>
        </dependency>
        <!-- Log4j2 门面 API -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.13.1</version>
        </dependency>
        <!-- Log4j2 日志实现 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.1</version>
        </dependency>
快速入门
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class Test {

    // 定义日志记录器对象
    public static final Logger LOGGER = LoggerFactory.getLogger(Test.class);

    public static void main(String[] args) {
            // 日志输出
            LOGGER.error("error");
            LOGGER.warn("warn");
            LOGGER.info("info");
            LOGGER.debug("debug");
            LOGGER.trace("trace");

    }
}

3、log4j2 的配置文件

  创建一个 log4j2.xml 配置文件,配置内容如下和 Logback 的配置文件类似。

<?xml version="1.0" encoding="UTF-8" ?>
<!--
    monitorInterval="5" 自动加载配置文件的间隔时间,不低于5秒
-->
<Configuration monitorInterval="5">
    <!--
        集中配置属性进行管理
        使用时通过:${name}  引用
    -->
    <properties>
        <property name="LogHome">E:/log</property>
        <property name="Layout">%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n</property>
    </properties>
    <!--日志处理-->
    <Appenders>
        <!--控制台输出 appender-->
        <Console name="console" target="SYSTEM_ERR">
            <PatternLayout pattern="${Layout}"/>
        </Console>
        <!-- 日志文件输出 appender-->
        <File name="file" fileName="${LogHome}/myFile.log">
            <PatternLayout pattern="${Layout}"/>
        </File>
        <!--使用随机读写流的日志文件输出 appender,性能提高-->
        <RandomAccessFile name="accessFile" fileName="${LogHome}/myAccessFile.log">
            <PatternLayout pattern="${Layout}"/>
        </RandomAccessFile>
        <!--按照一定规则拆分的日志文件的 appender-->
        <RollingFile name="rollingFile" fileName="${LogHome}/myRollingFile.log"
                filePattern="${LogHome}/$${date:yyyy-MM-dd}/rolling-%d{yyyy-MM-dd-HH-mm}-%i.log">
            <!--日志消息格式-->
            <PatternLayout pattern="${Layout}"/>
            <!--日志级别过滤器-->
            <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
            <Policies>
                <!--在系统启动时,出发拆分规则,生产一个新的日志文件-->
                <OnStartupTriggeringPolicy/>
                <!--安装文件大小拆分,10MB-->
                <SizeBasedTriggeringPolicy size="10KB"/>
                <!--按照时间结点拆分,规则根据filePattern定义的-->
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <!--在同一目录下,文件的个数限定为 30 个-->
            <DefaultRolloverStrategy max="30"/>
        </RollingFile>

    </Appenders>

    <!--logger 定义-->
    <loggers>
        <!--使用 rootLogger 配置 日志级别-->
        <Root level="trace">
            <!--指定日志使用的处理器-->
            <AppenderRef ref="console"/>
        </Root>
    </loggers>
</Configuration>

4、Log4j2 异步日志

  log4j2 最大的特点就是异步日志,其性能的提升主要也是从异步日志中受益,我们来看看如何使用 log4j2 的异步日志。
  log4j2 提供了两种实现日志的方式,一个是通过 AsyncAppender、另一个是通过 AsyncLogger,分别对应前面我们说的 Appender 组件和 Logger 组件。

注意:配置异步日志需要添加依赖

        <!-- 异步日志的依赖 -->
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.4.2</version>
        </dependency>
AsyncAppender 方式
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration monitorInterval="5">

    <properties>
        <property name="LogHome">E:/log</property>
        <property name="Layout">%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n</property>
    </properties>
    <!--日志处理-->
    <Appenders>
        <!-- 日志文件输出 appender-->
        <File name="file" fileName="${LogHome}/myFile.log">
            <PatternLayout pattern="${Layout}"/>
        </File>
        <Async name="Async">
            <AppenderRef ref="file"/>
        </Async>
    </Appenders>

    <!--logger 定义-->
    <loggers>
        <!--使用 rootLogger 配置 日志级别-->
        <Root level="trace">
            <!--指定日志使用的处理器-->
            <AppenderRef ref="Async"/>
        </Root>
    </loggers>
</Configuration>
AsyncLogger 方式

  AsyncLogger 是官方推荐的异步方式,它可以调用 Logger.log 返回的更快,有两种方式:全局异步和混合异步。

全局异步

  全局异步就是将所有的日志都异步的记录,在配置文件上不用做任何改动,只需要添加一个 log4j2.component.properties 配置:

Log4jContextSelector = org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
混合异步

  混合异步就是在应用中同时使用同步日志和异步日志,这使得日志的配置方便更加灵活。

    <!--logger 定义-->
    <loggers>
        <!--
            自定义异步 logger 对象
            name 需要异步的包路径
            includeLocation="false" 关闭日志记录的行号信息
            additivity="false" 不在继承 rootLogger对象
        -->
        <AsyncLogger name="top.zyxwmj.journal.demo" level="info" includeLocation="false" additivity="false">
            <AppenderRef ref="file"/>
        </AsyncLogger>
    </loggers>

标题:日志框架——log4j、log4j2
作者:Yi-Xing
地址:http://zyxwmj.top/articles/2020/03/22/1584840916941.html
博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!