Java日志框架学习笔记

一 日志概述

日志文件

日志文件是用于记录系统操作事件的文件集合,分为调试日志和系统日志

日志框架
  • 日志门面

    JCL、slf4j

  • 日志实现

    JUL、logback、log4j、log4j2

在这里插入图片描述

二 JUL

Java Util Logging,Java原生日志框架

使用
import java.util.logging.*;

public class JULTest {
    @Test
    public void test() throws Exception {
        //获取日志记录器对象
        Logger logger=Logger.getLogger("com.web02.JULTest");
        //日志记录输出
        logger.info("hello jul");

        //通用方法记录日志
        logger.log(Level.INFO,"info msg");

        //占位符方式输出变量值
        String name="hhf";
        Integer age=21;
        logger.log(Level.INFO,"info msg: {0},{1}",new Object[]{name,age});
    }
}
日志级别
  • SEVERE:严重错误
  • WARNING:警告
  • INFO:普通信息
  • CONFIG:配置信息
  • FINE、FINER、FINEST:用于debug记录
  • ALL:启用所有消息的日志记录
  • OFF:关闭日志记录

控制台默认输出前三个级别的日志

自定义配置日志级别
@Test
public void testLogConfig() throws Exception {
    Logger logger=Logger.getLogger("com.web02.JULTest");

    //关闭系统默认配置
    logger.setUseParentHandlers(false);

    //创建ConsoleHandler,控制台输出
    ConsoleHandler consoleHandler=new ConsoleHandler();

    //创建简单格式转换对象
    SimpleFormatter simpleFormatter=new SimpleFormatter();

    //进行关联
    consoleHandler.setFormatter(simpleFormatter);
    logger.addHandler(consoleHandler);

    //自定义配置日志级别
    logger.setLevel(Level.ALL);
    consoleHandler.setLevel(Level.ALL);

    //创建FileHandler,文件输出
    FileHandler fileHandler=new FileHandler("jul.log");
    fileHandler.setFormatter(simpleFormatter);
    fileHandler.setLevel(Level.ALL);
    logger.addHandler(fileHandler);

    logger.config("config");
}
Logger对象父子关系

用getParent()获取Logger父对象

所有日志记录器的顶级父元素是LogManager$RootLogger

自定义配置文件

resources下新建logging.properties

#RootLogger默认处理器
handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler
#RootLogger默认日志级别
.level=ALL

#自定义Logger
com.web02.JULTest.handlers=java.util.logging.ConsoleHandler
com.web02.JULTest.level=CONFIG
com.web02.JULTest.useParentHandlers=false

#日志文件路径
java.util.logging.FileHandler.pattern=my.log
#日志文件内容大小
java.util.logging.FileHandler.limit=50000
#日志文件数量
java.util.logging.FileHandler.count=1
java.util.logging.FileHandler.formatter=java.util.logging.XMLFormatter
#指定追加方式
java.util.logging.FileHandler.append=true

#控制台处理器的日志级别
java.util.logging.ConsoleHandler.level=ALL
#控制台处理器的消息格式对象
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
#控制台处理器的字符集
java.util.logging.ConsoleHandler.encoding=UTF-8
#消息格式
java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
@Test
public void testLogProperties() throws Exception {
    //通过类加载器读取配置文件
    InputStream ins=JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
    //创建LogManager
    LogManager logManager=LogManager.getLogManager();
    //加载配置文件
    logManager.readConfiguration(ins);

    Logger logger=Logger.getLogger("com.web02.JULTest");
    logger.config("config");
}
原理

在这里插入图片描述

三 Log4j

简单使用
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
</dependency>
import org.apache.log4j.Logger;
import org.apache.log4j.helpers.LogLog;
import org.junit.Test;

public class Log4jTest {
    @Test
    public void test() throws Exception {
        //初始化配置信息
        BasicConfigurator.configure();
        //获取日志记录器对象
        Logger logger=Logger.getLogger(Log4jTest.class);

        //日志级别
        logger.fatal("fatal");//严重错误
        logger.error("error");//错误信息
        logger.warn("warn");//警告信息
        logger.info("msg");//运行信息
        logger.debug("debug");//调试信息
        logger.trace("trace");//追踪信息
    }
}
组件
Loggers

