log4j2 的配置与使用

简单说一下log4j2的改进,引用一下百度上的:

1、丢数据这种情况少,可以用来做审计功能。而且自身内部报的exception会被发现,但是logback和log4j不会。
2、log4j2使用了disruptor技术,在多线程环境下,据说性能高于logback等10倍以上。
3、(garbage free)之前的版本会产生非常多的临时对象,会造成GC频繁,log4j2则在这方面上做了优化,减少产生临时对象。尽可能少的GC
4、利用插件系统,使得扩展新的appender,filter,layout等变得容易,log4j不可以扩展 插件????
5、因为插件系统的简单性,所以在配置的时候,可以不用具体指定所要处理的类型。class
6、可以自定义level
7、Java 8 lambda support for lazy logging
8、Support for Message objects
9、对filter的功能支持的更强大
10、系统日志(Syslog)协议supports both TCP and UDP
11、利用jdk1.5并发的特性,减少了死锁的发生。
12、Socket LogEvent SerializedLayout
13、支持kafka queue
 

然后就是看怎么集成了:

1、用maven引入jar支持:

	<!-- log4j2 支持 -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.10.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-api</artifactId>
			<version>2.10.0</version>
		</dependency>


		<!-- log4j2 异步化需要添加 -->
		<dependency>
			<groupId>com.lmax</groupId>
			<artifactId>disruptor</artifactId>
			<version>3.3.6</version>
		</dependency>
		<!-- log4j2 支持end -->

需要注意的是,如果你引入了spring boot整合的库,比如:spring-cloud-starter。。。等这些包,记得要先排除其他日志框架,否则可能会造成jar冲突。举个例子:

<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
			<version>1.4.4.RELEASE</version>
			<exclusions>
                <!--移除其他日志框架,以免冲突-->
				<exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-logging</artifactId>
				</exclusion>
				<exclusion>
					<artifactId>*</artifactId>
					<groupId>ch.qos.logback</groupId>
				</exclusion>
				<exclusion>
					<artifactId>*</artifactId>
					<groupId>org.slf4j</groupId>
				</exclusion>
			</exclusions>
		</dependency>

2、再就是添加log2j的配置文件了,直接看吧,注释比较清楚:

<?xml version="1.0" encoding="UTF-8"?>
<!-- (1)请根据实际情况配置各项参数 (2)需要注意日志文件备份数和日志文件大小,注意预留目录空间 (3)实际部署的时候backupFilePatch变量需要修改成linux目录 -->

<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->

<!-- %p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL。 %d:输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,如:%d{yyyy/MM/dd 
	HH:mm:ss,SSS}。 %r:输出自应用程序启动到输出该log信息耗费的毫秒数。 %t:输出产生该日志事件的线程名。 %l:输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.java:10)。 
	%c:输出日志信息所属的类目,通常就是所在类的全名。 %M:输出产生日志信息的方法名。 %F:输出日志消息产生时所在的文件名称。 %L::输出代码中的行号。 
	%m::输出代码中指定的具体日志信息。 %n:输出一个回车换行符,Windows平台为"rn",Unix平台为"n"。 %x:输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java 
	servlets这样的多客户多线程的应用中。 %%:输出一个"%"字符。 -->

<!-- status : 这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,会看到log4j2内部各种详细输出 monitorInterval 
	: Log4j能够自动检测修改配置文件和重新配置本身, 设置间隔秒数。monitorInterval="300" 每隔300秒重新读取配置文件,对web应用很实用 -->
