log4j2的异步使用及添加自定义参数方式

yizhihongxing

一、log4j2异步使用

在高并发场景下,日志的输出是一件非常耗时的操作。当日志输出的工作由主线程负责完成时,会拖慢主线程的执行速度,从而影响系统的响应速度。为了解决这个问题,我们可以使用Log4j2的异步日志支持。

在Log4j2中,异步日志的实现依赖于以下两个组件:AsyncLogger和AsyncAppender。AsyncLogger是Log4j2中的一个专门用于异步日志输出的Logger,而AsyncAppender允许我们将日志记录器日志事件发送到另一个线程执行。

使用AsyncLogger时,我们只需要在Logger的配置中配置上async="true"即可,如下所示:

<Configuration status="warn" name="AsyncTest">
    <Appenders>
        <Async name="Async" bufferSize="1024">
            <AppenderRef ref="Console" />
        </Async>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Async" />
        </Root>
    </Loggers>
</Configuration>

在上面的配置中,我们创建了一个名为Async的AsyncAppender,它的缓冲区大小为1024。然后,我们将指定日志输出到该Appender。最后,我们创建了一个名为Root的Logger,它的级别是info,并将日志事件附加到AsyncAppender。

二、log4j2添加自定义参数方式

  1. 自定义Layout实现添加自定义参数

添加自定义参数最常见的方式是继承Log4j2的PatternLayout类,并覆盖其format方法。PatternLayout是一种高度可定制化的Layout,使用相对简单的模式进行格式化输出。在覆盖format方法时,我们可以通过配置属性或使用配置API来向模式添加自定义参数。

public class MyLayout extends PatternLayout {

    private String myParameter = "defaultValue";

    public MyLayout(final Configuration config, final String myParameter, final String pattern, final Charset charset, final boolean alwaysWriteExceptions, final boolean noConsoleNoAnsi,
                     final boolean header, final boolean footer) {
        super(config, pattern, charset, alwaysWriteExceptions, noConsoleNoAnsi, header, footer);
        this.myParameter = myParameter;
    }

    @Override
    public String format(final LogEvent event) {
        // 在日志消息中添加自定义参数
        return super.format(event).replace("%mypar%", myParameter);
    }
}
  1. 自定义LogEventFactory实现添加自定义参数

另一种添加自定义参数的方式是实现自己的LogEventFactory。在这种情况下,我们不使用Log4j2提供的默认LogEventFactory,而是创建自己的LogEventFactory。我们可以在此过程中添加自定义属性。在LogEvent被创建之前,我们可以将自定义属性添加到LogEvent对象中,并将新的LogEvent对象返回给Appender。

public class MyLogEventFactory implements LogEventFactory {

    private final String myParameter;

    public MyLogEventFactory(String myParameter) {
        this.myParameter = myParameter;
    }

    @Override
    public LogEvent createEvent(String loggerName, Marker marker, String fqcn, Level level, Message data, List<Property> properties, Throwable t) {
        // 将自定义属性添加到LogEvent中
        properties.add(Property.createProperty("myParameter", myParameter));
        return new Log4jLogEvent(loggerName, marker, fqcn, level, data, properties, t);
    }
}

示例1:

<Configuration>
    <Appenders>
        <Console name="Console">
            <PatternLayout pattern="%d{ISO8601} [%t] %-5p %c{1} - %msg - %property{myProperty}%n"/>
        </Console>
        <CustomAppender name="CustomAppender" >
            <MyLayout>
                <MyParameter>myParameterValue</MyParameter>
                <Pattern>%d{ISO8601} [%t] %-5p %c{1} - %msg - %mypar%n</Pattern>
            </MyLayout>
        </CustomAppender>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="CustomAppender"/>
        </Root>
    </Loggers>
</Configuration>

在这个例子中,我们创建了一个名为CustomAppender的新Appender。对于这个Appender,我们在堆栈跟踪和输出消息行中添加了自定义参数。在PatternLayout中,我们将%myParameter的值设置为我们自己的默认值。自定义参数的值可以通过自定义的Layout配置中的MyLayout属性进行修改。

示例2:

public class MyAsyncAppender extends AsyncAppender {

  private final String myParameter;

  public MyAsyncAppender(String name, String myParameter, AppenderRef[] appenderRefs, LoggerConfig loggerConfig, int bufferSize, boolean blocking, Configuration configuration) {
    super(name, appenderRefs, loggerConfig, bufferSize, blocking, configuration);
    this.myParameter = myParameter;
  }

