Java 日志框架 Log4J

引言

Java 日志框架 JUL

在这篇文章中已经向大家介绍了我们为什么要使用日志文件、常见的日志框架、日志框架的发展历程、还向大家介绍了一个Java原生的一个日志框架JUL。我们在说日志文件的发展历程的时候提到Log4J2是现在最优秀的Java日志框架,Log4J当前已经停止维护,不建议使用。但是Log4是Log4J2的前身,Log4J2是在Log4J的基础上做的改进。

知其然并知其所以然 今天我们来聊一下另外一个日志框架Log4J。

什么是Log4J

Log4J是Apache开源项目,通过使用Log4J,我们可以控制日志信息输送的目的地是控制台、文件、数据库等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

Log4J三大组件

Loggers(日志记录器)

Loggers(日志记录器):负责收集处理日志记录,获取logger实例可通过类名或者全限定名获取,并且对于名称具有继承机制。

从log4J 1.2以来,Logger类取代了Category类,Logger类可以视作Category类的别名。

在Log4J中包含一个特殊的loggerrootlogger,它是所有logger的根,其他logger会直接或间接的继承该rootlogger,可使用Logger.getLogger()获取。

Appender(输出端)

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

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

Layout(日志格式化器)

用于控制日志输出内容的格式,通过使用不同的Layout类型来指定各种需要的格式。

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

Log4J日志级别

Log4J 在 org.apache.log4j.Level 类中定义了OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL七种日志级别:

级别含义
OFF最高日志级别,关闭左右日志
FATAL将会导致应用程序退出的错误
ERROR发生错误事件,但仍不影响系统的继续运行
WARN警告,即潜在的错误情形
INFO一般和在粗粒度级别上,强调应用程序的运行全程
DEBUG一般用于细粒度级别上,对调试应用程序非常有帮助
ALL最低等级,打开所有日志记录

一般只使用4个级别,优先级从高到低为 ERROR > WARN > INFO > DEBUG

Log4J基本使用

我们知道Log4J是Apache开源项目,那么我们在使用时,需要引入Jar包。

<dependencies>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
</dependencies>

我们这里先不使用配置文件,直接使用BasicConfigurator.configure() 初始化系统配置,如果我们不使用配置文件又不使用BasicConfigurator.configure() 初始化系统配置将会报错。

public class LogTest {
    public static void main(String[] args) {
        //初始化系统配置,不需要配置文件
        BasicConfigurator.configure();
        //获取logger实例,注意这里的Logger是Log4j的
        Logger logger = Logger.getLogger(LogTest.class);
        //打印不同的日志等级
        logger.fatal("fatal");
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace");
    }
}

当通过调用方法进行配置时,logger实例的父属性rootloggerappenderConsoleAppender(formatterSimpleFormatter),logger实例的日志等级为DEBUG。所以trace等级的日志并不会输出。

自定义配置文件

将自定义配置文件log4j.properties放置到resource目录下

#rootLogger配置 第一个参数为日志等级,第二个参数为appender
log4j.rootLogger = trace,console
#console只是作为指定appender的别名
log4j.appender.console = org.apache.log4j.ConsoleAppender
#设置ConsoleAppender的layout为SimpleLayout
log4j.appender.console.layout = org.apache.log4j.SimpleLayout
public class LogTest {
    public static void main(String[] args) {
        //获取logger实例
        Logger logger = Logger.getLogger(LogTest.class);
        //打印6个不同的日志等级
        logger.fatal("fatal");
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace");
    }
}

当通过配置文件进行配置时,所有级别都输出了。

# 设置rootlogger日志等级为trace、指定appender为下面定义的ConsoleAppender
log4j.rootLogger = trace,console
# 指定ConsoleAppender设置别名为console
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定ConsoleAppender的layout设置为PatternLayout
log4j.appender.console.layout = org.apache.log4j.PatternLayout
# 设置该layout的自定义格式(解析时会调用)
log4j.appender.console.layout.ConversionPattern= [%-5p]%r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

专对于PatternLayout类中的pattern自定义格式说明

# 占位符相关含义
%p: 输出优先级,及 DEBUG、INFO 等
%m: 输出代码中指定的日志信息
%n: 换行符(Windows平台的换行符为 "\n",Unix 平台为 "\n")
%r: 输出自应用启动到输出该 log 信息耗费的毫秒数
%d: 输出服务器当前时间,默认为 ISO8601,也可以指定格式,如:%d{yyyy-MM-dd HH:mm:ss:SSS}  => 年月日 时分秒毫秒

