[英]Programmatic Custom Json Layout Log4j2
我有使用
Log4j2 framework.<\/code>的
Java<\/code>桌面客戶端應用程序。
使用自定義參數記錄異常或信息時使用 JSON 結構。 出於這個原因,我正在嘗試以編程方式配置 Log4j2。 我知道建議使用基於文件的配置,但似乎最好為我的案例以編程方式初始化框架。
這是我正在嘗試構建的結構。
自定義 Json 布局<\/li>
HttpAppender<\/code>將通過 HTTP 發送日志
<\/li>
如果 HttpAppender 失敗,它將使用JdbcAppender<\/code>寫入數據庫
<\/li>
如果 JdbcAppender 失敗,它將使用FileAppender<\/code>寫入日志文件
<\/li><\/ul>我能夠生成JsonLayout<\/code>但我無法添加自定義字段並從默認結構中刪除現有字段。
我可能已經檢查了 50 多篇文章\/問題,但沒有一個對我有用。 這是我擁有的當前代碼。
此代碼打印到控制台並將 Json 格式的日志記錄寫入文件。 自定義值不會添加到 Json。
我嘗試通過其
builder<\/code>創建 JsonLayout,但我無法將其添加到構建器本身。
我需要添加到 Json 的參數是動態的,我不知道自定義節點的鍵和值。 在這個階段,我試圖在將其寫入文件時創建一個自定義 Json 布局。
我可能做錯了,所以請指教! 我願意接受建議。 謝謝。
通過調用LayoutComponentBuilder
的addComponent
方法,可以將自定義值作為鍵值對添加為組件。 以下代碼片段顯示了一個示例:
ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
AppenderComponentBuilder console =
builder.newAppender("stdout", "Console")
.addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
LayoutComponentBuilder jsonLayout
= builder.newLayout("JsonLayout")
.addAttribute("complete", false)
.addAttribute("compact", false)
.addComponent(builder.newKeyValuePair("key1", "value1"))
.addComponent(builder.newKeyValuePair("key2", "value2"));
console.add(jsonLayout);
builder.add(console);
RootLoggerComponentBuilder rootLogger
= builder.newRootLogger(Level.INFO);
rootLogger.add(builder.newAppenderRef("stdout"));
builder.add(rootLogger);
builder.writeXmlConfiguration(System.out);
return builder;
這是相應的 xml 輸出:
<?xml version='1.0' encoding='UTF-8'?>
<Configuration>
<Appenders>
<Console name="stdout" target="SYSTEM_OUT">
<JsonLayout complete="false" compact="false">
<KeyValuePair key="key1" value="value1"/>
<KeyValuePair key="key2" value="value2"/>
</JsonLayout>
</Console>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="stdout"/>
</Root>
</Loggers>
</Configuration>
使用 log4j 2.17.1 測試
您可以使用以下類從日志中減去您想要的類中的任何屬性。
import com.fanap.midhco.applicationUtil.JsonUtil;
import com.fasterxml.jackson.core.util.MinimalPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.core.jackson.JsonConstants;
import org.apache.logging.log4j.core.jackson.Log4jJsonObjectMapper;
import org.apache.logging.log4j.core.layout.AbstractStringLayout;
import org.apache.logging.log4j.core.util.StringBuilderWriter;
import org.apache.logging.log4j.util.Strings;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Set;
@Plugin(name = "MineCustLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true)
public class MineCustLayout extends AbstractStringLayout {
private final ObjectWriter objectWriter;
@PluginFactory
public static MineCustLayout createLayout(
@PluginAttribute(value = "locationInfo", defaultBoolean = false) final boolean locationInfo, @PluginAttribute(value = "eventEol", defaultBoolean = true) final boolean eventEol
) {
final SimpleFilterProvider filters = new SimpleFilterProvider();
final Set<String> except = new HashSet<>();
if (!locationInfo) {
except.add(JsonConstants.ELT_SOURCE);
}
except.add("loggerFqcn");
except.add("level");
except.add("timeMillis");
except.add("instant");
except.add("thread");
except.add("loggerName");
except.add("threadId");
except.add("threadPriority");
except.add("contextMap");
except.add("endOfBatch");
except.add(JsonConstants.ELT_NANO_TIME);
filters.addFilter(Log4jLogEvent.class.getName(), SimpleBeanPropertyFilter.serializeAllExcept(except));
final ObjectWriter writer = new Log4jJsonObjectMapper().writer(new MinimalPrettyPrinter());
return new MineCustLayout(writer.with(filters));
}
public MineCustLayout(ObjectWriter objectWriter) {
super(StandardCharsets.UTF_8, null, null);
this.objectWriter = objectWriter;
}
@Override
public String toSerializable(LogEvent event) {
final StringBuilderWriter writer = new StringBuilderWriter();
try {
objectWriter.writeValue(writer, event);
// writer.write('\n');
return JsonUtil.getJsonObject(writer.toString()).get("message").toString() + '\n';
} catch (final IOException e) {
LOGGER.error(e);
return Strings.EMPTY;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.