###前提・実現したいこと
掲題の通りなのですが、javaでログ出力(イベントログ的)の機能を作成したいです。
複数プロセスから同時に書込みがされる事を考え排他制御を行いたいのですが、
素人考えで作成すると排他制御できずにログ内容が混ざって出力されたりすることが不安です。
通常、javaでログ出力機能を作成する場合、どのような方法を取るのでしょうか?
簡単な方法があるのでしょうか?ご教授お願いいたします。
また、排他制御は大きく分けて以下の2パターンになるかと思うのですが、パターン(1)は実現可能でしょうか?
(1)ログ書込み前に排他を取り、既に取られている場合、開放されるまで待機し、解放後処理継続する。
(2)ログ書込み前に排他を取り、既に取られている場合、一定時間待機し、規定回数リトライを行う。一定期間内に排他が開放された場合、ログ出力を行い、開放されなかった場合、ログ出力エラーで例外扱いとする。
質問ばかりで申し訳ありませんが、ご回答の程宜しくお願い致します。
###補足情報(言語/FW/ツール等のバージョンなど)
使用しているのは、java7になります。
###該当のソースコード
package jp.sample;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
/**
- ログ出力機能のサンプルクラスです。
*/
public class LogWritter {
/** 最大リトライ回数 */ private static final int MAX_RETRY_COUNT = 3; /** インターバル(ミリ秒) */ private static final int RETRY_INTERVAL = 10000; public static void main(String[] args) throws IOException { logWritter("user123", "OK", "2016-0807-1200-00"); } /** * ログ出力の処理です。(引数はとりあえず固定値) * * @param userId ユーザーID * @param result 処理結果 * @param trunDate 処理日時 * @throws IOException */ private static void logWritter(String userId, String result, String trunDate) throws IOException { // ログ出力内容を編集する StringBuilder sb = new StringBuilder(); sb.append(userId); sb.append(result); sb.append(trunDate); sb.append(System.getProperty("line.separator")); // 改行コード File file = new File("C:/work/log/test.log"); FileOutputStream fs = null; int retryCount = 0; try { while (true) { if (retryCount > MAX_RETRY_COUNT) { break; } fs = new FileOutputStream(file, true); FileChannel ch = fs.getChannel(); FileLock lock = null; try { lock = ch.tryLock(); //ロックを取得 // 他プロセスがロック取得してない場合、ログ出力処理を行う。 // ロックがかかっていた場合、1秒待機後にリトライを行う。 if (lock != null) { fs.write(new String(sb).getBytes("UTF-8")); break; } else { Thread.sleep(RETRY_INTERVAL); retryCount++; } } catch (InterruptedException e) { System.out.println("Thread.sleepで例外発生"); e.printStackTrace(); break; } finally { if (lock != null) { System.out.println("排他ロックの開放"); lock.release(); } } } } finally { if (fs != null) System.out.println("ファイルストリームのクローズ"); fs.close(); } }
}
回答2件
あなたの回答
tips
プレビュー