java日志框架入门

一、学习目标

1、了解java常用日志框架
2、掌握JUL(java util logging)
3、掌握Log4j和Log4j2
4、掌握JCL(jakarta Commons Logging)
5、掌握slf4j(Simple Logging Facade for Java)
6、各种日志框架使用场景


二、学习笔记

2.1 JUL学习

JUL全称Java util Logging是java原生的日志框架,使用时不需要另外引入第三方类库,相对其他日志框架使用方便,学习简单,能够在小型应用中灵活使用。

2.1.1 架构介绍

在这里插入图片描述

  • Loggers
    被称为记录器,应用程序通过获取Logger对象,调用其API来发布日志信息。Logger通常是应用程序访问日志系统的入口程序。
  • Appender
    被称为Handler,每个Logger都会关联一组Handlers,Logger会将日志交给关联Handlers处理,有Handler负责将日志做记录。Handler是一个抽象,其具体实现决定了日志的位置可以是控制台、文件、网络上的其他日志服务或者操作系统日志等。
  • Layouts
    被称为Formatters,它负责对日志事件中的数据进行转换和格式化。Layouts决定了数据在一条日志记录中的最终形式。
  • Level
    每条日志消息都有一个关联的日志级别。该级别粗略知道了日志消息的重要性和紧迫性,可以将Level和Loggers,Appenders做关联以便我们过滤消息。
  • Filters
    过滤器,根据需要定制那些信息会被记录,那些信息被放弃

2.1.2 JUL执行原理

1、初始化LogManager
(1)LogManager加载logging.properties配置
(2)添加Logger到LogManager
2、从单例LogManager获取Logger
3、设置级别Level,并指定日志记录LogRecord
4、Filter提供了日志级别之外更细粒度的控制
5、Handler是用来处理日志输出位置
6、Formatter用来格式化LogRecord的
在这里插入图片描述

2.1.3 JUL硬编码配置

jdk自带的日志记录器,不需要额外引入依赖,在rt.jar中:
在这里插入图片描述
一共有七个日志级别

public class JulTest {
    public static void main(String[] args) throws IOException {
        Logger logger = Logger.getLogger(JulTest.class.getName());
        //关闭系统默认配置
        logger.setUseParentHandlers( false );

        //自定义配置日志级别
        //创建ConsolHhandler
        ConsoleHandler consoleHandler = new ConsoleHandler();
        //创建简单格式转换对象
        SimpleFormatter simpleFormatter = new SimpleFormatter();
        //进行关联
        consoleHandler.setFormatter(simpleFormatter);
        logger.addHandler( consoleHandler );
        //设置日志级别
        logger.setLevel(Level.ALL); //logger进行第一个日志级别过滤
        consoleHandler.setLevel(Level.CONFIG); //handler进行第二次日志级别的过滤

        //添加文件类型的输出,
        //入参:pattern(文件路径);append(是否在原文件追加日志,false代表每次覆盖文件)
        FileHandler fileHandler = new FileHandler("d:/jul.log",true);
        //多个文件循环覆盖,如下为:10个文件,每个文件最大1M
        //FileHandler fileHandler1 = new FileHandler("d:/jul.log",1024*1024,10);
        fileHandler.setFormatter(simpleFormatter);
        //添加文件日志处理器
        logger.addHandler(fileHandler);
        //设置日志级别
        logger.setLevel(Level.ALL);
        fileHandler.setLevel(Level.ALL);
        //测试
        logger.severe("测试severe");
        logger.warning("测试warning");
        logger.info("测试info");
        logger.config("测试config");
        logger.fine("测试fine");
        logger.finer("测试finer");
        logger.finest("测试finest");
    }
}

2.1.4 Logger对象的父子关系

    @Test
    public void loggerParentSon() {
        Logger logger = Logger.getLogger("com.cmb.jultest");
        Logger logger1 = Logger.getLogger("com.cmb");

		//输出结果为true
        System.out.println(logger.getParent() == logger1) ;
    	
    	//
    	//获取logger1的父对象
    	//所有日志记录器的顶级父元素 LogManager$RootLogger,name 为 "";
        System.out.println("logger1的Parent:" + logger1.getParent() + ",loggerName:" + logger1.getParent().getName());

    }
    

2.1.5 JUL配置文件

1、默认配置文件在jdk目录下:\Program Files\Java\jdk1.8.0_211\jre\lib\logging.properties

############################################################
#  	Default Logging Configuration File
#
# You can use a different file by specifying a filename
# with the java.util.logging.config.file system property.  
# For example java -Djava.util.logging.config.file=myfile
############################################################

############################################################
#  	Global properties
############################################################

