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下已经有了我们想要的以线程名命名的日志文件了。
log4j2 异步多线程打印日志的更多相关文章
- 一次鞭辟入里的 Log4j2 异步日志输出阻塞问题的定位
一次鞭辟入里的 Log4j2 日志输出阻塞问题的定位 问题现象 线上某个应用的某个实例突然出现某些次请求服务响应极慢的情况,有几次请求超过 60s 才返回,并且通过日志发现,服务线程并没有做什么很重的 ...
- Log4j2中的同步日志与异步日志
1.背景 Log4j 2中记录日志的方式有同步日志和异步日志两种方式,其中异步日志又可分为使用AsyncAppender和使用AsyncLogger两种方式. 2.Log4j2中的同步日志 所谓同步日 ...
- log4j2异步日志配置及官方文档的问题澄清
配置及demo 方法一全部打开 加启动参数 -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextS ...
- log4j2异步日志解读(二)AsyncLogger
前文已经讲了log4j2的AsyncAppender的实现[log4j2异步日志解读(一)AsyncAppender],今天我们看看AsyncLogger的实现. 看了这个图,应该很清楚AsyncLo ...
- 使用log4j2打印Log,log4j不能打印日志信息,log4j2不能打印日志信息,log4j和logj2,idea控制台信息乱码(文末)
说来惭愧,今天就写了个"hello world",了解了一下log4j的日志. 本来是想在控制台打印个log信息,也是遇到坎坷重重,开始也没去了解log4j就来使用,log4j配置 ...
- Log4j2异步情况下怎么防止丢日志的源码分析以及队列等待和拒绝策略分析
org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor以下所有源码均在此类中首先我们看下log4j2异步队列的初始化 从这里面我们 ...
- log4j2异步日志解读(一)AsyncAppender
log4j.logback.log4j2 历史和关系,我们就在这里不展开讲了.直接上干货,log4j2突出于其他日志的优势,异步日志实现. 看一个东西,首先看官网文档 ,因为前面文章已经讲解了disr ...
- 如何监控 Log4j2 异步日志遇到写入瓶颈
如何监控 Log4j2 异步日志遇到写入瓶颈 在之前的一篇文章中(一次鞭辟入里的 Log4j2 异步日志输出阻塞问题的定位),我们详细分析了一个经典的 Log4j2 异步日志阻塞问题的定位,主要原因还 ...
- 使用 @Log4j2 log.error() 打印异常日志
public static void main(String[] args) { int a = 10; try { int i = 1/0; } catch (Exception e) { Syst ...
随机推荐
- 1012 The Best Rank
1012 The Best Rank 1. 注意点 一名同学同样排名下的科目优先级问题 不同同学分数相同时排名相同,注意 排名不是 1 1 2 3 4 这种, 而是 1 1 3 4 5 注意到有些同学 ...
- 概率dp 148 D
概率dp 设 f(i,j)f(i,j) 表示有 ii 只白鼠,jj 只黑鼠时A先手胜的概率 初始状态 全白时,显然先手必胜 有一只黑鼠时,先手若抽到黑鼠则后手必胜,所以先手首回合必须抽到白鼠 f(i, ...
- Java实现定时器的四种方式
package com.wxltsoft.tool; import org.junit.Test; import java.util.Calendar; import ja ...
- 2019冬季PAT甲级第一题
#define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace std; ][]; ][]; ]; string ...
- 每日扫盲(一):java的rmi
JAVA RMI 原理和使用浅析 本地对象调用 我们先看看本地对象方法的调用: ObjectClass objectA = new ObjectClass(); String retn = objec ...
- 面试问烂的 Spring AO,全文详解
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...
- JAVA基础学习(4)之循环控制
4循环控制 4.1 for循环 4.1.1 for循环 固定次数for循环 先执行一次do-while循环 其他while循环 Scanner in = new Scanner(System.in); ...
- 201771010135 杨蓉庆/张燕《面对对象程序设计(java)》第十三周学习总结
1.实验目的与要求 (1) 掌握事件处理的基本原理,理解其用途: (2) 掌握AWT事件模型的工作机制: (3) 掌握事件处理的基本编程模型: (4) 了解GUI界面组件观感设置方法: (5) 掌握W ...
- ios 用touchend事件 pc用click touchend击穿
var clickEvent = (function() { if ('ontouchend' in document.documentElement === true) return 'touche ...
- ECMAScript中的箭头函数 (=>) 使用注意事项
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或 new.target.这些函数表达式更适用于那些本来需要匿名函数的地方,并且它们不能用作构造函数. 箭 ...