15

Javaアプリ内から多くのログファイルを「Tail-f」したいと思います。

サイズと最終更新を監視し、ファイルを繰り返し開いて、ファイルサイズまたは最終更新時刻が変更されるたびに最後の数バイトを読み取り、すぐに閉じることで、これを機能させることができました。

ロガーがファイルの名前を変更することを決定したときにファイルを開く可能性があるため、これは問題があるようです。これにより、何らかの問題が発生します。

また、ファイルサイズが減少したことに気付くよりも確実なメカニズムで「ロール」ファイルを検出したいと思います...エラーが発生しやすいようですが、ありそうにありません。

ファイル記述子やその他の低レベルのファイルユーティリティにアクセスできないため、テールの動作を再現できない可能性がありますが、名前の変更/削除のためにファイルを「ロック」せずにファイルを読み取るためのトリックはありますか? Windows 7)

別の可能性は、実際にtail -fプロセスを生成してプロセス出力を読み取ることだと思いますが、それはやや重いようです。ここでは60個のログファイルのようにスキャンしており、そのうちのいくつかは大量の出力を持っています(ほとんどはアイドル状態になります)。

4

3 に答える 3

8

Apache Commons has a Tailer class, would that do what you want? If it would, it has rolling detection mechanism as well as the reading stuff, so you'd get all you need.

If that cannot do it, it might be that there's no way of doing it with pure java. You'd need some help of, for example, C code, utilizing fopen with SH_DENYNO parameter allowing shared open on windows. Or then just call a tail implementation by executing a system command.

But since the code opening the log file is the one causing the lock on it, even that might not help. In that case the only real option is to change the way your logging works, as that is the culprit locking the file. Log4j can use a SocketAppender, among other things.

于 2013-01-30T20:58:56.013 に答える
6

Use apache.commons.io

And here is a simple example

public class LogTailTest {

/**
* TailerListener implementation.
*/
static public class ShowLinesListener extends TailerListenerAdapter {
    @Override
    public void handle(String line) {
        System.out.println(line);
    }
}

public static void main(String args[]) {

    TailerListener listener  = new ShowLinesListener();
    File file = new File("./test.log");

    Tailer tailer = new Tailer(file, listener, 1000);
    tailer.run();

    try {
        Thread.sleep(100000);
    } catch(InterruptedException ex) {
        Thread.currentThread().interrupt();
    }

    tailer.stop();
}

}

于 2013-03-07T18:54:07.163 に答える
1

In Linux you would not have a problem since the locking is only advisory. But in Windows things are different.
This should depend on the mode that your logger (I assume log4j) opens the file to log.
Looking in this answer for C# it seems that there is a parameter dwShareMode that can be used for this kind of sharing.

I believe NIO would be the way to go. Look if dwShareMode parameter is available as part of NIO APIs

于 2013-01-30T20:31:55.190 に答える