日志使用简介

1. 日志概述

对于一个应用程序来说日志记录是必不可少的一部分。线上问题追踪,基于日志的业务逻辑统计分析等都离开不日志。java领域存在多种日志框架,目前常用的日志框架包括Log4j 1,Log4j 2,Commons Logging,Slf4j,Logback,Jul。

在这里插入图片描述

1.1 日志框架

  • Log4j: Apache Log4j是一个基于Java的日志记录工具。它是由Ceki Gülcü首创的,现在则是Apache软件基金会的一个项目。
  • Log4j 2: Apache Log4j 2是apache开发的一款Log4j的升级产品。
  • Commons Logging: Apache基金会所属的项目,是一套Java日志接口,之前叫Jakarta Commons Logging,后更名为Commons Logging。
  • Slf4j: 类似于Commons Logging,是一套简易的Java日志门面,本身并无日志的实现。(Simple Logging Facade for Java,缩写Slf4j)。
  • Logback: 一套日志组件的实现(Slf4j阵营)。
  • Jul: (Java Util Logging),自Java1.4以来的官方日志实现。

1.2 框架历史

  • 1996年早期,欧洲安全电子市场项目组决定编写它自己的程序跟踪API(Tracing API)。经过不断的完善,这个API终于成为一个十分受欢迎的Java日志软件包,即Log4j。后来Log4j成为Apache基金会项目中的一员。
  • 期间Log4j近乎成了Java社区的日志标准。据说Apache基金会还曾经建议Sun引入Log4j到java的标准库中,但Sun拒绝了。
  • 2002年Java1.4发布,Sun推出了自己的日志库JUL(Java Util Logging),其实现基本模仿了Log4j的实现。在JUL出来以前,Log4j就已经成为一项成熟的技术,使得Log4j在选择上占据了一定的优势。
  • 接着,Apache推出了Jakarta Commons Logging,JCL只是定义了一套日志接口(其内部也提供一个Simple Log的简单实现),支持运行时动态加载日志组件的实现,也就是说,在你应用代码里,只需调用Commons Logging的接口,底层实现可以是Log4j,也可以是Java Util Logging。
  • 2006年Ceki Gülcü不适应Apache的工作方式,离开了Apache。然后创建了Slf4j(日志门面接口,类似于Commons Logging)和Logback(Slf4j的实现)两个项目,并回瑞典创建了QOS公司,QOS官网上是这样描述Logback的The Generic,Reliable Fast&Flexible Logging Framework(一个通用,可靠,快速且灵活的日志框架)。
  • 现今,Java日志领域被划分为两大阵营:Commons Logging阵营和Slf4j阵营。Commons Logging在Apache大树的笼罩下,有很大的用户基数。但有证据表明,形式正在发生变化。2013年底有人分析了GitHub上30000个项目,统计出了最流行的100个Libraries,可以看出Slf4j的发展趋势更好。
  • Apache眼看有被Logback反超的势头,于2012-07重写了Log4j 1.x,成立了新的项目Log4j 2, Log4j 2具有Logback的所有特性。

在这里插入图片描述

1.3 框架选择

在新项目中推荐使用 Slf4j + Logback 的组合

  • Slf4j实现机制决定Slf4j限制较少,使用范围更广。由于Slf4j在编译期间,静态绑定本地的LOG库使得通用性要比Commons Logging要好。
  • Logback拥有更好的性能。某些关键操作,比如判定是否记录一条日志语句的操作,其性能得到了显著的提高。这个操作在Logback中需要3纳秒,而在Log4J中则需要30纳秒。LogBack创建记录器的速度也更快,只需要13毫秒,而在Log4J中需要23毫秒。更重要的是,它获取已存在的记录器只需94纳秒,而Log4J需要2234纳秒,时间减少到了1/23。跟JUL相比的性能提高也是显著的。
  • Commons Logging开销更高。
  • Logback的所有文档是全面免费提供的,不象Log4J那样只提供部分免费文档而需要用户去购买付费文档。

2. 日志组件

日志组件包括三个部分,记录器、输出源和布局。

2.1 记录器

Loggers即记录器,它指定日志的级别,日志的何种级别需要记录。记录器只输出级别不低于设定级别的日志信息,假设Loggers级别设定为INFO,则INFO、WARN、ERROR和FATAL级别的日志信息都会输出,而级别比INFO低的DEBUG则不会输出。

2.2.1 日志级别

  • 等级:OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL
