log4j2 异步多线程打印日志

log4j2 异步多线程打印日志

Maven依赖

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-1.2-api</artifactId>
	<version>2.3</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-api</artifactId>
	<version>2.3</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-core</artifactId>
	<version>2.3</version>
</dependency>
<dependency>
	<groupId>com.lmax</groupId>
	<artifactId>disruptor</artifactId>
	<version>3.3.4</version>
</dependency>

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn"
packages="com.hoperun.zhulongxiang.asnc_print_different_logfile">
<Appenders>
    <console name="console" target="system_out">
		<!-- 只输出level及以上级别的信息(onmatch),其他的直接拒绝(onmismatch)。默认就是trace。      
		<thresholdfilter 
			level="trace" onmatch="accept" onmismatch="deny"/> -->
		<patternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} -
		%m%n" />
	</console>
	<Routing name="Routing">
		<Routes pattern="$${thread:threadName}">
			<Route>
				<RollingFile name="logFile-${thread:threadName}"
					fileName="log/${thread:threadName}.log"
					filePattern="log/${thread:threadName}-%d{MM-dd-yyyy}-%i.log">
					<PatternLayout pattern="%d %-5p [%t] %C{2} - %m%n" />
					<Policies>
						<SizeBasedTriggeringPolicy size="50 MB" />
					</Policies>
					<DefaultRolloverStrategy max="100" />
				</RollingFile>
			</Route>
		</Routes>
	</Routing>
	<Async name="async" bufferSize="1000" includeLocation="true">
		<AppenderRef ref="Routing" />
		<AppenderRef ref="console" />
	</Async>
</Appenders>
<Loggers>
	<Root level="debug">
		<AppenderRef ref="async" />
	</Root>
</Loggers>
</Configuration>

核心java类

package com.hoperun.zhulongxiang.asnc_print_different_logfile;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.lookup.StrLookup;

@Plugin(name = "thread", category = StrLookup.CATEGORY)
public class ThreadLookup implements StrLookup {

	public String lookup(String key) {
		return Thread.currentThread().getName();
	}

	public String lookup(LogEvent event, String key) {
		return event.getThreadName() == null ? Thread.currentThread().getName() : event.getThreadName();
	}

}

这里@Plugin中的name的值对应log4j2.xml中<Routes pattern="$${thread:threadName}">配置中的thread

准备两个线程类

package com.hoperun.zhulongxiang.asnc_print_different_logfile;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class LogThread implements Runnable {

	private static final Logger LOGGER = LogManager.getLogger(LogThread.class);

	public String threadName;

	public LogThread(String threadName) {
		this.threadName = threadName;
	}

	public void run() {
		Thread.currentThread().setName(threadName);
		LOGGER.info("1");
	}

}


package com.hoperun.zhulongxiang.asnc_print_different_logfile;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class OtherLogThread implements Runnable {

	private static final Logger LOGGER = LogManager.getLogger(LogThread.class);

	public String threadName;

	public OtherLogThread(String threadName) {
		this.threadName = threadName;
	}

	public void run() {
		Thread.currentThread().setName(threadName);
		LOGGER.info("2");
	}

}

测试

package com.hoperun.zhulongxiang.asnc_print_different_logfile;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import org.nutz.ioc.Ioc;

import com.hoperun.base.IocMaster;

public class LogApp {

	static {
		System.setProperty("log4j.configurationFile", "etc/log4j2.xml");
	}

	private static final Logger LOGGER = LogManager.getLogger(LogApp.class);

	public static void main(String[] args) {
		ThreadContext.put("threadName", Thread.currentThread().getName());
		LogThread t1 = new LogThread("123123123");
		OtherLogThread t2 = new OtherLogThread("4564564564");
		ExecutorService pool = Executors.newFixedThreadPool(20);
		pool.submit(t1);
		pool.submit(t2);
		
	}
}

这里ThreadContext.put("threadName", Thread.currentThread().getName())设置的参数threadName对应log4j2.xml中<Routes pattern="$${thread:threadName}">配置中的threadName

日志

09:44:39.704 [123123123] INFO  com.hoperun.zhulongxiang.asnc_print_different_logfile.LogThread -    1
09:44:39.704 [4564564564] INFO  com.hoperun.zhulongxiang.asnc_print_different_logfile.LogThread -    2

日志中的线程名已经修改成我们设定的名称。log下已经有了我们想要的以线程名命名的日志文件了。

转载于:https://my.oschina.net/xiaozhutefannao/blog/774574

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多线程环境下,日志可能会出现错乱的情况,因为多个线程可能会同时写入同一个日志文件。为了避免这种情况,可以在log4j2配置文件中设置一个Appender的locking属性为true,这样在写入日志时会使用同步锁来保证线程安全。示例如下: ``` <?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <File name="file" fileName="example.log"> <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" /> <locking>true</locking> </File> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="file" /> </Root> </Loggers> </Configuration> ``` 另外,建议使用异步日志记录器(AsyncLogger)来记录日志,这样可以减少对主线程的阻塞,提高应用程序的性能。可以在log4j2配置文件中设置AsyncLogger的ringBufferSize属性来控制异步队列的大小。示例如下: ``` <?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="console" target="SYSTEM_OUT"> <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" /> </Console> <Async name="async"> <AppenderRef ref="console" /> <blocking>false</blocking> <ringBufferSize>1024</ringBufferSize> </Async> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="async" /> </Root> </Loggers> </Configuration> ``` 以上配置中,Async Appender使用了一个大小为1024的环形缓冲区来存储日志事件,如果缓冲区已满,将会丢失最早的事件。blocking属性设置为false表示当缓冲区已满时不会阻塞当前线程,而是直接将事件丢弃。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值