<configuration status="INFO">

	<!-- 配置日志文件输出目录 -->
	<Properties>
		<!-- 日志文件名称 -->
		<Property name="fileName">rblZuulServer</Property>
		<!-- 日志文件存放目录,根据你的需要设置 -->
		<Property name="backupFilePatch">/usr/log</Property>
	</Properties>
	<!--先定义所有的appender -->
	<appenders>

		<!--这个是输出到控制台的配置 target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT -->
		<Console name="Console" target="SYSTEM_OUT">
			<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
			<ThresholdFilter level="trace" onMatch="ACCEPT"
				onMismatch="DENY" />
			<!--输出日志的格式 -->
			<PatternLayout pattern="%d{yyyy.MM.dd HH:mm:ss.SSS} %p %c %M - %m%n" />
		</Console>

		<!--这个文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,挺有用的,适合临时测试用,或者查看本次运行时间的日志 -->
		<File name="File" fileName="${backupFilePatch}/${fileName}_test.log"
			append="false">
			<ThresholdFilter level="trace" onMatch="ACCEPT"
				onMismatch="DENY" />
			<PatternLayout pattern="%d{yyyy.MM.dd HH:mm:ss.SSS} %p %c %M - %m%n" />
		</File>

		<!--这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 (service.log.年份.gz) -->
		<!-- 注意%d{MM-dd-yyyy}要用年月日格式,不能加上时分秒,并且最后要有%i,这样log4j2才能判断出哪天一共产生几个文件,便于自动删除配置 -->
		<RollingFile name="service_appender" fileName="${backupFilePatch}/${fileName}.log"
			filePattern="${backupFilePatch}/${fileName}.log.%d{yyyy-MM-dd}-%i.log.gz"
			immediateFlush="true">

			<!-- %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间 %p : 日志输出格式 %c : logger的名称 
				%m : 日志内容,即 logger.info("message") %n : 换行符 %C : Java类名 %L : 日志输出所在行数 %M 
				: 日志输出所在方法名 hostName : 本地机器名 hostAddress : 本地ip地址 -->

			<PatternLayout pattern="%d{yyyy.MM.dd HH:mm:ss.SSS} %p %c %M - %m%n" />

			<Policies>
				<TimeBasedTriggeringPolicy interval="1"
					modulate="true" />
				<!-- 每个日志文件大小设置,超过大小自动压缩打包 -->
				<SizeBasedTriggeringPolicy size="30MB" />
			</Policies>

			<!-- 最多保留文件数 -->
			<DefaultRolloverStrategy max="20">
				<Delete basePath="${backupFilePatch}/" maxDepth="1">
					<!-- 指定要删除的后缀 -->
					<IfFileName glob="*.log.gz" />
					<!-- 超过20天自动删除 -->
					<IfLastModified age="20D" />
				</Delete>
			</DefaultRolloverStrategy>
		</RollingFile>

	</appenders>

	<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效 ,异步是 AsyncLogger 、asyncRoot,同步则是Logger、Root,推荐异步,性能高 -->
	<loggers>

		<!--过滤掉spring和mybatis等的一些无用的DEBUG信息 -->
		<AsyncLogger name="org.springframework" level="ERROR">
		</AsyncLogger>
		<AsyncLogger name="org.mybatis" level="error">
		</AsyncLogger>
		<AsyncLogger name="org.hibernate" level="error">
		</AsyncLogger>
		<AsyncLogger name="org.apache" level="error">
		</AsyncLogger>
	

		<!-- 需要打印的日志级别,以及包的设置,additivity="true"则是打印时同时输出到控制台 -->
		<AsyncLogger name="com.poly.zuul" level="DEBUG"
			additivity="true">
		</AsyncLogger>

		<!-- 指定打印根的级别 -->
		<asyncRoot level="INFO">
			<!-- 设置要打印的appender -->
			<AppenderRef ref="Console" />
			<AppenderRef ref="File" />
			<AppenderRef ref="service_appender" />
		</asyncRoot>
	</loggers>
</configuration>

3、在你的工程引入配置文件,比如命名为log4j2.xml,然后在工程配置文件中指定日志配置文件。如在application.properties中加入:

#log4j2指定配置文件路径
logging.config=classpath:xml/log4j2.xml

4、到此为止,基本配置已经完成,可以直接使用了,为了方便,这里给一个日志工具类 LoggerUtil,便于大家使用:

/*
 * 文件名:LoggerUtils.java 版权:Copyright by www.huawei.com 描述: 修改人:kokJuis 修改时间:2017年8月9日 跟踪单号: 修改单号:
 * 修改内容:
 */

package com.poly.rbl.utils;


import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


/**
 * 日志工具类
 * 
 * @author gogym
 * @version 2017年8月9日
 * @see LoggerUtils
 * @since
 */