  @Override
  protected LogEvent createEvent(final byte[] data, final int offset, final int length, final long timestamp, final String threadName,
                                 final Level level, final String loggerName, final Message message, final Throwable throwable, final Map<String, String> contextMap,
                                 final ThreadContext.ContextStack contextStack, final String fqcn, final StackTraceElement location) {
    // 将自定义参数添加到日志事件中
    return new Log4jLogEvent(loggerName, null, fqcn, level, message, new ArrayList<>(0), throwable, ThreadContext.getImmutableContext(), contextStack, location, null, timestamp).toBuilder()
      .putContextData("myParameter", myParameter)
      .build();
  }
}

在这个例子中,我们创建了一个名为MyAsyncAppender的新Appender。对于这个Appender,我们在日志消息中添加了自定义参数。我们重写了AsyncAppender的createEvent()方法,在其中创建LogEvent,并将自定义参数添加到上下文数据中。它们可以在格式化时使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:log4j2的异步使用及添加自定义参数方式 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • python的类class定义及其初始化方式

    Python是一门面向对象的编程语言,其中类(class)是面向对象的基础。类是一种抽象的概念,描述了数据和操作数据的方法。在Python中,要定义一个类,需要使用关键字“class”,并遵循一定的命名规范。 定义类(class) 定义一个类的语法如下: class ClassName: attribute1 = value1 attribute2 = va…

    other 2023年6月20日
    00
  • Android Socket通信详解

    Android Socket通信详解 简介 Socket通信是一种网络编程技术,它提供了一种在不同设备间进行通信的方式。在Android应用中,如果需要实现跨设备间的通信,可以使用Socket来实现。 使用Socket通信需要建立两个端点,一个是客户端,一个是服务器端。客户端和服务器可以通过Socket进行通信,从而实现数据交换。 Socket通信的基本原理…

    other 2023年6月27日
    00
  • Android Studio 3.5格式化布局代码时错位、错乱bug的解决

    针对这个问题,我会提供一个完整的解决攻略,包含以下几个步骤: 1. 下载最新的Android Studio升级版 这个问题可能是因为在旧版Android Studio中的一个布局标记管理错误所导致的。因此,向升级到最新的稳定版可能会解决这个问题。 2. 清除缓存文件 如果升级到最新的稳定版并不能解决你的问题,你可以尝试清除缓存文件。这是因为Android S…

    other 2023年6月27日
    00
  • C语言数据存储归类介绍

    C语言数据存储归类介绍 C语言是一门十分经典的编程语言,无论是在学习还是工作中,都有着非常广泛的应用。在C语言中,数据的存储归类是非常重要的知识点,在本篇文章中,我们将会详细讲解C语言数据存储归类的介绍。 C语言中的数据类型 在C语言中,定义了许多的数据类型,其中一些常用的数据类型包括: 整型(int) 浮点型(float) 双精度浮点型(double) 字…

    other 2023年6月27日
    00
  • 详解能在多种前端框架下使用的表格控件

    为了在多种前端框架下使用表格控件,我们可以使用开源JavaScript库datatables。此库是一个可以为我们提供非常多样化的数据展示方式和高级交互功能的表格插件。同时,datatables还能够支持从服务器获取数据而不是仅限于静态数据的呈现方式。 以下是datatables在多种前端框架下的使用步骤: 步骤 (jQuery环境) 引入jQuery库和d…

    other 2023年6月27日
    00
  • 解决Android Studio 出现“Cannot resolve symbol” 的问题

    当在Android Studio项目中遇到“Cannot resolve symbol”错误时,这通常意味着无法找到定义该符号的类、变量、方法或其他属性。这可能是由于多种原因引起的,下面是常见的几种原因及其解决方法: 1. 缺少依赖库 这通常是由于项目中缺少必要的依赖库而导致的。要解决这个问题,可以尝试以下几个步骤: 确认项目中是否导入所需的依赖库,在项目的…

    other 2023年6月26日
    00
  • 易语言制作调试助手

    易语言制作调试助手攻略 简介 在本攻略中,我们将使用易语言制作一个调试助手。调试助手可以帮助程序员在开发过程中进行调试和测试,提高开发效率。我们将使用易语言的基本语法和功能来实现这个调试助手。 步骤 步骤一:创建主界面 打开易语言开发环境,创建一个新项目。 在主界面上添加一个文本框和一个按钮,用于输入和执行调试命令。 示例代码: // 创建主界面 Form …

    other 2023年7月29日
    00
  • uwsgi常用配置

    uwsgi常用配置 uwsgi是一个很流行的Python web服务器网关接口程序,在部署Python Web应用程序时经常使用。在配置uwsgi时,需要设置一些常用的参数来确保应用程序的稳定性和性能。 安装uwsgi 在Ubuntu系统中,可以使用以下命令进行安装: sudo apt-get install uwsgi 也可以使用pip进行安装: pip …

    其他 2023年3月29日
    00
合作推广
合作推广
分享本页
返回顶部