百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

企业中是如何具体使用log4j2的 log4j作用

lipiwang 2024-10-27 13:32 7 浏览 0 评论

本号主要用于分享企业中常用的技术,更加侧重于实用,欢迎关注,便于浏览其它更多实用的历史文章。

一、目录简介

  • 基础部分
  • 日志框架简单比较(slf4j、log4j、logback、log4j2 )
  • log4j2基础示例
  • log4j2配置文件
  • 实战部分
  • slf4j + log4j2 实际使用

二、日志框架比较(slf4j、log4j、logback、log4j2 )

  • 日志接口(slf4j)

slf4j是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用(如log4j、logback)

  • 日志实现(log4j、logback、log4j2)
  • log4j是apache实现的一个开源日志组件
  • logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现
  • Log4j2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活,官网地址: http://logging.apache.org/log4j/2.x/manual/configuration.html

为什么需要日志接口,直接使用具体的实现不就行了吗?

接口用于定制规范,可以有多个实现,使用时是面向接口的(导入的包都是slf4j的包而不是具体某个日志框架中的包),即直接和接口交互,不直接使用实现,所以可以任意的更换实现而不用更改代码中的日志相关代码。

比如:slf4j定义了一套日志接口,项目中使用的日志框架是logback,开发中调用的所有接口都是slf4j的,不直接使用logback,调用是 自己的工程调用slf4j的接口,slf4j的接口去调用logback的实现,可以看到整个过程应用程序并没有直接使用logback,当项目需要更换更加优秀的日志框架时(如log4j2)只需要引入Log4j2的jar和Log4j2对应的配置文件即可,完全不用更改Java代码中的日志相关的代码logger.info(“xxx”),也不用修改日志相关的类的导入的包(import org.slf4j.Logger; import org.slf4j.LoggerFactory;)

使用日志接口便于更换为其他日志框架。

log4j、logback、log4j2都是一种日志具体实现框架,所以既可以单独使用也可以结合slf4j一起搭配使用)

三、log4j2基础示例

1.创建maven web 项目, 结构如下

2. 配置pom.xml,引入log4j2必要的依赖(log4j-api、log4j-core)

<properties>
 	<junit.version>3.8.1</junit.version>
 	<log4j.version>2.5</log4j.version>
</properties>
<!-- 使用aliyun镜像 -->
<repositories>
 <repository>
 <id>aliyun</id>
 <name>aliyun</name>
 <url>http://maven.aliyun.com/nexus/content/groups/public</url>
 </repository>
</repositories>
<dependencies>
	<dependency> 
 <groupId>org.apache.logging.log4j</groupId> 
 <artifactId>log4j-api</artifactId> 
 <version>${log4j.version}</version> 
 </dependency> 
 <dependency> 
 <groupId>org.apache.logging.log4j</groupId> 
 <artifactId>log4j-core</artifactId> 
 <version>${log4j.version}</version> 
 </dependency> 
</dependencies>

3、 使用Main方法简单测试

测试说明:

  1. 工程中只引入的jar并没有引入任何配置文件,在测试的时候可以看到有ERROR输出:“ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.”
  2. 输出logger时可以看到只有error和fatal级别的被输出来,是因为没有配置文件就使用默认的,默认级别是error,所以只有error和fatal输出来
  3. 引入的包是log4j本身的包(import org.apache.logging.log4j.LogManager)

四:log2j 配置文件详解

配置文件的格式和位置

配置文件的格式:log2j配置文件可以是xml格式的,也可以是json格式的,

配置文件的位置:log4j2默认会在classpath目录下寻找log4j2.xml、log4j.json、log4j.jsn等名称的文件,如果都没有找到,则会按默认配置输出,也就是输出到控制台,也可以对配置文件自定义位置(需要在web.xml中配置),一般放置在src/main/resources根目录下即可

纯Java方式:

public static void main(String[] args) throws IOException { 
 File file = new File("D:/log4j2.xml"); 
 BufferedInputStream in = new BufferedInputStream(new FileInputStream(file)); 
 final ConfigurationSource source = new ConfigurationSource(in); 
 Configurator.initialize(null, source); 
 
 Logger logger = LogManager.getLogger("myLogger"); 
Web工程方式:
<context-param> 
 <param-name>log4jConfiguration</param-name> 
 <param-value>/WEB-INF/conf/log4j2.xml</param-value> 
</context-param> 
 
<listener> 
 <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class> 
</listener> 

示例一:简单配置(使用根控制器输出到控制台上)

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN"> 
 <Appenders> 
 <Console name="Console" target="SYSTEM_OUT"> 
 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> 
 </Console> 
 </Appenders> 
 
 <Loggers> 
 <Root level="info"> 
 <AppenderRef ref="Console" /> 
 </Root> 
 </Loggers> 
</Configuration>

示例结果:

结果解释:

日志管理器获取的是根日志器LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

对应的log4j2.xml中的Loggers节点下的Root,因为该根日志器的level=“info”,所以输出的info级别以上的日志

示例二:File Logger

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN"> 
 <Appenders> 
 <Console name="Console" target="SYSTEM_OUT"> 
 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> 
 </Console>
 
 <File name="FileAppender" fileName="D:/logs/app.log"> 
 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> 
 </File> 
 
 <!-- 发现Async 好像PatternLayout的输出格式配置的和输出的格式不一样,不用异步就完全一样 -->
 <Async name="AsyncAppender">
	 <AppenderRef ref="FileAppender"/>
 	</Async>
 </Appenders> 
 
 <Loggers> 
 	<Logger name="AsyncFileLogger" level="trace" additivity="true"> 
	 <AppenderRef ref="AsyncAppender" /> 
		</Logger>
 <Root level="info"> 
 <AppenderRef ref="Console" /> 
 </Root> 
 </Loggers> 
</Configuration>
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4j2Test {
	public static void main(String[] args) {
		Logger logger = LogManager.getLogger("AsyncFileLogger"); // Logger的名称
		
		logger.trace("trace level");
		logger.debug("debug level");
		logger.info("info level");
		logger.warn("warn level");
		logger.error("error level");
		logger.fatal("fatal level");
	}
}

AsyncFileLogger的additivity的值如果为false的话,就不会在控制台上输出或者为该Logger再增加一个输出源Consloe

<Logger name="AsyncFileLogger" level="trace" additivity="false"> 
	<AppenderRef ref="AsyncAppender" /> 
	<AppenderRef ref="Console" /> 
</Logger>

示例三: RollingRandomAccessFile

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN"> 
	<properties>
		<property name="LOG_HOME">D:/logs</property>
		<property name="FILE_NAME">mylog</property>
	</properties>
	
	 
 <Appenders> 
 <Console name="Console" target="SYSTEM_OUT"> 
 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> 
 </Console>
 
 <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}.log" filePattern="${LOG_HOME}/${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">
 	<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
 	<Policies>
 		<TimeBasedTriggeringPolicy interval="1"/>
 		<SizeBasedTriggeringPolicy size="10 MB"/>
 	</Policies>
 	<DefaultRolloverStrategy max="20"/>
 </RollingRandomAccessFile>
 
 <Async name="AsyncAppender">
 	<AppenderRef ref="RollingRandomAccessFile"/>
 	</Async>
 </Appenders> 
 
 <Loggers> 
 	<Logger name="RollingRandomAccessFileLogger" level="info" additivity="false"> 
	 <AppenderRef ref="AsyncAppender" /> 
	 <AppenderRef ref="Console" /> 
	 </Logger>
 </Loggers> 
</Configuration>
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4j2Test {
	public static void main(String[] args) {
		
	 Logger logger = LogManager.getLogger("RollingRandomAccessFileLogger"); 
	 for(int i = 0; i < 50000; i++) { 
	 logger.trace("trace level"); 
	 logger.debug("debug level"); 
	 logger.info("info level"); 
	 logger.warn("warn level"); 
	 logger.error("error level"); 
	 logger.fatal("fatal level"); 
	 } 
	 
	 try { 
	 Thread.sleep(1000 * 61); 
	 } catch (InterruptedException e) {} 
	 
	 logger.trace("trace level"); 
	 logger.debug("debug level"); 
	 logger.info("info level"); 
	 logger.warn("warn level"); 
	 logger.error("error level"); 
	 logger.fatal("fatal level"); 
	}
}

RollingRandomAccessFile 会根据命名规则当文件满足一定大小时就会另起一个新的文件

五:log4j2配置文件详解

log4j2.xml文件的配置大致如下:

Configuration

  • properties
  • Appenders
  • Console
  • PatternLayout
  • File
  • RollingRandomAccessFile
  • Async
  • Loggers
  • Logger
  • Root
  • AppenderRef

PatternLayout:控制台或文件输出源(Console、File、RollingRandomAccessFile)都必须包含一个PatternLayout节点,用于指定输出文件的格式(如 日志输出的时间 文件 方法 行数 等格式),例如 pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"

  • %d{HH:mm:ss.SSS} 表示输出到毫秒的时间
  • %t 输出当前线程名称
  • %-5level 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
  • %logger 输出logger名称,因为Root Logger没有名称,所以没有输出
  • %msg 日志文本
  • %n 换行
  • 其他常用的占位符有:
  • %F 输出所在的类文件名,如Log4j2Test.java
  • %L 输出行号
  • %M 输出所在方法名
  • %l 输出语句所在的行数, 包括类名、方法名、文件名、行数

Loggers:日志器

日志器分根日志器Root和自定义日志器,当根据日志名字获取不到指定的日志器时就使用Root作为默认的日志器,自定义时需要指定每个Logger的名称name(对于命名可以以包名作为日志的名字,不同的包配置不同的级别等),日志级别level,相加性additivity(是否继承下面配置的日志器), 对于一般的日志器(如Console、File、RollingRandomAccessFile)一般需要配置一个或多个输出源AppenderRef;

每个logger可以指定一个level(TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF),不指定时level默认为ERROR

additivity指定是否同时输出log到父类的appender,缺省为true。

<Logger name="rollingRandomAccessFileLogger" level="trace" additivity="true"> 
	<AppenderRef ref="RollingRandomAccessFile" /> 
</Logger>

properties: 属性

使用来定义常量,以便在其他配置的时候引用,该配置是可选的,例如定义日志的存放位置

D:/logs

【实战部分】

1. 引入slf4j和log4j需要的依赖

<properties>
 	<junit.version>3.8.1</junit.version>
 	<log4j.version>2.5</log4j.version>
 </properties>
 
 <dependencies>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>${junit.version}</version>
 <scope>test</scope>
 </dependency>
 
 <!-- slf4j + log4j2 begin -->
 <dependency>
	 <groupId>org.slf4j</groupId>
	 <artifactId>slf4j-api</artifactId>
	 <version>1.7.10</version>
	</dependency>
	
	<dependency> <!-- 桥接:告诉Slf4j使用Log4j2 -->
	 <groupId>org.apache.logging.log4j</groupId>
	 <artifactId>log4j-slf4j-impl</artifactId>
	 <version>2.2</version>
	</dependency>
	<dependency> <!-- 桥接:告诉commons logging使用Log4j2 -->
	 <groupId>org.apache.logging.log4j</groupId>
	 <artifactId>log4j-jcl</artifactId>
	 <version>2.2</version>
	</dependency>
 
 <dependency> 
 <groupId>org.apache.logging.log4j</groupId> 
 <artifactId>log4j-api</artifactId> 
 <version>${log4j.version}</version> 
 </dependency> 
 <dependency> 
 <groupId>org.apache.logging.log4j</groupId> 
 <artifactId>log4j-core</artifactId> 
 <version>${log4j.version}</version> 
 </dependency> 
 <!-- log4j end-->
 </dependencies>
 
 <!-- 使用aliyun镜像 -->
 <repositories>
 <repository>
 <id>aliyun</id>
 <name>aliyun</name>
 <url>http://maven.aliyun.com/nexus/content/groups/public</url>
 </repository>
 </repositories>

2、配置log2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN"> 
	<properties>
		<property name="LOG_HOME">D:/logs</property>
		<property name="FILE_NAME">mylog</property>
		<property name="log.sql.level">info</property>
	</properties>
	
	 
 <Appenders> 
 <Console name="Console" target="SYSTEM_OUT"> 
 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %msg%n" /> 
 </Console>
 
 <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}.log" filePattern="${LOG_HOME}/${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">
 	<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %msg%n"/>
 	<Policies>
 		<TimeBasedTriggeringPolicy interval="1"/>
 		<SizeBasedTriggeringPolicy size="10 MB"/>
 	</Policies>
 	<DefaultRolloverStrategy max="20"/>
 </RollingRandomAccessFile>
 </Appenders> 
 
 <Loggers> 
 	<Root level="info"> 
 		<AppenderRef ref="Console" /> 
	 <AppenderRef ref="RollingRandomAccessFile" /> 
	 </Root>
	 
	 <Logger name="com.mengdee.dao" level="${log.sql.level}" additivity="false">
 <AppenderRef ref="Console" />
 </Logger>
 </Loggers> 
</Configuration>

3. Java

package com.mengdee.manage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Log4j2Test {
	// Logger和LoggerFactory导入的是org.slf4j包
	private final static Logger logger = LoggerFactory.getLogger(Log4j2Test.class);
	public static void main(String[] args) {
		long beginTime = System.currentTimeMillis();
		
		for(int i = 0; i < 100000; i++) { 
			logger.trace("trace level"); 
		 logger.debug("debug level"); 
		 logger.info("info level"); 
		 logger.warn("warn level"); 
		 logger.error("error level");
		}
		
		try { 
	 Thread.sleep(1000 * 61); 
	 } catch (InterruptedException e) {} 
	 
	 
	 logger.info("请求处理结束,耗时:{}毫秒", (System.currentTimeMillis() - beginTime)); //第一种用法
	 logger.info("请求处理结束,耗时:" + (System.currentTimeMillis() - beginTime) + "毫秒"); //第二种用法
	}
}

4、运行结果

本号致力于让大家能够学到实用的知识,如果您认为写的不好请提出建议,写的好请给个赞。

相关推荐

《每日电讯报》研发数字工具,教你更有效率地报道新闻

为鼓励新闻编辑部持续创新,《每日电讯报》正在尝试有战略地研发数字工具。网站的数字媒体主任马尔科姆o科尔斯(MalcolmColes)表示,《每日电讯报》正试图去“创建一些可持续资产”,以便于让记者们...

html5学得好不好,看掌握多少标签

html5你了解了多少?如果你还是入门阶段的话,或者还是一知半解的话,那么我们专门为你们收集的html5常用的标签大全对你就很有帮助了,你需要了解了html5有哪些标签你才能够更好的。驾驭html5...

前端分享-少年了解过iframe么(我想了解少年)

iframe就像是HTML的「内嵌画布」,允许在页面中加载独立网页,如同在画布上叠加另一幅动态画卷。核心特性包括:独立上下文:每个iframe都拥有独立的DOM/CSS/JS环境(类似浏...

做SEO要知道什么是AJAX(人能看到但搜索引擎看不到的内容)

一个明显的,人能看到但搜索引擎不能看到的内容是AJAX。那么什么是AJAX呢?其实,了解过的基本上也都清楚,AJAX不是新的编程语言,而是一种使用现有标准的新方法。AJAX最大的优点是在不重新加...

介绍最前沿的人工智能创新,‘无反向传播’神经网络训练方法?

图像由GoogleImageFX生成前言:本文整理自NoProp原始论文与实践代码,并结合多个公开实现细节进行了全流程复现。对神经网络训练机制的探索仍在不断演进,如果你也在研究反向传播之...

说说我们对HTML6的期许(对html的看法)

HTML5概述HTML5是HTML语言最受欢迎的版本之一,它支持音频和视频、离线存储、移动端、和标签属性等等。还提供了article,section,header这样的标签来帮助开发者更好...

浏览器中在线预览pdf文件,pdf.mjs插件实现web预览pdf

背景:本来只是淘宝上卖卖袜子,想着扩展一下业务,准备做同名“来家居”海外袜子馆外贸项目,碰到pdf在线预览的需求,就找了pdf.js插件进行实践后把此方法记录下来,可以通过多种方法来实现,每种方法都有...

SVG 在前端的7种使用方法,你还知道哪几种?

本文简介点赞+关注+收藏=学会了技术一直在演变,在网页中使用SVG的方法也层出不穷。每个时期都有对应的最优解。所以我打算把我知道的7种SVG的使用方法列举出来,有备无患~如果你还...

HTML5常用标签大全(html5em标签)

HTML前端开发最终取决于掌握标签的多少HTML大概有七八百个标签楼主这里给大家总结了下HTML常用标签标签描述<!--...-->定义注释。<!DOCTYPE>定义文档类型...

&quot;伪君子Snoop Dogg!&quot;... WHAT?| MetroDaily 24/7

TUE.01-新作品-虽说年纪大了会有点糊涂,但是最近SnoopDogg的这波操作实在是让粉丝们有点迷,甚至有人表示没想到他是这样的"伪君子"......而这一切都源于他近日在IG上Po出的一...

史努比snoopy卡通手机壁纸屏保(史努比壁纸无水印)

...

莎夏·班克斯盼望表哥Snoop Dogg为其作出场曲

NXT女子冠军莎夏·班克斯(SashaBanks)近日接受了迈阿密先驱报采访,访谈纪要如下:关于她出众的形象:“我一向喜欢与众不同。为了能让人眼前一亮,我的装束总是非常前卫、非常抢眼,这样才能让观众...

喜欢Snoop!全球第一间「史努比博物馆」海外分馆在东京!

1950年起,由美國漫畫家CharlesM.Schulz創作的作品《Snoopy》史努比,其鮮明的可愛角色與幽默的劇情內容,至今仍成為許多大朋友與小朋友心中的最愛。為了紀念作者所設立的全球首...

Vetements 推出 Snoop Dogg 肖像「天价」T-Shirt

Vetements的CEOGuramGvasalia早前才透露品牌经营策略的秘密–Vetements如何成为人人热议的话题品牌。但似乎他仍有更多需要解释的东西–这个法国奢侈品牌最新...

狗爷Snoop Dogg的《I Wanna Thank Me》巡回演唱会旧金山站

西海岸匪帮说唱歌手SnoopDogg在《IWannaThankMe》巡回演唱会旧金山站表演(图片来自ICphoto)西海岸匪帮说唱歌手SnoopDogg(图片来自ICphoto)西海...

取消回复欢迎 发表评论: