[英]Separate error logging in Log4j 2
Log4j 2允許將類別和行信息包含在日志條目中。 但是,作者聲稱創建該條目需要花費4至5倍的時間。
我日志的99.5%由正常操作條目(info)組成,而實際上並不需要行和類。 我想知道是否有任何方法可以配置log4j 2,使其僅將文件,類和行包含到具有“警告”或更高級別的條目中?
本地似乎不支持此功能。 但是,您可以使用自己的過濾器實現和2個附加程序來歸檔所需的結果。
每個附加器僅輸出一定范圍的級別,嚴重事件的附加器可以添加行號。 記錄器需要同時使用兩個追加程序,以免您處理代碼中的區別,即記錄如下:
// Will have line numbers in output.
LogManager.getLogger().error("bla");
// Won't have line numbers in output.
LogManager.getLogger().info("blub");
Log4j 2的配置類似於(注意ConsoleMoreSevere
%line
):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" packages="yield.log4j2">
<Appenders>
<Console name="ConsoleLessSevere" target="SYSTEM_OUT">
<PatternLayout pattern="%d{ISO8601} [%t] %-5level %logger{36} - %msg%n" />
<LevelRangeFilter maxLevel="INFO"/>
</Console>
<Console name="ConsoleMoreSevere" target="SYSTEM_OUT">
<PatternLayout pattern="%d{ISO8601} [%t] %-5level %logger{36}:%line - %msg%n" />
<LevelRangeFilter minLevel="WARN"/>
</Console>
</Appenders>
<Loggers>
<Root level="WARN">
<AppenderRef ref="ConsoleLessSevere" />
<AppenderRef ref="ConsoleMoreSevere" />
</Root>
</Loggers>
</Configuration>
這就需要定義自定義過濾器實現,在我的示例中稱為yield.log4j2.LevelRangeFilter
。 該實現是根據Log4j 2文檔中的示例建模的 ,可以在https://github.com/AugustusKling/yield/blob/master/src/main/java/yield/log4j2/LevelRangeFilter.java中找到。 隨時復制課程。
為了在沒有外部資源的情況下完成此答案,請執行LevelRangeFilter
的實現:
package yield.log4j2;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
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.filter.AbstractFilter;
import org.apache.logging.log4j.message.Message;
/**
* Filters log events within given bounds.
*/
@Plugin(name = "LevelRangeFilter", category = "Core", elementType = "filter", printObject = true)
public class LevelRangeFilter extends AbstractFilter {
private final Level minLevel;
private final Level maxLevel;
private LevelRangeFilter(final Level minLevel, final Level maxLevel,
final Result onMatch, final Result onMismatch) {
super(onMatch, onMismatch);
this.minLevel = minLevel;
this.maxLevel = maxLevel;
}
@Override
public Result filter(final Logger logger, final Level level,
final Marker marker, final String msg, final Object... params) {
return filter(level);
}
@Override
public Result filter(final Logger logger, final Level level,
final Marker marker, final Object msg, final Throwable t) {
return filter(level);
}
@Override
public Result filter(final Logger logger, final Level level,
final Marker marker, final Message msg, final Throwable t) {
return filter(level);
}
@Override
public Result filter(final LogEvent event) {
return filter(event.getLevel());
}
private Result filter(final Level level) {
if (maxLevel.intLevel() <= level.intLevel()
&& minLevel.intLevel() >= level.intLevel()) {
return onMatch;
} else {
return onMismatch;
}
}
/**
* @param minLevel
* Minimum log Level.
* @param maxLevel
* Maximum log level.
* @param onMatch
* Action to take on a match.
* @param onMismatch
* Action to take on a mismatch.
* @return The created filter.
*/
@PluginFactory
public static LevelRangeFilter createFilter(
@PluginAttribute(value = "minLevel", defaultString = "TRACE") final Level minLevel,
@PluginAttribute(value = "maxLevel", defaultString = "FATAL") final Level maxLevel,
@PluginAttribute(value = "onMatch", defaultString = "NEUTRAL") final Result onMatch,
@PluginAttribute(value = "onMismatch", defaultString = "DENY") final Result onMismatch) {
return new LevelRangeFilter(minLevel, maxLevel, onMatch, onMismatch);
}
}
從RC2開始,Log4j2不提供這種功能。 您可以為此在log4j2 Jira問題跟蹤器上提出功能請求。
同時,您是否要包含位置信息的控制權以每個記錄器為基礎。 因此,一個想法可能是擁有一個配置為includeLocation="true"
的單個系統級FATAL級記錄器。
配置片段示例:
...
<Loggers>
<AsyncLogger name="FATAL_LOGGER" level="fatal" includeLocation="true" additivity="false">
<AppenderRef ref="someAppender"/>
</AsyncLogger>
<Root level="trace" includeLocation="false">
<AppenderRef ref="someAppender"/>
</Root>
</Loggers>
</Configuration>
用法示例:
public class MyApp {
private static final Logger logger = LogManager.getLogger(MyApp.class);
public void someMethod(int value) {
// normal trace-level logging does not include location info
logger.trace("Doing some work with param {}", value);
try {
callAnotherMethod();
} catch (Throwable t) {
// use the shared fatal logger to include location info
LogManager.getLogger("FATAL_LOGGER").fatal("Unexpected error", t);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.