You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Log4j2 MongoDB NoSQL Appender日志写入前修改MongoDB文档?

解决Log4j2 MongoDB Appender自定义日志文档的问题

你之前配置的JsonLayout未生效的原因是:Log4j2的MongoDB NoSQL Appender默认通过MongoDbDocumentFactory直接构建BSON文档,而非使用Layout序列化日志事件,因此Layout的KeyValuePair配置不会被应用。

以下是两种可行的自定义方案:

方法一:自定义MongoDbDocumentFactory(推荐)

这是最灵活的方式,通过重写文档创建逻辑,完全控制日志文档的结构。

步骤1:实现自定义DocumentFactory

创建继承自MongoDbDocumentFactory的类,重写createDocument方法来修改文档:

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.mongodb4.MongoDbDocumentFactory;
import org.bson.Document;

public class CustomMongoDocumentFactory extends MongoDbDocumentFactory {
    @Override
    public Document createDocument(final LogEvent event) {
        // 先获取默认生成的日志文档
        Document logDocument = super.createDocument(event);
        
        // 自定义操作示例:
        // 1. 添加自定义字段
        logDocument.put("customField", "customValue");
        // 2. 修改已有字段(比如将日志级别转为大写)
        logDocument.replace("level", logDocument.getString("level").toUpperCase());
        // 3. 删除不需要的字段
        logDocument.remove("threadName");
        
        return logDocument;
    }
}

步骤2:在log4j2.xml中配置自定义DocumentFactory

修改原配置,替换JsonLayout为自定义的DocumentFactory:

<Appenders>
    <NoSql name="mongoDbAppender">
        <MongoDb4 connection="${spring:mongo.connection.string}" />
        <!-- 指定自定义的文档工厂类 -->
        <CustomMongoDocumentFactory />
    </NoSql>
</Appenders>

方法二:扩展MongoDb4Appender

如果需要更深度的控制(比如拦截日志事件再处理),可以直接扩展MongoDb4Appender,重写append方法:

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.mongodb4.MongoDb4Appender;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.bson.Document;

@Plugin(name = "CustomMongoDb4Appender", category = "Core", elementType = "appender", printObject = true)
public class CustomMongoDb4Appender extends MongoDb4Appender {

    protected CustomMongoDb4Appender(Builder builder) {
        super(builder);
    }

    @Override
    public void append(LogEvent event) {
        // 先对日志事件进行自定义修改,再调用父类方法存入数据库
        LogEvent modifiedEvent = modifyLogEvent(event);
        super.append(modifiedEvent);
    }

    private LogEvent modifyLogEvent(LogEvent event) {
        // 这里可以修改日志事件的属性,比如添加自定义上下文信息
        // 也可以直接跳过父类逻辑,自行构建并修改BSON文档后存入
        return event;
    }

    @PluginBuilderFactory
    public static <B extends Builder<B>> B newBuilder() {
        return new Builder<B>().asBuilder();
    }

    public static class Builder<B extends Builder<B>> extends MongoDb4Appender.Builder<B> {
        @Override
        public CustomMongoDb4Appender build() {
            return new CustomMongoDb4Appender(this);
        }
    }
}

然后在配置中使用自定义的Appender:

<Appenders>
    <CustomMongoDb4Appender name="customMongoDbAppender">
        <MongoDb4 connection="${spring:mongo.connection.string}" />
    </CustomMongoDb4Appender>
</Appenders>

内容的提问来源于stack exchange,提问作者Tim Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 03:46:05