%l: 输出日志时间发生的位置,包括类名、线程、及在代码中的行数。如:Test.main(Test.java:10)
	# %l即可表示下方四个修饰符
    %c: 输出打印语句所属的类的全名
    %t: 输出产生该日志的线程全名
    %F: 输出日志消息产生时所在的文件名称
    %L: 输出代码中的行号
%%: 输出一个 "%" 字符

# 可在例如%m之间加入修饰符来控制最小宽度、最大宽度和文本的对其方式
%5c: 输出category名称,最小宽度是5,category<5,默认的情况下右对齐
%-5c: 输出category名称,最小宽度是5,category<5,"-"号指定左对齐,会有空格
%.5c: 输出category名称,最大宽度是5,category>5,就会将左边多出的字符截掉,<5不会有空格
%20.30c: category名称<20补空格,并且右对齐,>30字符,就从左边交远销出的字符截掉

public class LogTest {
    public static void main(String[] args) {
        //开启LogLog的debug模式
        LogLog.setInternalDebugging(true);
        //获取logger实例
        Logger logger = Logger.getLogger(LogTest.class);
        //打印不同的日志等级
        logger.fatal("fatal");
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace");
    }
}

Appender示例

FileAppender

FileAppender:用于输出到文件,其有两个实现类,DailyRollingFileAppender提供了轮询功能(可根据指定时间点添加文件)、RollingFileAppender提供了根据文件大小拆分的功能。

log4j.rootLogger = trace,file
# FileAppender
#  file为名称   其中属性file:文件路径   encoding:编码
log4j.appender.file = org.apache.log4j.FileAppender
log4j.appender.file.file = C:/Users/93997/Desktop/projectexers/logs/log.txt
log4j.appender.file.encoding = UTF-8
#  设置自定义布局(自定义输出格式)
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern= [%-5p]%r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

public class LogTest {
    public static void main(String[] args) {
        //开启LogLog的debug模式
        LogLog.setInternalDebugging(true);
        //获取logger实例
        Logger logger = Logger.getLogger(LogTest.class);
        //打印不同的日志等级
        logger.fatal("fatal");
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace");
    }
}

DailyRollingFileAppender

轮询功能(根据指定是每小时,还是每天输出log日志)

# 日志等级为trace,指定appender为下面以roll作为别名的
log4j.rootLogger = trace,roll
# DailyRollingFileAppender 轮询
log4j.appender.roll = org.apache.log4j.DailyRollingFileAppender
log4j.appender.roll.file = /logs/log4j.log
log4j.appender.roll.encoding = UTF-8
# datePattern指的是根据分钟来进行轮询 可设置年月日时分秒毫秒如右: '.'yyyy-MM-dd-HH-mm-ss-SSS
log4j.appender.roll.datePattern = '.'yyyy-MM-dd-HH-mm
#  设置自定义布局(自定义输出格式)
log4j.appender.roll.layout = org.apache.log4j.PatternLayout
log4j.appender.roll.layout.ConversionPattern= [%-5p]%r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

public class LogTest {

    public static void main(String[] args) {
        //开启LogLog的debug模式
        LogLog.setInternalDebugging(true);

        //获取logger实例
        Logger logger = Logger.getLogger(LogTest.class);
        //打印不同的日志等级
        logger.fatal("fatal");
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace");
    }
}

image-20210305201500407

RollingFileAppender

按照指定文件大小进行拆分,拆分最大的文件数量可指定。

# 日志等级为trace,指定appender为下面以rollfile作为别名的
log4j.rootLogger = trace,rollfile
# RollingFileAppender 分段
log4j.appender.rollfile = org.apache.log4j.RollingFileAppender
log4j.appender.rollfile.file = /logs/log4j.log
log4j.appender.rollfile.encoding = UTF-8
# 设置单个文件最大容量(KB、MB、GB,其他单位默认传为10MB+1)以及最大文件个数 
log4j.appender.rollfile.maxFileSize = 1MB
log4j.appender.rollfile.maxBackupIndex = 5
#  设置自定义布局(自定义输出格式)
log4j.appender.rollfile.layout = org.apache.log4j.PatternLayout
log4j.appender.rollfile.layout.ConversionPattern= [%-5p]%r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