public class LoggerUtil
{
    /**
     * 是否开启Debug
     */
    public static boolean isDebug = LogManager.getLogger(LoggerUtils.class).isDebugEnabled();

    public static void info(String message)
    {
        Logger logger = LogManager.getLogger();
        logger.info(message);
    }

    /**
     * Description: info输出
     * 
     * @param clazz
     *            目标.Class
     * @param message
     *            输出信息
     * @see
     */
    public static void info(Class<? extends Object> clazz, String message)
    {
        Logger logger = LogManager.getLogger(clazz);
        logger.info(message);
    }

    /**
     * info 输出
     * 
     * @param clazz
     *            目标.Class
     * @param fmtString
     *            输出信息key
     * @param value
     *            输出信息value
     */
    public static void fmtInfo(Class<? extends Object> clazz, String key, Object... value)
    {

        if (StringUtils.isBlank(key))
        {
            return;
        }
        if (null != value && value.length != 0)
        {
            Logger logger = LogManager.getLogger(clazz);
            logger.info("{}:{}", key, value);
        }
    }

    /**
     * Debug 输出
     * 
     * @param clazz
     *            目标.Class
     * @param message
     *            输出信息
     */
    public static void debug(Class<? extends Object> clazz, String message)
    {
        if (!isDebug) return;
        Logger logger = LogManager.getLogger(clazz);
        logger.debug(message);
    }

    /**
     * Debug 输出
     * 
     * @param clazz
     *            目标.Class
     * @param fmtString
     *            输出信息key
     * @param value
     *            输出信息value
     */
    public static void fmtDebug(Class<? extends Object> clazz, String key, Object... value)
    {
        if (!isDebug) return;

        if (StringUtils.isBlank(key))
        {
            return;
        }
        if (null != value && value.length != 0)
        {
            Logger logger = LogManager.getLogger(clazz);
            logger.debug("{}:{}", key, value);
        }
    }

    /**
     * Error 输出
     * 
     * @param clazz
     *            目标.Class
     * @param message
     *            输出信息
     * @param e
     *            异常类
     */
    public static void error(Class<? extends Object> clazz, String message, Exception e)
    {
        Logger logger = LogManager.getLogger(clazz);
        if (null == e)
        {
            logger.error(message);
            return;
        }
        logger.error(message, e);
    }

    /**
     * Error 输出
     * 
     * @param clazz
     *            目标.Class
     * @param message
     *            输出信息
     */
    public static void error(Class<? extends Object> clazz, String message)
    {
        error(clazz, message, null);
    }

    /**
     * 异常填充值输出
     * 
     * @param clazz
     *            目标.Class
     * @param fmtString
     *            输出信息key
     * @param e
     *            异常类
     * @param value
     *            输出信息value
     */
    public static void fmtError(Class<? extends Object> clazz, Exception e, String key,
                                Object... value)
    {
        if (StringUtils.isBlank(key))
        {
            return;
        }
        if (StringUtils.isBlank(key))
        {
            return;
        }
        if (null != value && value.length != 0)
        {
            Logger logger = LogManager.getLogger(clazz);
            logger.error("{}:{}", key, value);
        }
    }

    /**
     * 异常填充值输出
     * 
     * @param clazz
     *            目标.Class
     * @param fmtString
     *            输出信息key
     * @param value
     *            输出信息value
     */
    public static void fmtError(Class<? extends Object> clazz, String key, Object... value)
    {
        if (StringUtils.isBlank(key))
        {
            return;
        }
        if (StringUtils.isBlank(key))
        {
            return;
        }
        if (null != value && value.length != 0)
        {
            Logger logger = LogManager.getLogger(clazz);
            logger.error("{}:{}", key, value);
        }
    }
}

使用方式很简单,直接复制上面的类到你的工程。使用示例:

//最简单的使用
LoggerUtils.info("我是日志");

//加上class出处
LoggerUtils.info(getClass(), "我是日志");

//debug级别
LoggerUtils.debug(getClass(), "我是debug日志");

//error级别
LoggerUtils.error(clazz, "我是error日志");

//error级别,并打印异常
LoggerUtils.error(clazz, "我是error日志",Exception e);

//自定义输出信息
LoggerUtils.fmtInfo(getClass(),String key,Object... value);

//...............

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值