日志记录器,负责收集处理日志记录

Appenders

指定日志输出的位置

分为ConsoleAppender, FileAppender, DailyRollingFileAppender, RollingFileAppender, JDBCAppender

Layout

控制日志输出的格式

分为HTMLLayout, SimpleLayout, PatternLayout

配置文件

resources下新建log4j.properties

#指定日志级别,使用的appender
log4j.rootLogger=trace,console
#指定控制台输出的appender
log4j.appender.console=org.apache.log4j.ConsoleAppender
#指定消息格式layout
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#指定消息格式内容
log4j.appender.console.layout.conversionPattern=%r [%t] %p %c %x - %m%n

在这里插入图片描述

开启log4j内置日志记录
LogLog.setInternalDebugging(true);
FileAppender配置
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=%r [%t] %p %c %x - %m%n
log4j.appender.file.file=log4j.log
log4j.appender.file.encoding=UTF-8
RollingFileAppender配置
#按照文件大小拆分
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.conversionPattern=%r [%t] %p %c %x - %m%n
log4j.appender.rollingFile.file=log4j.log
log4j.appender.rollingFile.encoding=UTF-8
log4j.appender.rollingFile.maxFileSize=1MB
log4j.appender.rollingFile.maxBackupIndex=10
DailyRollingFileAppender配置
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyFile.layout.conversionPattern=%r [%t] %p %c %x - %m%n
log4j.appender.dailyFile.file=log4j.log
log4j.appender.dailyFile.encoding=UTF-8
log4j.appender.dailyFile.datePattern='.'yyyy-MM-dd-HH-mm-ss
JDBCAppender配置
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout
log4j.appender.logDB.Driver=com.mysql.jdbc.Driver
log4j.appender.logDB.URL=jdbc:mysql://localhost:3306/test
log4j.appender.logDB.User=xxx
log4j.appender.logDB.Password=xxx
log4j.appender.logDB.Sql=xxx
自定义logger设置
log4j.logger.com.web02=info,file

四 JCL

Jakarta Commons Logging,Apache提供的一个通用日志API,为所有Java日志实现提供一个统一接口

在这里插入图片描述

使用
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;

public class JCLTest {
    @Test
    public void test() {
        Log log= LogFactory.getLog(JCLTest.class);
        log.info("info");
    }
}
优势
  • 面向接口开发,减少代码耦合
  • 可灵活切换日志框架
  • 统一API,方便学习使用
  • 统一配置
原理
  1. 通过LogFactory动态加载Log实现类
  2. 查找符合条件的日志实现,包括Log4JLogger, Jdk14Logger, Jdk13LumberjackLogger, SimpleLog
  3. 获取具体的日志实现

五 Slf4j

简单使用
<!--slf4j日志门面-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.28</version>
</dependency>

<!--slf4j内置实现-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.21</version>
</dependency>
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Slf4jTest {
    public static final Logger LOGGER= LoggerFactory.getLogger(Slf4jTest.class);

    @Test
    public void test() {
        LOGGER.error("error");
        LOGGER.warn("warn");
        LOGGER.info("info");//默认级别
        LOGGER.debug("debug");
        LOGGER.trace("trace");

        String name="log";
        LOGGER.info("{}",name);

        try {
            int a=1/0;
        } catch (Exception ex) {
            LOGGER.error("error",ex);
        }
    }
}
日志绑定

只能绑定一个日志实现,如果出现多个默认使用第一个

绑定logback
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
绑定slf4j-nop
<!--日志开关-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-nop</artifactId>
    <version>1.7.25</version>
</dependency>
绑定log4j
<!--适配器-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.12</version>
</dependency>
<dependency>
	<groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
</dependency>
绑定JUL
<!--适配器-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-jdk14</artifactId>
    <version>1.5.6</version>