# "handlers" specifies a comma separated list of log Handler 
# classes.  These handlers will be installed during VM startup.
# Note that these classes must be on the system classpath.
# By default we only configure a ConsoleHandler, which will only
# show messages at the INFO and above levels.
handlers= java.util.logging.ConsoleHandler

# To also add the FileHandler, use the following line instead.
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers.  For any given facility this global level
# can be overriden by a facility specific level
# Note that the ConsoleHandler also has a separate level
# setting to limit messages printed to the console.
.level= INFO

############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################

# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

# Example to customize the SimpleFormatter output format 
# to print one-line log message like this:
#     <level>: <log message> [<date/time>]
#
# java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n

############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

# For example, set the com.xyz.foo logger to only log SEVERE
# messages:
com.xyz.foo.level = SEVERE

2、自定义配置文件

# RootLogger顶级父元素指定默认处理器为:ConsoleHandler
handlers= java.util.logging.ConsoleHandler


# RootLogger 顶级父元素默认的日志级别为:INFO
.level= INFO


# 向日志文件输出的handler 对象
# 指定日志文件路径
java.util.logging.FileHandler.pattern = /logs/test.log
#指定日志文件大小
java.util.logging.FileHandler.limit = 50000
#指定日志文件个数
java.util.logging.FileHandler.count = 1
#指定日志内容的格式
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter


# 向控制塔输出的 handler对象
# 指定handler的日志输出级别
java.util.logging.ConsoleHandler.level = INFO
# 指定 handler对象的日志消息格式对象
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 loggerProperties() throws IOException {
        //读取配置文件,通过类加载器加载
        InputStream inputStream = JulTest.class.getClassLoader().getResourceAsStream("logging.properties");

        //创建LogManager
        LogManager logManager = LogManager.getLogManager();

        //通过LogManager设置配置信息
        logManager.readConfiguration(inputStream);

        //创建日志记录器
        Logger logger = Logger.getLogger("com.cmb.jultest");

        //测试
        logger.severe("测试severe");
        logger.warning("测试warning");
        logger.info("测试info");
        logger.config("测试config");
        logger.fine("测试fine");
        logger.finer("测试finer");
        logger.finest("测试finest");
    }

2.2 Log4j学习

2.2.1 Layout日志信息格式

org.apache.log4j.HTMLLayout(以HTML格式布局),
org.apache.log4j.xml.XMLLayout(以XML格式布局),
org.apache.log4j.PatternLayout(可以灵活地自定义布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

2.2.2 appender

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

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

以下测试代码为实例:

   <dependencies>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
package com.log.log4jtest;

import org.apache.log4j.Logger;

public class Log4jTest {
    public static void main(String[] args) {
        //开启log4j内部日志记录
       // LogLog.setInternalDebugging(true);

        Logger logger = Logger.getLogger(Log4jTest.class);

        for (int i = 0; i < 5000; i++) {
            logger.fatal("fatal");
            logger.error("error");
            logger.warn("warn");
            logger.info("info");
            logger.debug("debug");
            logger.trace("trace");
        }
    }
}
2.2.2.1 ConsoleAppender配置

log4j.xml配置如下:

# 指定 RootLogger顶级父元素默认配置信息
# 指定日志级别=trace,使用的 appender为=console
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 = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss} %m%n

日志输出效果如下:

[FATAL]1852 Log4jTest.main(Log4jTest.java:11) 2021-06-26 16:46:59 fatal
[ERROR]1852 Log4jTest.main(Log4jTest.java:12) 2021-06-26 16:46:59 error
[WARN]1852 Log4jTest.main(Log4jTest.java:13) 2021-06-26 16:46:59 warn
[INFO]1852 Log4jTest.main(Log4jTest.java:14) 2021-06-26 16:46:59 info
[DEBUG]1852 Log4jTest.main(Log4jTest.java:15) 2021-06-26 16:46:59 debug
[TRACE]1852 Log4jTest.main(Log4jTest.java:16) 2021-06-26 16:46:59 trace
2.2.2.2 FileAppender配置

log4j.xml配置如下:

# 指定 RootLogger顶级父元素默认配置信息
# 指定日志级别=trace,使用的 appender为=file
log4j.rootLogger = trace,file 
# 日志文件输出的 appender 对象
log4j.appender.file = org.apache.log4j.FileAppender
# 指定消息格式 layout
log4j.appender.file.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
log4j.appender.file.layout.conversionPattern =  [%p]%r %l %d{yyyy-MM-dd HH:mm:ss} %m%n
# 指定日志文件保存路径
log4j.appender.file.file = /logs/log4j.log
# 指定日志文件的字符集
log4j.appender.file.encoding = UTF-8

日志输出效果:
在这里插入图片描述

2.2.2.3 RollingFileAppender配置

