特定の要件があります:
今、これが私の実装です:
final Logger logger = LoggerFactory.getLogger(HelloWorld.class);
final Marker marker = MarkerFactory.getMarker("FATAL");
logger.error(marker, "!!! Fatal World !!!");
これが私のPatternLayout(yamlで)です:
PatternLayout:
Pattern: "%d{ISO8601_BASIC} %-5level %marker [%t] %logger{3.} - %msg%n"
これが私のログ出力です:
20150506T155705,158 ERROR FATAL [main] - !!! Fatal World !!!
ログ出力から「エラー」を効率的に削除する方法について何か考えがありますか?
どうもありがとうございました
これは私が何人かの同僚と一緒に来た最も近い実用的な解決策です:
これはJavaサンプルです:
Marker fatal = MarkerFactory.getMarker("FATAL");
// Usage example
final Logger logger = LoggerFactory.getLogger(FatalLogger.class);
logger.log(fatal, "this is a fatal message");
// Log sample :
20150514T115144,279 FATAL [main] FatalLogger - this is a fatal message
これが[〜#〜] yaml [〜#〜]サンプルです:
Configuration:
status: debug
Appenders:
RandomAccessFile:
- name: APPLICATION_APPENDER
fileName: logs/application.log
PatternLayout:
Pattern: "%d{ISO8601_BASIC} %-5level %msg%n"
- name: FATAL_APPENDER
fileName: logs/application.log
PatternLayout:
Pattern: "%d{ISO8601_BASIC} FATAL %msg%n"
Routing:
name: ROUTING_APPENDER
Routes:
pattern: "$${marker:}"
Route:
- key: FATAL
ref: FATAL_APPENDER
- ref: APPLICATION_APPENDER #DefaultRoute
Loggers:
Root:
level: trace
AppenderRef:
- ref: ROUTING_APPENDER
Marker
は、ここで本当に望んでいるものではありません。 Marker
は、ログメッセージを「強化」して、より簡単に検索できるようにするためのものです。ログレベル/優先度を変更しようとしていますが、これは少し異なります。
メッセージをERROR
レベルとして記録するlogger.error()
を使用しています。
事前定義されたFATAL
レベルがない場合(通常はlogger.fatal()
など)、ログレベルを指定できる汎用のlogger.log()
を使用します。
logger.fatal(yourMessage);
OR
logger.log(priorityLevel, yourMessage);
SLF4Jウェブサイトから:
Org.slf4jパッケージの一部であるMarkerインターフェイスは、FATALレベルを大幅に冗長にします。特定のエラーに通常のエラーに割り当てられたエラー以外の注意が必要な場合は、特別に指定されたマーカーでロギングステートメントをマークします。
http://www.slf4j.org/faq.html#fatal
したがって、SLF4Jでは、FATAL
ログレベルを設定することはできません。私はこの決定の背後にある理論的根拠には強く反対しますが、それはそれがそうであるものです。
質問がlog4jに関するものであることはわかっています。このページは、logbackに関して調べたときに見つかりました。 sl4jの推奨事項は次のとおりです https://www.slf4j.org/faq.html#fatal 。
これは私がlog4jのためにしたことですが、log4j2についてもお勧めします。 ...
独自のカスタムslf4j静的バインダー(別名、ブリッジ)を記述します。これには少しの作業が必要ですが、さまざまな複雑な理由から価値があります 1 ブログを書くのは1日ほどです。
これがあなたのやることです。
Log4jLogger
_ クラスを編集し、適切にディスパッチするようにマーカーメソッド(trace、error、warn、infoなど)を変更します。すなわちif (marker.contains("FATAL")) fatal(....);
log4j-slf4j-impl
_を除外し、新しいコードをそのまま使用します。<soap-box-rant>
正直なところ、slf4jには重大な欠陥があると思います
logger.fatal(...)
を提供せずにハードコア静的初期化をオーバーライドすることは非常に困難/不可能になります。fatal
がないためです。 80/20ではありません。マーカーは1%用で、fatal
は99%用です。</ soap-box-rant>
1それらの1つは、ほとんど任意の静的な初期化を決定するのが難しいのとは対照的に、実際にロギングフレームワークのブートプロセスの一部になることができます
これまでに見つけた唯一の解決策は、5つのマーカーを使用することです。
final Marker traceMarker = MarkerFactory.getMarker("TRACE");
final Marker debugMarker = MarkerFactory.getMarker("DEBUG");
final Marker infoMarker = MarkerFactory.getMarker("INFO");
final Marker warnMarker = MarkerFactory.getMarker("WARN");
final Marker errorMarker = MarkerFactory.getMarker("ERROR");
final Marker fatalMarker = MarkerFactory.getMarker("FATAL");
そして、毎回マーカーを渡すログ:
logger.info(infoMarker, "!!! INFO World !!!");
logger.error(errorMarker, "!!! ERROR World !!!");
logger.error(fatalMarker, "!!! FATAL World !!!");
そしてPatternLayoutを変更してLogLevelを完全に削除し、次のように常にマーカーをログに記録します。
PatternLayout:
Pattern: "%d{ISO8601_BASIC} %marker [%t] %logger{3.} - %msg%n"
このソリューションはハックだと思います... LogLevelを正しい方法で使用すると、外部ライブラリのログレベルも削除されます。
概要:この解決策は良い解決策ではありません。
[〜#〜] update [〜#〜]:RewritePolicyを記述して別のソリューションを試しました:
public class FatalRewritePolicy implements RewritePolicy {
public static final String FATAL = "FATAL";
@Override
public LogEvent rewrite(final LogEvent logEvent) {
final Marker marker = logEvent.getMarker();
if (marker == null)
return logEvent;
// Log Level is final in the LogEvent, there's no way we can modify it.
Level level = logEvent.getLevel();
return null;
}
}
Log4j2(でLogEventのLogLevelを変更する方法はないようです)。
概要:まだ解決策はありません。
メッセージの最初に「致命的」を追加できます。例えば:
LOGGER.error("FATAL: database connection lost.");
レベルに基づくフィルタリングなど、いくつかのことは失われますが、特にFATALステートメント(デバッグとトレース、確かに)をフィルターで除外する可能性が低いため、これは多くの人にとって問題ないかもしれません。