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

一、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日

相关文章

  • Xcode中Info.plist字段详解

    下面是详细的讲解: Xcode中Info.plist字段详解 什么是Info.plist文件 Info.plist 是苹果开发者必须添加到其应用程序捆绑包中的一个文件。这个文件是应用程序的“属性清单”,列出了应用程序所需的所有信息。 Info.plist文件的常用字段 Info.plist 中常用的字段有很多,下面分别介绍一下其中比较常用的几个: CFBun…

    other 2023年6月25日
    00
  • C#操作INI配置文件示例详解

    下面是详细的“C#操作INI配置文件示例详解”攻略。 什么是INI文件? INI文件是一种简单的文本文件,它通常用于存储程序的配置信息。INI文件由若干个节组成,每个节中包含若干个键值对,键值对用等号连接,例如: [Database] Server=127.0.0.1 Port=3306 Username=root Password=123456 C#如何操…

    other 2023年6月25日
    00
  • 在IDEA2020.2中配置使用Git的详细教程

    下面是在 IDEA2020.2 中配置使用 Git 的详细教程攻略: 前置条件 在开始 Git 的配置过程之前,请确保已经安装了 Git 工具,并且确保本地电脑上已经可以使用 Git 命令行。 配置 Git 的用户名和邮箱地址 在 IDEA 中使用 Git 前,需要配置全局用户信息,以便 Git 识别用户身份。在 Git 安装完成后,可以通过以下命令配置用户…

    other 2023年6月20日
    00
  • 什么是深度学习?

    深度学习是机器学习的一种分支,使用多层神经网络模型进行特征提取和模型训练,以解决复杂的分类和预测问题。深度学习可以应用于图像识别、语音识别、自然语言处理等领域,在人工智能领域中具有重要的地位。 深度学习的完整攻略可以按照以下步骤进行: 数据准备在进行深度学习之前,首先需要准备好数据集。通常情况下,数据集需要包含大量的数据样本,并且需要进行标注。常用的公开数据…

    其他 2023年4月19日
    00
  • Android使用CardView作为RecyclerView的Item并实现拖拽和左滑删除

    Android使用CardView作为RecyclerView的Item并实现拖拽和左滑删除攻略 在Android开发中,使用CardView作为RecyclerView的Item并实现拖拽和左滑删除功能是一种常见的需求。下面是一个完整的攻略,包含了实现该功能的详细步骤和两个示例说明。 步骤一:添加依赖 首先,确保你的项目中已经添加了CardView和Rec…

    other 2023年9月6日
    00
  • linux如何部署nginx

    Linux如何部署nginx 在Linux服务器上部署nginx可以快速搭建一个高性能的web服务器,本文将介绍如何在Linux上安装和配置nginx。 步骤一:安装nginx 使用命令行工具登录到Linux服务器; 安装nginx,命令如下: sudo apt update sudo apt install nginx 等待安装完成,安装成功后启动ngin…

    其他 2023年3月28日
    00
  • Android 访问文件权限的四种模式介绍

    Android 访问文件权限的四种模式介绍 在Android开发中,访问文件权限是一个重要的话题。Android提供了四种不同的文件访问权限模式,分别是: 私有模式(Private Mode):在私有模式下,应用程序可以创建和访问其私有目录中的文件。其他应用程序无法直接访问这些文件。这种模式适用于应用程序需要保存用户数据或配置信息的情况。以下是一个示例: F…

    other 2023年9月6日
    00
  • surfaceview使用详解

    SurfaceView 使用详解 SurfaceView 是 Android 中一个很实用的UI控件,它可以让我们在一个单独的线程中绘制复杂的图形,例如视频、动画等等。这里就来详细介绍一下 SurfaceView 的使用。 SurfaceView 的基本用法 首先,需要在 xml 文件中定义一个 SurfaceView 控件: <android.vie…

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