log4j.xml配置如下:

log4j.rootLogger = trace,rollingFile 
# 按照文件大小拆分的appender对象
log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender
# 指定消息格式 layout
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
log4j.appender.rollingFile.layout.conversionPattern =  [%p]%r %l %d{yyyy-MM-dd HH:mm:ss} %m%n
# 指定日志文件保存路径
log4j.appender.rollingFile.file = /logs/log4j.log
# 指定日志文件的字符集
log4j.appender.rollingFile.encoding = UTF-8
# 指定单个文件大小
log4j.appender.rollingFile.maxFileSize = 1048576
# 指定文件个数
log4j.appender.rollingFile.maxBackupIndex=10

日志输出效果:
在这里插入图片描述

2.2.2.4 DailyRollingFileAppender配置

log4j.xml配置如下:

log4j.rootLogger = trace,dailyFile
# 按照时间规则拆分的appender对象
log4j.appender.dailyFile = org.apache.log4j.DailyRollingFileAppender
# 指定消息格式 layout
log4j.appender.dailyFile.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
log4j.appender.dailyFile.layout.conversionPattern =  [%p]%r %l %d{yyyy-MM-dd HH:mm:ss} %m%n
# 指定日志文件保存路径
log4j.appender.dailyFile.file = /logs/logs/log4j.log
# 指定日志文件的字符集
log4j.appender.dailyFile.encoding = UTF-8
# 指定文件拆分规则
log4j.appender.dailyFile.datePattern = '.'yyyy-MM-dd-HH-mm-ss

日志输出效果:
在这里插入图片描述

2.2.3 Layouts

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

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

2.2.4 Layout的格式

log4j采用类似 C语言的printf函数的打印格式格式化日志信息,具体的占位符及其含义如下:
#%m 输出代码中指定的日志信息
#%p 输出优先级,及 DEBUG、INFO 等
#%n 换行符(Windows平台的换行符为 "\n",Unix 平台为 "\n")
#%r 输出自应用启动到输出该 log 信息耗费的毫秒数
#%c 输出打印语句所属的类的全名
#%t 输出产生该日志的线程全名
#%d 输出服务器当前时间,默认为 ISO8601,也可以指定格式,如:%d{yyyy年MM月dd日 HH:mm:ss}
#%l 输出日志时间发生的位置,包括类名、线程、及在代码中的行数。如:
#Test.main(Test.java:10)
#%F 输出日志消息产生时所在的文件名称
#%L 输出代码中的行号
#%% 输出一个 "%" 字符

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

    %5c 输出category名称,最小宽度是5,category<5,默认的情况下右对齐
    %-5c 输出category名称,最小宽度是5,category<5,"-"号指定左对齐,会有空格
    %.5c 输出category名称,最大宽度是5,category>5,就会将左边多出的字符截掉,<5不
    会有空格
    %20.30c category名称<20补空格,并且右对齐,>30字符,就从左边交远销出的字符截掉

2.2.5 自定义logger

log4j.rootLogger = trace,console

# 自定义Logger 对象设置
# 自定义日志级别: com.log.log4jtest下的日志采用info级别,使用file
log4j.logger.com.log.log4jtest = info,file

日志输出效果:
com.log.log4jtest包下的日志级别都是info以上
在这里插入图片描述


2.3 JCL学习(淘汰)

全称为Jakarta Commons Logging,是Apache提供的一个通用日志API。
它是为“所有java日志实现”提供一个统一的接口,它自身也提供了一个日志实现,但是功能非常弱(SimpleLog)。所以一般不会单独使用它。它允许你开发人员使用不同的具体日志实现工具:Log4j,Jdk自带的日志JUL
JCL有两个基本抽象类:Log(基本记录器)和LogFactory(负责创建Log实例)


2.4 Slf4j 学习

slf4j调用逻辑图
在这里插入图片描述

slf4j是日志门面,依赖具体的日志实现。
slf4j只能同时导入一个日志实现,导入多个日志实现会报错。

依赖:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.32</version>
</dependency>

2.4.1 slf4j + log4j

log4j 和 slf4j 结合使用,需要使用适配器
依赖:

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.32</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.32</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

log4j.properties配置:

log4j.rootLogger=INFO,console
log4j.additivity.org.apache=true
#console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=INFO
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%p] %m%n

测试代码:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class Slf4jLog4j {
    private final static Logger logger = LoggerFactory.getLogger(Slf4jLog4j.class);
    public static void main(String[] args) {
        logger.error("测试");
        logger.info("info级别");
    }
}

测试结果:

2021-09-25 23:20:38 [ERROR] 测试
2021-09-25 23:20:38 [INFO] info级别

2.5 logback学习

logback比log4j性能高

学习产出:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值