Log4j教程

时间:2020-02-23 14:37:19  来源:igfitidea点击:

欢迎使用log4j教程。
Log4j是Java应用程序中最常用的日志记录框架。
在本log4j教程中,我们将介绍log4j的基础知识,它的配置,然后在Java独立应用程序中然后在Java Web应用程序中查看它的运行情况。

Log4j教程

在开始使用log4j示例之前,第一步是获取log4j jar。
有多种下载log4j jar的方法。

  • 我最喜欢的是通过Maven获取所有依赖项。
    您可以在pom.xml文件中添加以下依赖项以获取log4j jar。

  • 如果您使用gradle,则将依赖项添加为:'log4j:log4j:1.2.17'

  • 如果不使用任何构建工具,则可以从Apache Log4j Official页面下载log4j jar,并将其包含在项目类路径中。

Log4j配置

Log4j支持基于属性和基于XML的配置。
其中我将使用基于XML的配置,您可以在链接的文章中看到基于log4j属性的配置。

log4j.xml

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

log4j配置文件的最重要部分是:

  • Appenders:这里我们定义日志记录策略,例如使用哪种类型的appender类,例如" org.apache.log4j.ConsoleAppender"或者" org.apache.log4j.RollingFileAppender"。
    org.apache.log4j.PatternLayout用于定义日志记录模式。
    %d%d {Z} [%t]%-5p(%F:%L)-%m%n将附加时间,线程,日志记录级别,带有行号的类名。
    我们可以在log4j配置文件中定义任意数量的附加程序。

  • logger:用于在带有附加程序的Java包/类和日志记录级别之间提供映射。
    如您所见,单个记录器可以使用多个追加器。
    如果多个记录器与java类包匹配,则使用更具体的记录器。

  • root:当没有为Java包定义记录器时使用。
    例如,如果com.theitroad.beans包中包含某些类,则它将与任何记录器都不匹配。
    因此,根记录器将用于记录配置。

准备好log4j配置文件后,我们必须在代码中对其进行配置,然后才能真正开始记录日志。
下面是这样做的方法。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="https://jakarta.apache.org/log4j/"
	debug="false">

	<!-- console appender -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" 
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p %c{1} - %m%n" 
		</layout>
	</appender>
	
	<!-- rolling file appender -->
	<appender name="file" class="org.apache.log4j.RollingFileAppender">
		<param name="File" value="logs/main.log" 
		<param name="Append" value="true" 
		<param name="ImmediateFlush" value="true" 
		<param name="MaxFileSize" value="10MB" 
		<param name="MaxBackupIndex" value="5" 

		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d %d{Z} [%t] %-5p (%F:%L) - %m%n" 
		</layout>
	</appender>

	<logger name="com.theitroad.log4j" additivity="false">
		<level value="DEBUG" 
		<appender-ref ref="file" 
		<appender-ref ref="console" 
	</logger>

	<logger name="com.theitroad.log4j.logic" additivity="false">
		<level value="INFO" 
		<appender-ref ref="file" 
	</logger>

	<root>
		<priority value="DEBUG" 
		<appender-ref ref="file" 
		<appender-ref ref="console" 
	</root>

</log4j:configuration>

注意,如果我们的log4j配置文件名是log4j.xml或者log4j.properties,那么我们可以跳过此步骤,因为log4j会尝试自动从类路径中加载这些文件。

Java Log4j用法

现在,让我们看看如何在代码中使用它们。
我们为上面定义的记录器创建了两个类。

//for XML based configuration
DOMConfigurator.configure("log4j.xml");
//for properties based configuration
PropertyConfigurator.configure("log4j.properties");

我们可以一次创建一个最终的Logger实例,然后在整个类中重复使用它。
注意,我正在用init()方法配置log4j,该方法是在静态块中加载类时调用的。

package com.theitroad.log4j.main;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

import com.theitroad.log4j.logic.MathUtils;

public class Log4jExample {

	static{
		init();
	}
	
	private final static Logger logger = Logger.getLogger(Log4jExample.class);
	
	public static void main(String[] args) {

		logger.debug("My Debug Log");
		logger.info("My Info Log");
		logger.warn("My Warn Log");
		logger.error("My error log");
		logger.fatal("My fatal log");
		
		MathUtils.add(4,5);
		MathUtils.add(40,50);
		MathUtils.add(1,5);
		
	}

	/**
	 * method to init log4j configurations
	 */
	private static void init() {
		DOMConfigurator.configure("log4j.xml");
	}

}

现在,当我们在main方法之上运行时,我们将在main.log文件中获得以下日志。

package com.theitroad.log4j.logic;

import org.apache.log4j.Logger;

public class MathUtils {

	private static final Logger logger = Logger.getLogger(MathUtils.class);
	
	public static int add(int x, int y){
		logger.debug("inputs are:"+x+", "+y);
		return x+y;
	}
}

您还将看到日志打印到控制台。

