顯然,log4j2中的JSONLayout沒有時間戳記模式支持。通常它只有JSON格式選項,但沒有這樣的pattern
選項。Log4j2 JSONLayout時間戳記模式
{
"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"
}
}
}
}
}
日誌示例,
{
"timeMillis" : 1482231551081,
"thread" : "main",
"level" : "debug",
"endOfBatch" : false,
"threadId" : 1,
"threadPriority" : 5,
"message" : "log4j might suck"
}
當我看着他們的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));
}
}
架構看起來比我預想的更:(複雜,我從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();
}
和也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()));
}
}
我猜測它可能會工作,雖然它打破了幾個核心log4j核心測試。我基本上想知道添加額外的json字段以最小的改變的技巧。
我看到幾個其他impls像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錯過。
感謝Remko。我可能會創建一個JIRA問題。我最終像你說的那樣做了,在'LogEvent'周圍創建了Wrapper'JsonLogEvent',它返回格式化的時間。而'CustomLogEventMixIn擴展LogEventMixIn'具有'timestamp' json鍵。 – prayagupd
也許對別人有用。如果留在StackOverflow上,每個人都需要將其作爲自定義解決方案來實現。可能會很好地融入到Log4j中。 –