pra*_*upd 5 java logging log4j2
显然,log4j2中的JSONLayout不支持时间戳模式。通常,它仅具有JSON格式选项,而没有此类pattern选项。
{
"configuration": {
"name": "logggg",
"packages" : "logger.savemyjob",
"appenders": {
"RollingFile": {
"name": "rollingStone",
"fileName": "async_rolled.log",
"filePattern": "async_rolled-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz",
"immediateFlush" : false,
"JSONLayout": {
"complete": true,
"compact": false,
"eventEol": true
},
"SizeBasedTriggeringPolicy": {
"size": "10 MB"
},
"DefaultRolloverStrategy": {
"max": "10"
}
}
},
"loggers": {
"root": {
"level": "debug",
"appender-ref": {
"ref": "rollingStone"
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
日志示例
{
"timeMillis" : 1482231551081,
"thread" : "main",
"level" : "debug",
"endOfBatch" : false,
"threadId" : 1,
"threadPriority" : 5,
"message" : "log4j might suck"
}
Run Code Online (Sandbox Code Playgroud)
当我看他们的API时,看起来太冗长,看不到添加时间戳字段的简单方法。
JsonLayout插件似乎是我需要重写的插件,因为它final甚至无法扩展,否则我必须复制整个依赖类。
@Plugin(name = "JsonLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true)
public final class JsonLayout extends AbstractJacksonLayout {
protected JsonLayout(final Configuration config, final boolean locationInfo, final boolean properties,
final boolean encodeThreadContextAsList,
final boolean complete, final boolean compact, final boolean eventEol, final String headerPattern,
final String footerPattern, final Charset charset) {
super(config, new JacksonFactory.JSON(encodeThreadContextAsList).newWriter(locationInfo, properties, compact),
charset, compact, complete, eventEol,
PatternLayout.createSerializer(config, null, headerPattern, DEFAULT_HEADER, null, false, false),
PatternLayout.createSerializer(config, null, footerPattern, DEFAULT_FOOTER, null, false, false));
}
}
Run Code Online (Sandbox Code Playgroud)
该体系结构看起来比我预期的要复杂:(,我正在从中追踪Logger。

我也考虑过改变LogEvent自己,
public interface LogEvent extends Serializable {
@Deprecated
Map<String, String> getContextMap();
ReadOnlyStringMap getContextData();
ThreadContext.ContextStack getContextStack();
String getLoggerFqcn();
Level getLevel();
String getLoggerName();
Marker getMarker();
Message getMessage();
long getTimeMillis();
StackTraceElement getSource();
String getThreadName();
long getThreadId();
int getThreadPriority();
Throwable getThrown();
ThrowableProxy getThrownProxy();
boolean isEndOfBatch();
boolean isIncludeLocation();
void setEndOfBatch(boolean endOfBatch);
void setIncludeLocation(boolean locationRequired);
long getNanoTime();
String getTimestamp();
}
Run Code Online (Sandbox Code Playgroud)
并且 MutableLogEvent
public class MutableLogEvent implements LogEvent, ReusableMessage {
public void initFrom(final LogEvent event) {
SimpleDateFormat standardDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
this.timestamp = standardDateFormat.format(new Date(event.getTimeMillis()));
}
}
Run Code Online (Sandbox Code Playgroud)
我猜它可能会工作,尽管它破坏了几个核心的log4j-core测试。我基本上想知道以最小的变化添加额外的json字段的技巧。
我还看到了其他一些像JSONEventLayoutV1这样的impl,它似乎与log4j json api完全不同,这在性能上是非常明智的。
这是我尝试覆盖的失败尝试LogEvent,https://github.com/prayagupd/sell-peace/blob/custom_timestamp/supply-peace/src/main/java/org/apache/logging/log4j/core/DnLogEvent.java
问题越来越长,我基本上想知道重载log4j2 api时不要错过的重要事项。
小智 8
如果这仅仅是添加一个包含时间戳的新字段(默认情况下提供的timeMillis除外)的原因,为什么不尝试在新的自定义字段上使用查阅。
然后,JsonLayout配置可能如下所示:
<JsonLayout>
<KeyValuePair key="timestamp" value="$${date:yyyy-MM-dd'T'HH:mm:ss.SSSZ}" />
</JsonLayout>
Run Code Online (Sandbox Code Playgroud)
$$是Lookup,后面的字符date:是java SimpleDateFormat可以接受的格式。
要做的第一件事是在Log4j2 JIRA 问题跟踪器上提出功能请求。这听起来可能会让许多用户受益,因此值得尝试在 Log4j 本身中修复它。
同时,让我们看一下自定义解决方案。我不会更改 LogEvent,这将导致一个脆弱的解决方案(例如可能不适用于异步记录器和 AsyncAppender)。此外,当您想要升级到 Log4j2 的更高版本时,您可能会遇到麻烦。已经LogEvent有了您需要的数据 ( timeMillis),只需对其进行格式化即可。
官方的方式是创建一个自定义的Json布局插件。您可以重写,也可以从复制代码开始。(JIRA 票证中提出的另一个主题。)要更改的关键类可能是LogEventJsonMixIn。
Log4j2 使用 Jackson 生成 json 字符串。您可能需要将 LogEventJsonMixIn 替换为提供格式化日期而不是原始毫秒的版本。Jackson 可能已经有一个反序列化器用于此目的,否则您需要编写自己的反序列化器。Log4j 社区也许还能够提供更多想法。
| 归档时间: |
|
| 查看次数: |
4623 次 |
| 最近记录: |