</dependency>
日志桥接器

举例:项目由log4j切换为slf4j+logback

<!--配置log4j桥接器-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
    <version>1.7.25</version>
</dependency>

桥接器和适配器不能同时存在,否则会出现栈溢出异常

六 Logback

分为三个模块

  • logback-core
  • logback-classic
  • logback-access
使用
<!--slf4j日志门面-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.28</version>
</dependency>
<dependency>
	<groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogbackTest {
    public static final Logger LOGGER= LoggerFactory.getLogger(LogbackTest.class);

    @Test
    public void test() {
        LOGGER.error("error");
        LOGGER.warn("warn");
        LOGGER.info("info");
        LOGGER.debug("debug");//默认级别
        LOGGER.trace("trace");
    }
}
配置文件

logback会依次读取以下配置文件,如果都不存在会使用默认配置

  • logback.groovy
  • logback-test.xml
  • logback.xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <!--配置集中管理属性-->
    <property name="pattern" value="%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L %thread %m%n"></property>

    <!--控制台输出appender-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!--控制输出流对象-->
        <target>System.err</target>
        <!--消息格式配置-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!--root logger配置-->
    <root level="ALL">
        <appender-ref ref="console"></appender-ref>
    </root>
</configuration>

在这里插入图片描述

FileAppender配置
<property name="pattern" value="%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L %thread %m%n"></property>

<property name="log_dir" value="/logs"></property>

<!--文件输出appender-->
<appender name="file" class="ch.qos.logback.core.FileAppender">
	<!--文件保存路径-->
    <file>${log_dir}/logback.log</file>
    <!--消息格式配置-->
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    	<pattern>${pattern}</pattern>
    </encoder>
</appender>

<!--html文件输出appender-->
<appender name="htmlfile" class="ch.qos.logback.core.FileAppender">
	<!--文件保存路径-->
    <file>${log_dir}/logback.html</file>
    <!--消息格式配置-->
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
    	<layout class="ch.qos.logback.classic.html.HTMLLayout">
            <pattern>${pattern}</pattern>
        </layout>
    </encoder>
</appender>

<root level="ALL">
	<appender-ref ref="file"></appender-ref>
    <appender-ref ref="htmlfile"></appender-ref>
</root>
拆分Appender配置
<property name="pattern" value="%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L %thread %m%n"></property>

<property name="log_dir" value="/logs"></property>
<appender name="rollfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!--文件保存路径-->
    <!--<file>${log_dir}/roll_logback.log</file>-->
    <!--消息格式配置-->
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>${pattern}</pattern>
    </encoder>
    <!--指定拆分规则-->
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!--按照时间,压缩格式用log.gz-->
        <fileNamePattern>${log_dir}/roll.%d{yyyy-MM-dd-HH-mm-ss}.log%i</fileNamePattern>
        <!--按照文件大小-->
        <maxFileSize>1MB</maxFileSize>
    </rollingPolicy>
</appender>
<root level="ALL">
	<appender-ref ref="rollfile"></appender-ref>
</root>
过滤器
<appender name="rollfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!--文件保存路径-->
    <!--<file>${log_dir}/roll_logback.log</file>-->
    <!--消息格式配置-->
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>${pattern}</pattern>
    </encoder>
    <!--指定拆分规则-->
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!--按照时间,压缩格式用log.gz-->
        <fileNamePattern>${log_dir}/roll.%d{yyyy-MM-dd-HH-mm-ss}.log%i</fileNamePattern>
        <!--按照文件大小-->
        <maxFileSize>1MB</maxFileSize>
    </rollingPolicy>

    <!--日志级别过滤器-->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <!--过滤规则-->
        <level>ERROR</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
</appender>
异步日志
<!--异步日志,提升性能-->
<appender name="async" class="ch.qos.logback.classic.AsyncAppender">
    <!--指定某个具体appender-->
    <appender-ref ref="rollfile"></appender-ref>
</appender>
<root level="ALL">
	<appender-ref ref="async"></appender-ref>
