如何在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
相关产品推荐
相关产品推荐

