Java 日志框架 Log4J

news2024/11/23 12:05:22

文章目录

    • 引言
    • 什么是Log4J
    • Log4J三大组件
    • Log4J日志级别
    • Log4J基本使用
    • 自定义配置文件
    • Appender示例
      • FileAppender
      • DailyRollingFileAppender
      • RollingFileAppender
      • JDBCAppender
    • 自定义Logger

引言

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");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/168724.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

张力调节(精密调节气阀应用)

跳舞轮对应张力调节范围&#xff0c;我们可以通过改变气缸的气压方式间接改变&#xff0c;张力跳舞轮在收放卷闭环控制上的详细应用&#xff0c;可以参看下面的文章链接&#xff0c;这里我们主要讨论精密可调气阀的模拟量编程问题。 PLC张力控制&#xff08;开环闭环算法分析&…

【实践向】当移除了三级缓存……

本文会手把手带你一起把使用二级缓存替换三级缓存&#xff0c;看下移除了三级缓存&#xff0c;只有二级缓存会出什么问题&#xff0c;用实践回答那个被问了无数次的“为什么要有三级缓存&#xff1f;”以及“二级缓存解决不了循环依赖问题吗&#xff1f;”等类似问题(&#xff…

“Flash配置不当漏洞”详解

危害 可被用来进行跨域访问&#xff0c;可能会导致“跨站点伪造请求”或“跨站点跟踪”&#xff08;“跨站点脚本编制”的变体&#xff09;之类的攻击&#xff0c;从而导致其它用户的信息被非法读取。 导致不受信任的第三方域的flash也能访问当前域的资源&#xff0c;绕过同源策…

一、构建自己的图像分类数据集(Datawhale组队学习)

文章目录安装配置环境图像采集采集函数爬取一类图片爬取多类图片一些参考类别的关键词制作图像分类数据集的注意事项删除多余文件删除系统自动生成的多余文件删除gif格式的图像文件删除非三通道的图像统计图像尺寸、比例分布采用的数据集统计数据集的基本信息可视化图像尺寸分布…

Embarcadero Dev-C++第一次使用注意事项

Embarcadero Dev-C第一次使用注意事项 Embarcadero Dev-C简介 2000年左右&#xff0c;Bloodshed software开发了Dev-C &#xff0c;提供轻量、免费、开源的C/CIDE。Dev-C是最适合初学C语言的IDE之一&#xff0c;但至2015年Dev C5.11&#xff0c;停止了更新维护了。 后来&…

springboot,vue电影院售票系统

开发工具&#xff1a;IDEA服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8项目构建&#xff1a;maven数据库&#xff1a;mysql5.7系统用户前台和管理后台两部分&#xff0c;项目采用前后端分离前端技术&#xff1a;vue elementUI服务端技术&#xff1a;springbootmybatis项目功…

pom文件中自定义的repository不生效

问题描述 对应的pom中依赖获取失败 pom文件依赖配置如下: <dependencies><dependency><groupId>it.geosolutions</groupId><artifactId>geoserver-manager</artifactId><version>1.7.0</version><exclusions><excl…

verilog学习笔记- 15)动态数码管显示实验

目录 简介&#xff1a; 实验任务&#xff1a; 硬件设计&#xff1a; 程序设计&#xff1a; 下载验证&#xff1a; 简介&#xff1a; 由于一般的静态驱动操作虽然方便&#xff0c;但占用的 I/0 口较多&#xff0c;例如要驱动6 位 8 段数码管&#xff0c;以静态驱动方式让数…

值得收藏的30道Python基础练手题(附详解)

今天给大家分享30道Python练习题&#xff0c;建议大家先独立思考一下解题思路&#xff0c;再查看答案。 1. 已知一个字符串为 “hello_world_JMzz”&#xff0c;如何得到一个队列 [“hello”,”world”,”JMzz”] &#xff1f; 使用 split 函数&#xff0c;分割字符串&…

ESP8266 ArduinoIDE 闪存文件操作系统

