質問
log4j に同じ構成情報を使用する必要があるジョブがいくつか同時に実行されています。これらはすべて、同じアペンダーを使用してログを 1 つのファイルにダンプしています。各ジョブが動的にログ ファイルに名前を付けて、別々の状態に保つ方法はありますか?
ありがとう
トム
解決
各ジョブに Java システム プロパティを渡すことはできますか?その場合は、次のようにパラメータ化できます。
java -Dmy_var=somevalue my.job.Classname
そして、log4j.propertiesで次のようにします。
log4j.appender.A.File=${my_var}/A.log
Java システム プロパティに、ジョブのインスタンスを一意に識別するホストの環境 (たとえば) の値を設定できます。
他のヒント
ジョブ名が事前にわかっている場合は、getLogger() 呼び出しを実行するときにジョブ名を含めることができます。その後、別のファイル名 (または他の宛先) を使用して、別のアペンダーを別のロガーにバインドできます。
ジョブ名を事前に知ることができない場合は、構成ファイルを使用する代わりに、実行時にロガーを構成できます。
FileAppender appender = new FileAppender();
appender.setFileName(...);
appender.setLayout(...);
Logger logger = Logger.getLogger("com.company.job."+jobName);
logger.addAppender(appender);
私たちのシステムにも同様のものが実装されています。特定のロガーを HashMap に保存し、必要に応じてそれぞれのロガーのアペンダーを初期化します。
以下に例を示します。
public class JobLogger {
private static Hashtable<String, Logger> m_loggers = new Hashtable<String, Logger>();
private static String m_filename = "..."; // Root log directory
public static synchronized void logMessage(String jobName, String message)
{
Logger l = getJobLogger(jobName);
l.info(message);
}
public static synchronized void logException(String jobName, Exception e)
{
Logger l = getJobLogger(partner);
l.info(e.getMessage(), e);
}
private static synchronized Logger getJobLogger(String jobName)
{
Logger logger = m_loggers.get(jobName);
if (logger == null) {
Layout layout = new PatternLayout("...");
logger = Logger.getLogger(jobName);
m_loggers.put(jobName, logger);
logger.setLevel(Level.INFO);
try {
File file = new File(m_filename);
file.mkdirs();
file = new File(m_filename + jobName + ".log");
FileAppender appender = new FileAppender(layout, file.getAbsolutePath(), false);
logger.removeAllAppenders();
logger.addAppender(appender);
}
catch (Exception e)
{ ... }
}
return logger;
}
}
これをジョブで使用するには、次のような 1 行のエントリを使用するだけです。
JobLogger.logMessage(jobName, logMessage);
これにより、ジョブ名ごとに 1 つのログ ファイルが作成され、指定したディレクトリにそのジョブ名を持つ独自のファイルがドロップされます。
他のタイプのアペンダーなどをいじることができます。書かれているように、JVM が再起動されるまで追加が続行されますが、常に稼働しているサーバーで同じジョブを実行する場合は機能しない可能性がありますが、これはどのようにできるかの一般的なアイデアを与えます。仕事。
各ジョブに NDC または MDC を設定してから、NDC または MDC の値に基づいて名前を変更するアペンダーを作成できます。新しいアペンダーの作成はそれほど難しくありません。log4j サンドボックスの要件に適合するアペンダーも存在する可能性があります。調べ始める http://svn.apache.org/viewvc/logging/log4j/trunk/contribs/
おそらく [File.createTempFile]( を使用して、独自のファイル名を構成する独自のアペンダーを作成できます。http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String)) 方法。もし FileAppender
クラスが正しく記述されていれば、それを拡張できるはずです。または RollingFileAppender
— そしてオーバーライドします getFile
メソッドを使用して、追加したい新しいプロパティに基づいて選択したプロパティを返します。
基礎を築く シャディットさんの答え。どのクラスのメインメソッドが開始されたかによって各ジョブを識別できる場合は、システムプロパティを使用できます。 sun.java.command
開始されたクラスの完全な名前が含まれます。たとえば次のようになります。
log4j.appender.LOGFILE.File=${sun.java.command}.log
と併用して使っています タイムスタンプファイルアペンダー このような:
log4j.appender.LOGFILE=TimestampFileAppender
log4j.appender.LOGFILE.TimestampPattern=yyyy_MM_dd__HH_mm
log4j.appender.LOGFILE.File=${sun.java.command}_{timestamp}.log
この方法では、Eclipse で開発しているときに、実行する新しいプロセスごとに新しいログ ファイルが取得されます。ログ ファイルは、main メソッドを持つクラスのクラス名と開始時刻によって識別されます。
トムは、ジョブごとに指定して追加できます。2 つの異なる Java パッケージ com.tom.firstbatch と com.tom.secondbatch に対応する 2 つのジョブがあるとします。 log4j.xml には次のような内容が含まれます。
<category name="com.tom.firstbatch">
<appender-ref ref="FIRST_APPENDER"/>
</category>
<category name="com.tom.secondtbatch">
<appender-ref ref="SECOND_APPENDER"/>
</category>
ジョブを初期化するときに、プログラムで log4j を構成できます。
実行時にシステム プロパティを使用して log4j.properties ファイルを設定することもできます。から マニュアル:
リソース文字列変数を次の値に設定します。 log4j.構成 システムプロパティ。デフォルトの初期化ファイルを指定する推奨方法は、log4j.configuration システム プロパティを使用することです。システム プロパティ log4j.configuration が定義されていない場合は、文字列変数リソースをデフォルト値「log4j.properties」に設定します。
異なる Java コマンドからジョブを実行していると仮定すると、これにより、ジョブごとに異なる log4j.properties ファイルと異なるファイル名を使用できるようになります。
ジョブがどのように実行されるかについての具体的な知識がなければ、何とも言えません。
以下を実装できます。
- ジョブの ID の ThreadLocal ホルダー。
- FileAppender を拡張すると、FileAppender はジョブ ID ごとに QuietWriter を保持するマップを保持する必要があります。メソッド subAppend では、ThreadLocal からジョブの ID を取得し、QuietWriter を検索 (または作成) してそれに書き込みます。
ご希望であれば、メールでコードをお送りすることもできます...
log4j.logger.com.foo.admin =、adminfileappender log4j.logger.com.foo.report =、reportfileappender
このタスクを実行する別の方法もあります。ここで、com.foo.admin は完全なパッケージ名です。