级别描述
ALLALL是最低等级的,用于打开所有日志记录
TRACETRACE比DEBUG更低,一般不使用
DEBUGDEBUG指出细粒度信息事件对调试应用程序是非常有帮助的
INFOINFO表明消息在粗粒度级别上突出强调应用程序的运行过程
WARNWARN表明会出现潜在错误的情形
ERRORERROR指出虽然发生错误事件,但仍然不影响系统的继续运行
FATALFATAL指出每个严重的错误事件将会导致应用程序的退出
OFFOFF是最高等级的,用于关闭所有日志记录

配置模式:

<!-- 日志输出级别 -->
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>

2.2 输出源

Appenders即输出源,它指定日志输出的位置,日志需要输出到哪里。允许把日志输出到不同的地方,如控制台、文件等,可以根据天数或者文件大小产生新的文件,也可以以流的形式发送到其它地方。

ConsoleAppender:控制台
FileAppender:文件
DailyRollingFileAppender:每天产生一个日志文件
RollingFileAppender:文件大小到达指定尺寸的时候产生一个新的文件
WriterAppender:将日志信息以流格式发送到任意指定的地方

配置模式:

<!-- 日志输出到控制台 -->
<Console name="Console_Appender" target="SYSTEM_OUT"></Console>

<!-- 日志输出到文件 -->
<File name="File_Appender" fileName="ERROR.log" append="false"></File>

<!-- 日志输出到文件(文件大小到达指定尺寸的时候产生一个新的文件) -->
<RollingFile name="File_ERROR_Appender" fileName="ERROR.log"></RollingFile>

2.3 布局

Layouts即布局,它规定日志的输出格式,日志要以什么样子输出。根据HTML样式、自由指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式。

HTMLLayout:以HTML表格形式布局
PatternLayout:可以灵活地指定布局模式
SimpleLayout:包含日志信息的级别和信息字符串
TTCCLayout:包含日志产生的时间、线程、类别等信息

2.3.1 输出格式

格式描述
%c输出日志信息所属的类的全名
%d输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式
%f输出日志信息所属的类的类名
%l输出日志事件的发生位置,即输出日志信息的语句处于它所在的类的第几行
%m输出代码中指定的信息
%n输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
%p输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r输出自应用启动到输出该日志信息所耗费的毫秒数
%t输出产生该日志事件的线程名

配置模式:

<!-- 日志输出格式 -->
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] 【%-5level】 %class{36} %L %M - %msg%xEx%n"/>

3. 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="error">
    <!-- 定义日志输出根目录 -->
    <Properties>
        <Property name="LOG_HOME">D:/log</Property>
    </Properties>
    <!-- 定义日志输出源 -->
    <appenders>
        <!-- 日志输出到控制台 -->
        <Console name="Console_Appender" target="SYSTEM_OUT">
            <!-- 定义日志输出级别即记录器 -->
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 定义日志输出格式即布局 -->
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] 【%-5level】 %class{36} %L %M - %msg%xEx%n"/>
        </Console>

        <!-- 日志输出到文件 -->
        <File name="File_Appender" fileName="${LOG_HOME}/logs/file.log" append="false">
            <!-- 定义日志输出级别即记录器 -->
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 定义日志输出格式即布局 -->
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] 【%-5level %class{36}】 %L %M - %msg%xEx%n"/>
        </File>

        <!-- 日志输出到文件(文件大小到达指定尺寸的时候产生一个新的文件) -->
        <RollingFile name="File_ERROR_Appender" fileName="${LOG_HOME}/logs/ERROR.log" filePattern="${LOG_HOME}/logs/$${date:yyyy-MM}/ERROR-%d{yyyy-MM-dd}-%i.log.gz">
            <!-- 定义日志输出级别即记录器 -->
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 定义日志输出格式即布局 -->
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] 【%-5level】 %class{36} %L %M - %msg%xEx%n"/>
            <Policies>
                <!-- 采用时间策略 -->
                <TimeBasedTriggeringPolicy/>
                <!-- 指定文件大小 -->
                <SizeBasedTriggeringPolicy size="1MB"/>
            </Policies>
        </RollingFile>
    </appenders>

    <loggers>
        <root level="ALL">
            <!-- 过滤无用日志信息 -->
            <logger name="org.springframework" level="INFO"></logger>
            <logger name="org.mybatis" level="INFO"></logger>
            <!-- 配置哪些输出源生效 -->
            <appender-ref ref="Console_Appender"/>
            <appender-ref ref="File_Appender"/>
            <appender-ref ref="File_ERROR_Appender"/>
            <appender-ref ref="File_WARN_Appender"/>
            <appender-ref ref="File_INFO_Appender"/>
            <appender-ref ref="File_DEBUG_Appender"/>
        </root>
    </loggers>
</configuration>

