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 异步多线程打印日志的更多相关文章

  1. 一次鞭辟入里的 Log4j2 异步日志输出阻塞问题的定位

    一次鞭辟入里的 Log4j2 日志输出阻塞问题的定位 问题现象 线上某个应用的某个实例突然出现某些次请求服务响应极慢的情况,有几次请求超过 60s 才返回,并且通过日志发现,服务线程并没有做什么很重的 ...

  2. Log4j2中的同步日志与异步日志

    1.背景 Log4j 2中记录日志的方式有同步日志和异步日志两种方式,其中异步日志又可分为使用AsyncAppender和使用AsyncLogger两种方式. 2.Log4j2中的同步日志 所谓同步日 ...

  3. log4j2异步日志配置及官方文档的问题澄清

    配置及demo 方法一全部打开 加启动参数 -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextS ...

  4. log4j2异步日志解读(二)AsyncLogger

    前文已经讲了log4j2的AsyncAppender的实现[log4j2异步日志解读(一)AsyncAppender],今天我们看看AsyncLogger的实现. 看了这个图,应该很清楚AsyncLo ...

  5. 使用log4j2打印Log,log4j不能打印日志信息,log4j2不能打印日志信息,log4j和logj2,idea控制台信息乱码(文末)

    说来惭愧,今天就写了个"hello world",了解了一下log4j的日志. 本来是想在控制台打印个log信息,也是遇到坎坷重重,开始也没去了解log4j就来使用,log4j配置 ...

  6. Log4j2异步情况下怎么防止丢日志的源码分析以及队列等待和拒绝策略分析

    org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor以下所有源码均在此类中首先我们看下log4j2异步队列的初始化 从这里面我们 ...

  7. log4j2异步日志解读(一)AsyncAppender

    log4j.logback.log4j2 历史和关系,我们就在这里不展开讲了.直接上干货,log4j2突出于其他日志的优势,异步日志实现. 看一个东西,首先看官网文档 ,因为前面文章已经讲解了disr ...

  8. 如何监控 Log4j2 异步日志遇到写入瓶颈

    如何监控 Log4j2 异步日志遇到写入瓶颈 在之前的一篇文章中(一次鞭辟入里的 Log4j2 异步日志输出阻塞问题的定位),我们详细分析了一个经典的 Log4j2 异步日志阻塞问题的定位,主要原因还 ...

  9. 使用 @Log4j2 log.error() 打印异常日志

    public static void main(String[] args) { int a = 10; try { int i = 1/0; } catch (Exception e) { Syst ...

随机推荐

  1. 深度学习之tensorflow框架(上)

    import tensorflow as tf import os os.environ[' def tensorflow_demo(): #原生python加法运算 a = 2; b=3; c=a+ ...

  2. JAVA中对null进行强制类型转换

    今天很好奇,对null进行强转会不会抛错.做了如下测试得到的结果是,如果把null强转给对象,是不会抛异常的,本身对象是可以为null的.但是如果是基本类型,比如 int i = (Integer)o ...

  3. 微信小程序使用wxParse实现接入富文本编辑

    简介 微信小程序中比如活动说明,简介这样的图文介绍说明页面,后台通常配置成富文本编辑框,由后台直接输入内容,然后在小程序界面展现. 但是富文本编辑提取到内容是html格式的,写法与小程序的wxml并不 ...

  4. php 移动操作数组函数

    下面的几个主要是移动数组指针和压入弹出数组元素的和个函数. 函数 功能 array_shift 弹出数组中的第一个元素 array_unshift 在数组的开始处压入元素 array_push 向数组 ...

  5. 七、linux基础-jdk1.8和weblogic12.2.1.3.0安装

    1.环境探查与准备 安装jdk和weblogic前需要对进行安装的linux系统硬件和软件环境进行探查确认,以确保支持对jdk1.8.0_144_1和weblogic12.2.1.3和的安装.webl ...

  6. 读写json文件

    def read_json(path): """return dict""" with open(path,'r+')as f: retur ...

  7. Javascript自增、自减运算符

    JavaScript自增.自减运算符与表达式语法 var i++; var-- 声明变量 i-- 变量名 ++ -- 自增运算符 JavaScript自增.自减运算符与表达式 JavaScript自增 ...

  8. getter和setter

    /* 对象属性是由名字.值和自足特性构成的. 属性值可以用一个或两个方法替代,这两个方法就是getter和setter. 由getter和setter定义的属性称作“存取器属性” */ /* 定义存取 ...

  9. 「CF241E」Flights

    传送门 Luogu 解题思路 首先对于所有不属于任何一条路径上的边,它的权值是任意的. 对于所有在路径上的边 \((u,v)\) 满足 \(1\le dis_v-dis_u\le2\) 差分约束即可. ...

  10. Java连载65-自定义手动抛出异常、子类的异常范围、数组初探

    一.手动抛出异常1.自定义无效名字异常: (1)编译时异常,直接继承Exception (2)运行时异常,直接继承RuntimeException 举例子:注意点:throws会向上抛出异常,跑到最上 ...