</root>
自定义logger
<!--自定义logger additivity:自定义logger是否继承rootlogger-->
<logger name="com.web02" level="info" additivity="false">
    <appender-ref ref="console"></appender-ref>
</logger>
log4j.properties->logback.xml

http://logback.qos.ch/translator/

logback-access

与Servlet容器(Tomcat、Jetty)集成,提供HTTP访问日志功能

七 Log4j2

slf4j+log4j2
<!--slf4j日志门面-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.28</version>
</dependency>

<!--log4j2日志门面-->
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.11.2</version>
</dependency>

<!--log4j2日志实现-->
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.10.0</version>
</dependency>

<!--log4j2适配器-->
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.9.1</version>
</dependency>
配置文件
<?xml version="1.0" encoding="utf-8" ?>
<!--status:输出的日志级别,monitorInternal:自动加载配置文件的间隔时间-->
<Configuration status="debug" monitorInternal="5">
    <!--配置集中管理属性-->
    <properties>
        <property name="log_home">/logs</property>
    </properties>

    <!--控制台输出appender-->
    <Appenders>
        <Console name="Console" target="SYSTEM_ERR">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}"></PatternLayout>
        </Console>

        <File name="file" fileName="${log_home}/myfile.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}"></PatternLayout>
        </File>

        <RandomAccessFile name="accessfile" fileName="${log_home}/myfile.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}"></PatternLayout>
        </RandomAccessFile>

        <RollingFile name="rollingfile" fileName="${log_home}/myfile.log"
        filePattern="/logs/$${date:yyyy-MM-dd}/rolllog-%d{yyyy-MM-dd-HH-mm}-%i.log">
            <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"></ThresholdFilter>
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}"></PatternLayout>

            <Policies>
                <OnStartupTriggeringPolicy></OnStartupTriggeringPolicy>
                <SizeBasedTriggeringPolicy size="1 MB"></SizeBasedTriggeringPolicy>
                <TimeBasedTriggeringPolicy></TimeBasedTriggeringPolicy>
            </Policies>
            <DefaultRolloverStrategy max="30"></DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>

    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"></AppenderRef>
        </Root>
    </Loggers>

</Configuration>
异步日志

在这里插入图片描述

<!--异步日志依赖-->
<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.3.4</version>
</dependency>
配置异步Appender:
<Appenders>
    <File name="file" fileName="${log_home}/myfile.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}"></PatternLayout>
        </File>

        <Async name="Async">
            <AppenderRef ref="file"></AppenderRef>
        </Async>
</Appenders>

<Loggers>
        <Root level="trace">
            <AppenderRef ref="Async"></AppenderRef>
        </Root>
    </Loggers>
配置异步Logger:
全局配置

log4j2.component.properties

Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
混合配置
<!--自定义异步Logger,includeLocation关闭行号信息,additivity不继承rootlogger-->
<AsyncLogger name="com.web02" level="trace" includeLocation="false" additivity="false">
    <AppenderRef ref="file"></AppenderRef>
</AsyncLogger>

使用异步日志,AsyncAppender, AsyncLogger, 全局日志不能同时出现

无垃圾模式

使用重用对象、缓冲区、尽可能不分配临时对象的手段,提高性能

八 SpringBoot日志

依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>

springboot默认使用slf4j作为日志门面,使用logback作为日志实现

配置

在这里插入图片描述

logback-spring.xml:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <!--配置集中管理属性-->
    <property name="pattern" value="%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L %thread %m%n"></property>

    <!--控制台输出appender-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!--控制输出流对象-->
        <target>System.err</target>
        <!--消息格式配置-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <springProfile name="dev">
                <pattern>${pattern}</pattern>
            </springProfile>
            <springProfile name="pro">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}</pattern>
            </springProfile>
        </encoder>
    </appender>

    <!--root logger配置-->
    <root level="ALL">
        <appender-ref ref="console"></appender-ref>
    </root>
</configuration>
#指定环境,使用不同的日志格式
spring.profiles.active=dev
切换为log4j2
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!--排除logback-->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值