4. 入门案例

  • GitEE地址:https://gitee.com/ghzhouwei/JavaBase.git

4.1 项目结构

在这里插入图片描述

4.2 创建工程

  • 基于MAVEN的项目

在这里插入图片描述

4.3 项目依赖

<dependencies>
    <!-- log4j-api -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.13.3</version>
    </dependency>
    <!-- log4j-core -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.12.1</version>
    </dependency>
</dependencies>

4.4 测试文件

package com.intest.log4j2.test;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * @ClassName: Log4jTest
 * @Description: 日志测试类
 * @Author: zhouWei
 * @Date: 2020-11-4 - 11:23
 */
public class Log4jTest
{
    private static Logger logger= LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    public static void main(String[] args)
    {
        for(int i = 0; i < 30000; i++)
        {
            // 记录error级别的信息
            logger.error("log4j2日志输出:This is error message.");

            // 记录warn级别的信息
            logger.warn("log4j2日志输出:This is warn message.");

            // 记录info级别的信息
            logger.info("log4j2日志输出:This is info message.");

            // 记录debug级别的信息
            logger.debug("log4j2日志输出:This is debug message.");
        }
    }
}

4.5 日志配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="error">
    <!-- 定义日志输出根目录 -->
    <Properties>
        <Property name="LOG_HOME">D:/log</Property>
    </Properties>
    <appenders>
        <!-- 日志输出到控制台 -->
        <Console name="Console_Appender" target="SYSTEM_OUT">
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] 【%-5level】 %class{36} %L %M - %msg%xEx%n"/>
        </Console>

        <!-- 日志输出到文件 -->
        <File name="File_Appender" fileName="${LOG_HOME}/logs/file.log" append="false">
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] 【%-5level %class{36}】 %L %M - %msg%xEx%n"/>
        </File>

        <!-- 日志输出到文件(文件大小到达指定尺寸的时候产生一个新的文件) -->
        <RollingFile name="File_ERROR_Appender" fileName="${LOG_HOME}/logs/ERROR.log" filePattern="${LOG_HOME}/logs/$${date:yyyy-MM}/ERROR-%d{yyyy-MM-dd}-%i.log.gz">
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] 【%-5level】 %class{36} %L %M - %msg%xEx%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="1MB"/>
            </Policies>
        </RollingFile>

        <!-- 日志输出到文件(文件大小到达指定尺寸的时候产生一个新的文件) -->
        <RollingFile name="File_WARN_Appender" fileName="${LOG_HOME}/logs/WARN.log" filePattern="${LOG_HOME}/logs/$${date:yyyy-MM}/WARN-%d{MM-dd-yyyy}-%i.log.gz">
            <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] 【%-5level】 %class{36} %L %M - %msg%xEx%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="1MB"/>
            </Policies>
        </RollingFile>

        <!-- 日志输出到文件(文件大小到达指定尺寸的时候产生一个新的文件) -->
        <RollingFile name="File_INFO_Appender" fileName="${LOG_HOME}/logs/INFO.log" filePattern="${LOG_HOME}/logs/$${date:yyyy-MM}/INFO-%d{MM-dd-yyyy}-%i.log.gz">
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] 【%-5level】 %class{36} %L %M - %msg%xEx%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="1MB"/>
            </Policies>
        </RollingFile>

        <!-- 日志输出到文件(文件大小到达指定尺寸的时候产生一个新的文件) -->
        <RollingFile name="File_DEBUG_Appender" fileName="${LOG_HOME}/logs/DEBUG.log" filePattern="${LOG_HOME}/logs/$${date:yyyy-MM}/DEBUG-%d{MM-dd-yyyy}-%i.log.gz">
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] 【%-5level】 %class{36} %L %M - %msg%xEx%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="1MB"/>
            </Policies>
        </RollingFile>
    </appenders>

    <loggers>
        <root level="ALL">
            <!-- 过滤无用日志信息 -->
            <logger name="org.springframework" level="INFO"></logger>
            <logger name="org.mybatis" level="INFO"></logger>
            <!-- 配置哪些输出源生效 -->
            <appender-ref ref="Console_Appender"/>
            <appender-ref ref="File_Appender"/>
            <appender-ref ref="File_ERROR_Appender"/>
            <appender-ref ref="File_WARN_Appender"/>
            <appender-ref ref="File_INFO_Appender"/>
            <appender-ref ref="File_DEBUG_Appender"/>
        </root>
    </loggers>
</configuration>

4.6 运行测试

  • 控制台打印了四种级别的日志

在这里插入图片描述

  • D:\log\logs目录下面也生成了对应的日志文件和日志压缩文件

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值