文章目录
简介
开源项目Log4j
是一个功能强大的日志组件,提供方便的日志记录功能,能够根据配置将日志输出到不同的地方。日志在任何程序系统是不可缺少的,好的日志记录一定会给系统的维护带来巨大的帮助。
更多的介绍可以参考官方链接:
官网Log4j 1.x
官网Log4j 2.x
1.x 版本已经不再更新了,现在都是转为2.x (包括支持Lambda)
简单的例子
首先通过一个简单的例子,我们来认识下log4j的配置。
pom dependency
创建一个maven项目,以1.2.17版本为例,在pom.xml 文件中增加以下配置: maven会自动下载log4j-1.2.17.jar 到项目中
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
配置文件
Log4j
支持两种格式的配置文件:
.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders 日志信息输出目的地 -->
<!-- ConsoleAppender -->
<!-- 每个ConsoleAppender都有一个target,表示它的输出目的地。 -->
<!-- 它可以是System.out,标准输出设备(缓冲显示屏) -->
<!-- 或者是System.err,标准错误设备(不缓冲显示屏) -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %c - %m%n" />
</layout>
</appender>
<!-- RollingFileAppender 回滚文件 -->
<!-- ImmediateFlush, 一旦有新日志,马上写入文件,如果日志很多,会有性能问题,为了提高日志写入文件的性能,可以结合使用BufferedIO和BufferSize -->
<!-- Append true,默认每次启动系统,日志继续输出到原来的文件 -->
<!-- MaxFileSize 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件 -->
<!-- MaxBackupIndex 最多20个 -->
<!-- PatternLayout 控制日志输出的格式化 -->
<!-- filter 级别范围过滤器 -->
<!-- levelMin levelMax 范围 -->
<appender name="all" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="D:/logs/all.log" />
<param name="ImmediateFlush" value="true"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="10MB"/>
<param name="MaxBackupIndex" value="20"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %c - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="DEBUG" />
<param name="levelMax" value="ERROR" />
<param name="AcceptOnMatch" value="true" />
</filter>
</appender>
<!-- 为了测试 -->
<appender name="File" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="D:/logs/log.log" />
<param name="Append" value="true"/>
<param name="MaxFileSize" value="10MB"/>
<param name="MaxBackupIndex" value="20"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %c - %m%n" />
</layout>
</appender>
<!-- 下面这些就是根据 这些路径来控制对应包下的文件的日志输出级别,基本上都是输出error日志-->
<logger name="org.springframework.core">
<level value="error" />
</logger>
<logger name="org.springframework.beans">
<level value="error" />
</logger>
<logger name="org.springframework.context">
<level value="error" />
</logger>
<logger name="org.springframework.http">
<level value="error" />
</logger>
<logger name="org.springframework.web">
<level value="error" />
</logger>
<logger name="org.elasticsearch.client.transport">
<level value="debug" />
</logger>
<logger name="org.springframework.data.mongodb">
<level value="error" />
</logger>
<!-- 这个就是自定义的一个logger -->
<!-- additivity 这个默认是true,即继承父类 root logger -->
<!-- 也就是说,你的这个日志也会在root的logger里面输出的,我这里配置false,就是不继承,各走各的。 -->
<!-- appender-ref 也就是说这个logger的输出目的地是哪里,ref就是关联到上面声明的一个all,一个console -->
<logger name="allLog" additivity="false">
<level value="debug" />
<appender-ref ref="all" />
<appender-ref ref="console" />
</logger>
<!-- 根logger -->
<!-- 输出级别是info级别及以上的日志,下面的ref关联的两个appender没有filter设置,所以,info及以上的日志都是会输出到这2个appender中 -->
<root>
<priority value="info" />
<appender-ref ref="console" />
<appender-ref ref="File" />
</root>
</log4j:configuration>
实战经验:
上面定义了很多logger,对于包名(一般是自己项目真实的包)的判断,我们可以写一个公共方法来根据规则截取特定内容,然后通过下面的方式来获得Logger,然后将日志输出到特定文件:
例如:
static Logger logger2 = Logger.getLogger("org.springframework.core");
另一种方式:
如果只想要将某些包或者类下的日志输出到指定日志文件,可以使用category属性:
<category name="com.xxx.xxx" additivity="false">
<level value="INFO" />
<appender-ref ref="all" />
</category>
.properties文件
使用的较多一些
示例:log4j.properties文件,其中以 ### 开头表示是注释
log4j.rootLogger = debug, stdout, D, E
### 输出信息到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG级别及以上级别的日志到 D:\logs\log.log文件中 ###
log4j.appender.D = org.apache.log4j.RollingFileAppender
### 文件目录及文件 ###
log4j.appender.D.File = D:\\logs\\log.log
### 最大文件大小 ###
log4j.appender.D.MaxFileSize = 100kb
### 备份文件个数 ###
log4j.appender.D.MaxBackupIndex = 10
### 往后追加 ###
log4j.appender.D.Append = true
### 可以指定日志level,例如这里就是输出DEBUG级别及以上级别的日志###
log4j.appender.D.Threshold = DEBUG
### 日志布局格式 ###
log4j.appender.D.layout = org.apache.log4j.PatternLayout
### 日志输出格式 ###
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %c - %m%n
### 输出ERROR 级别以上的日志到 D:\logs\error.log 文件中 ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =D:\\logs\\error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %c - %m%n
注意appender的Threshold 属性的作用,上面有注释说明。
使用
在代码中使用,步骤如下:
获取日志记录器
一般情况下,在一个类中,会通过该类名来获取,或者,根据logger名字来获取,如下例子,在maven项目中的App.java类中
static Logger logger = Logger.getLogger(App.class.getName());
或者
static Logger logger2 = Logger.getLogger("allLog");
// allLog是上面log4j.xml中定义的logger
读取配置文件
笔者测试时,是创建的maven项目,需要注意下面:
当配置文件放在src/main/resources的目录下时,直接可以写入log信息(从log4j 0.8.5版本起, 在类初始化的时候, log4j.properties(log4j.xml)文件将从用于加载类的路径中被查找,如果配置文件被发现,那将调用configure()方法来初始化log4j)。
public class App {
static Logger logger = Logger.getLogger(App.class.getName());
public static void main(String[] args) throws IOException {
System.out.println("Hello World!");
logger.debug("debug message");
logger.info("info message");
logger.warn("warn message");
logger.error("error message");
}
}
当配置文件不是直接放在src/main/resources的目录下时,需要加载properties文件,例如在src/main/resources/logging文件夹下,使用下面的方式来加载,当然这里也可以使用绝对路径:
public class App {
static Logger logger = Logger.getLogger(App.class.getName());
public static void main(String[] args) throws IOException {
PropertyConfigurator.configure("src/main/resources/logging/log4j.properties");
System.out.println("Hello World!");
logger.debug("debug message");
logger.info("info message");
logger.warn("warn message");
logger.error("error message");
}
}
写入log信息
调用下面的方法即可:
logger.debug(Object message);
logger.info(Object message);
logger.warn(Object message);
logger.error(Object message);
如果使用log4j.xml配置文件,可以做下面的测试,使用2个Logger,然后观察log输出情况:
public class App {
static Logger logger = Logger.getLogger(App.class.getName());
static Logger logger2 = Logger.getLogger("allLog");
public static void main(String[] args) throws IOException {
System.out.println("Hello World!");
logger.debug("debug message");
logger.info("info message");
logger.warn("warn message");
logger.error("error message");
logger2.debug("debug message");
logger2.info("info message");
logger2.warn("warn message");
logger2.error("error message");
}
}
可以观察console的输出、产生的log文件名及内容。
其中logger使用了root的Logger定义,产生文件D:/logs/log.log,包括INFO级别以上的日志信息,如图:
其中logger2使用了allLog的Logger定义,产生文件D:/logs/all.log,包DEBUG到ERROR级别的日志信息,如图:
注意到,格式%c产生的效果也是不同的
三大组件
Logger
根logger
主要定义log4j支持的日志级别及输出目的地,其语法为:
log4j.rootLogger = [ level ] , appenderName, appenderName, …
其中,level 是日志记录的优先级,下面列出的级别(优先级从高到低)或者自定义的级别。不区分大小写。
Log4J推荐使用:DEBUG, INFO, WARN, ERROR
OFF 为最高等级 关闭了日志信息
FATAL 为可能导致应用中止的严重事件错误
ERROR 为严重错误 主要是程序的错误
WARN 为一般警告,比如session丢失
INFO 为一般要显示的信息,比如登录登出
DEBUG 为程序的调试信息
TRACE 为比DEBUG更细粒度的事件信息
ALL 为最低等级,将打开所有级别的日志
appenderName指定日志信息输出到哪个地方,可同时指定多个输出目的地。需在控制台输入,只需将其中一个appender定义为stdout即可。
注意: rootLogger 默认是对整个工程生效的。
Appender
Appender主要定义日志信息输出在什么位置,主要语法为:
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
…
log4j.appender.appenderName.optionN = valueN
Log4j提供的appender有以下几种:
org.apache.log4j.ConsoleAppender(控制台),
org.apache.log4j.FileAppender(文件),
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
org.apache.log4j.JDBCAppender(将日志信息保存到数据库中)
以ConsoleAppender为例,如:
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
Layout
Layout 负责格式化Appender的输出格式,其语法为:
log4j.appender.appenderName.layout = fully.qualified.name.of.appender.class
log4j.appender.appenderName.layout.option1 = value1
…
log4j.appender.appenderName.layout.optionN = valueN
其中,Log4j提供的layout有以下几种:
org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)
注意日志输出格式:
例如:
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%.30t] %c %x - %m%n
%c 输出日志信息所属的类的全名
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy-M-dd HH:mm:ss },输出类似:2002-10-18- 22:10:28
%f 输出日志信息所属的类的类名
%l 输出日志事件的发生位置,即输出日志信息的语句处于它所在的类的第几行
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL。如果是调用debug()输出的,则为DEBUG,依此类推,例如,用法%-5p,固定优先级的长度为5个字符
%r 输出自应用启动到输出该日志信息所耗费的毫秒数
%t 输出产生该日志事件的线程名, 例如,用法 [%.30t],限制线程名的长度为最后39个字符。
%x 按NDC(Nested Diagnostic Context,线程堆栈)顺序输出日志
%m 输出代码中指定的信息,如log(message)中的message
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
Web应用中使用
简单的例子说明在web中的使用。
定义一个Initialization servlet
import org.apache.log4j.PropertyConfigurator;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.IOException;
public class Log4jInit extends HttpServlet {
public
void init() {
String prefix = getServletContext().getRealPath("/");
String file = getInitParameter("log4j-init-file");
// if the log4j-init-file is not set, then no point in trying
if(file != null) {
PropertyConfigurator.configure(prefix+file);
}
}
public
void doGet(HttpServletRequest req, HttpServletResponse res) {
}
}
在web.xml文件中申明
<servlet>
<servlet-name>log4j-init</servlet-name>
<servlet-class>com.foo.Log4jInit</servlet-class>
<init-param>
<param-name>log4j-init-file</param-name>
<param-value>WEB-INF/classes/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/155837.html