public class LogTest {
    public static void main(String[] args) {
        //开启LogLog的debug模式
        LogLog.setInternalDebugging(true);
        //获取logger实例
        Logger logger = Logger.getLogger(LogTest.class);
        for (int i = 0; i < 1000000; i++) {
            //打印不同的日志等级
            logger.fatal("fatal");
            logger.error("error");
            logger.warn("warn");
            logger.info("info");
            logger.debug("debug");
            logger.trace("trace");
        }
}

image-20210305203429897

JDBCAppender

创建log表

CREATE TABLE `log` (
`log_id` int(11) NOT NULL AUTO_INCREMENT,
`project_name` varchar(255) DEFAULT NULL COMMENT '目项名',
`create_date` varchar(255) DEFAULT NULL COMMENT '创建时间',
`level` varchar(255) DEFAULT NULL COMMENT '优先级',
`category` varchar(255) DEFAULT NULL COMMENT '所在类的全名',
`file_name` varchar(255) DEFAULT NULL COMMENT '输出日志消息产生时所在的文件名称 ',
`thread_name` varchar(255) DEFAULT NULL COMMENT '日志事件的线程名',
`line` varchar(255) DEFAULT NULL COMMENT '号行',
`all_category` varchar(255) DEFAULT NULL COMMENT '日志事件的发生位置',
`message` varchar(4000) DEFAULT NULL COMMENT '输出代码中指定的消息',
PRIMARY KEY (`log_id`)
);

引入mysql驱动

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.32</version>
</dependency>

配置连接信息

# rootlogger的日志等级是trace,appender为JDBCAppender,logDB是下面指定的别名
log4j.rootLogger = trace,logDB
# 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=root
log4j.appender.logDB.Password=123456
log4j.appender.logDB.Sql=INSERT INTO log(project_name,create_date,level,category,file_name,thread_name,line,all_category,message) values('changlu','%d{yyyy-MM-ddHH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')

public static void main(String[] args) {
    //开启LogLog的debug模式
    LogLog.setInternalDebugging(true);
    //获取logger实例
    Logger logger = Logger.getLogger(LogTest.class);
    for (int i = 0; i < 1000000; i++) {
        //打印不同的日志等级
        logger.fatal("fatal");
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace");
    }
}

自定义Logger

通过使用自定义Logger能够将第三方包下调用的类以及自己定义的类进行日志区分,对于自己的类的日志信息输出到文件中,而对于第三方包的类输出到屏幕上。

# rootLogger日志等级为trace,输出到屏幕上
log4j.rootLogger = trace,console
# 设置两个自定义logger
# xu.enbei(自己创建的包)自定义logger,日志等级为info,输出到文件
log4j.logger.xu.enbei = info,file
# 设置org.apache(第三方包)作为一个自定义logger,日志等级为error
log4j.logger.org.apache = err
# console
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern= [%-5p]%r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
# FileAppender
#  file:文件路径   encoding:编码
log4j.appender.file = org.apache.log4j.FileAppender
log4j.appender.file.file = C:/Users/93997/Desktop/projectexers/logs/log.log
log4j.appender.file.encoding = UTF-8
#  设置自定义布局(自定义输出格式)
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern= [%-5p]%r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

public class LogTest {
    public static void main(String[] args) {
        //开启LogLog的debug模式
        LogLog.setInternalDebugging(true);
        //自己包下类的自定义logger实例
        //getLogger()参数为xu.enbei包下的类,所以获取到配置文件中xu.enbei的logger实例
        //logger实例与rootLogger的日志等级都为INFO,本身实例输出到文件,rootLogger输出到窗口
        Logger logger = Logger.getLogger(LogTest.class);
        System.out.println(logger.getName());
        //打印不同的日志等级
        logger.fatal("fatal");
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace")
        // org.Apache包下的自定义logger实例,只输出到屏幕(本身实例没有设置logger)
        // 本身实例与rootLogger日志等级为error
        Logger logger1 = Logger.getLogger(Logger.class);
        System.out.println(logger1.getName());
        logger1.fatal("fatal logger1");
        logger1.error("error logger1");
        logger1.warn("warn logger1");
        logger1.info("info logger1");
        logger1.debug("debug logger1");
        logger1.trace("trace logger1");
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值