2015-05-12 21:22:44,610 +0530 [main] DEBUG (Log4jExample.java:18) - My Debug Log
2015-05-12 21:22:44,611 +0530 [main] INFO  (Log4jExample.java:19) - My Info Log
2015-05-12 21:22:44,611 +0530 [main] WARN  (Log4jExample.java:20) - My Warn Log
2015-05-12 21:22:44,612 +0530 [main] ERROR (Log4jExample.java:21) - My error log
2015-05-12 21:22:44,612 +0530 [main] FATAL (Log4jExample.java:22) - My fatal log

请注意,MathUtils类没有打印任何日志,这是因为它的记录器级别是INFO,高于DEBUG。
只需将其日志记录级别更改为DEBUG,如下所示。

DEBUG Log4jExample - My Debug Log
INFO  Log4jExample - My Info Log
WARN  Log4jExample - My Warn Log
ERROR Log4jExample - My error log
FATAL Log4jExample - My fatal log

现在,当您再次运行该程序时,main.log文件也将具有以下日志。

<logger name="com.theitroad.log4j.logic" additivity="false">
	<level value="DEBUG" 
	<appender-ref ref="file" 
</logger>

这就是在Java独立应用程序中使用log4j的过程。

Log4j Java Web应用程序

现在,让我们看看如何在Java Web应用程序中使用log4j。
创建一个"动态Web项目",然后将其转换为Maven。
下图显示了该项目的最终结构。

下面是log4j配置文件。

my-log4j.xml

2015-05-12 21:23:56,151 +0530 [main] DEBUG (MathUtils.java:10) - inputs are:4, 5
2015-05-12 21:23:56,151 +0530 [main] DEBUG (MathUtils.java:10) - inputs are:40, 50
2015-05-12 21:23:56,153 +0530 [main] DEBUG (MathUtils.java:10) - inputs are:1, 5

它与早期配置的相似之处更多,除了我们要注入" catalina.home"变量以将日志文件生成到tomcat日志目录中。

由于必须在使用log4j之前对其进行配置,因此我们可以通过定义如下的" ServletContextListener"来加载它。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="https://jakarta.apache.org/log4j/"
	debug="false">

	<!-- console appender -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" 
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p %c{1} - %m%n" 
		</layout>
	</appender>
	
	<!-- rolling file appender -->
	<appender name="file" class="org.apache.log4j.RollingFileAppender">
		<param name="File" value="${catalina.home}/logs/main.log" 
		<param name="Append" value="true" 
		<param name="ImmediateFlush" value="true" 
		<param name="MaxFileSize" value="10MB" 
		<param name="MaxBackupIndex" value="5" 

		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d %d{Z} [%t] %-5p (%F:%L) - %m%n" 
		</layout>
	</appender>

	<logger name="com.theitroad.log4j" additivity="false">
		<level value="DEBUG" 
		<appender-ref ref="file" 
		<appender-ref ref="console" 
	</logger>

	<root>
		<priority value="DEBUG" 
		<appender-ref ref="file" 
		<appender-ref ref="console" 
	</root>

</log4j:configuration>

注意,使用ServletContext来获取log4j配置文件的完整路径。
这是我们必须做的其他事情,因为我们在运行时不知道log4j文件的完整路径,也不想对其进行硬编码。

以下是使用Logger记录一些消息的简单Servlet类。

package com.theitroad.log4j.servlet;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import org.apache.log4j.xml.DOMConfigurator;

@WebListener
public final class Log4jInitListener implements ServletContextListener {

  public Log4jInitListener() {
  }

  public void contextDestroyed(ServletContextEvent paramServletContextEvent)  { 
  }

  public void contextInitialized(ServletContextEvent servletContext)  { 
  	String webAppPath = servletContext.getServletContext().getRealPath("/");
	String log4jFilePath = webAppPath + "WEB-INF/classes/my-log4j.xml";
  	DOMConfigurator.configure(log4jFilePath);
  	System.out.println("initialized log4j configuration from file:"+log4jFilePath);
  }
	
}

只需将项目导出为WAR文件,然后部署到Tomcat服务器,下图显示了当我们在浏览器中调用servlet时的图像。

您将在tomcat日志目录main.log文件中获得以下日志类型。

package com.theitroad.log4j.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	
	private static final Logger logger = Logger.getLogger(MyServlet.class);
	
  public MyServlet() {
  }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String name = request.getParameter("name");
		logger.info("Name parameter value = "+name);
		
		PrintWriter out = response.getWriter();
		
		out.append("Served at: ").append(request.getContextPath());
		out.append("\n\nHello "+name);
		out.flush();
	}

}

由于我们还在登录到catalina.out文件的控制台,因此您将在catalina日志文件中找到以下日志。

hyman:logs hyman$tail -f main.log 
2015-05-12 21:46:33,038 +0530 [http-nio-8080-exec-2] INFO  (MyServlet.java:29) - Name parameter value = hyman