一、闪存文件系统基本操作 esp8266 的采用 SPIFFS 嵌入式文件系统&#xff0c;在内部 Flash 为 4M&#xff0c;其中 1M 用于存储程序&#xff0c;其他的空间有一部分用于系统&#xff0c;3M 中剩下的大部分空间可以用来存放文件。 其中这个空间大小是可以自定义的&#xff0c;…

【Node.js实战】一文带你开发博客项目之安全(sql注入、xss攻击、md5加密算法)

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;也会涉及到服务端 &#x1f4c3;个人状态&#xff1a; 在校大学生一枚&#xff0c;已拿多个前端 offer&#xff08;秋招&#xff09; &#x1f680;未…

Netty进阶

三. Netty 进阶 1. 粘包与半包 1.1 粘包现象 服务端代码 public class HelloWorldServer {static final Logger log LoggerFactory.getLogger(HelloWorldServer.class);void start() {NioEventLoopGroup boss new NioEventLoopGroup(1);NioEventLoopGroup worker new Ni…

想要全面了解DevOps,从概念、实现相关工具到如何落地,看这篇就够了

我们总是在提DevOps&#xff0c;敏捷管理&#xff0c;但大家未必真的明白什么是DevOps。本文是将向大家介绍到底什么是DevOps&#xff0c;DevOps的初衷到底是为了解决什么问题&#xff1f;它能够如何实现&#xff1f;能够带来哪些价值&#xff1f;来让大家对DevOps有一个全面的…

Vscode++Opencv+Anaconda+Python安装教程

最近在学习opencv的时候vscode一直报这个错&#xff1a; Import “cv2” could not be resolved Pylance (reportMissingImports) 但是在Jupyter上面可以运行&#xff0c;一直没找到解决方法&#xff0c;无奈只好重装。 一&#xff1a;安装AnacondaPython 进入Anaconda官网 w…

计网必会:封装、协议、解封装

文章目录解释什么是封装什么是协议解封装是啥封装过程拓展知识需要了解解释 什么是封装 封装就是给初始的数据增加“数据”&#xff0c;让原始数据的信息量扩大&#xff0c;方便层与层间的交流&#xff0c;所谓封装&#xff0c;就是包装的意思&#xff0c;中文博大精深哈哈哈…

03.指针的进阶2.练习题(重点)

1.指针和数组笔试题解析 //1. sizeof(数组名)&#xff0c;数组名表示整个数组。计算的是整个数组的大小,单位是字节 //2. &数组名&#xff0c;数组名表示整个数组。取出的是整个数组的地址 //除此之外&#xff0c;所有的数组名都是数组首元素的地址 EG1:整型 int main…

爬虫学习笔记

目录一、Python基础知识回顾1、pip下载源2、pycharm设置作者信息3、python注释4、变量4.1 类型转换二、Urllib使用一、Python基础知识回顾 1、pip下载源 pip install python包默认是从 https://files.pythonhosted.org/ 网站&#xff08;国外网站&#xff09;上下载&#xff…

CV【3】:drop_out drop_path

文章目录前言1. drop_out1.1. 出现的原因1.2. 概念1.3. 工作原理1.4. 尺度匹配问题1.5. 有效缓解过拟合的原因1.6. 代码实现2. drop_path2.1. 与 drop_out 的差异2.2. 工作原理2.3. 在网络中的应用2.4. 代码实现前言 本文主要对比了两种正则化方法&#xff1a;drop_out 和 dro…

Javascript 组合模式

组合模式 简介 组合模式将对象组合成树形结构&#xff0c;以表示“部分-整体”的层次结构。除了用来表示树形结构之外&#xff0c;组合模式的另一个好处是通过对象的多态性表现&#xff0c;使得用户对单个对象和组合对象的使用具有一致性 请求在树中传递的过程 在组合模式中&…

Express框架连接MySQL数据库操作

在上一篇中已经在Node.js中引入使用了mysql模块进行数据库的基本操作&#xff0c;在本篇当中在Express框架中来连接数据库以及操作数据库&#xff1b; Express 项目环境 这里是通过全局安装Express框架生产的项目环境&#xff0c;也可以通过局部安装的方式&#xff0c;安装过程…