0

Tailer の実装 ( commons-io Tailer ) が動作しています。これが私の Tailer です。

public class SyslogConsumer implements TailerListener {
     @Override
     public void handle(String line) { System.out.println(line);}
    ...
}

public void process() {
    TailerListener listener = new SyslogConsumer();
    final Tailer tailer = Tailer.create( path.toFile(), listener );
    Runtime.getRuntime().addShutdownHook( new Thread( "LogProcessor shutdown hook" ) {
        public void run() {
            tailer.stop();
        }
    } );
}

そして私のテスト:

public class LogProcessorTest {

    private static Path templog;
    private static final String logEvent = "May 1 00:00:00 this is valid";

    @Before
    public void setup()
        throws IOException
    {
        templog = Files.createTempFile( "logprocessing", ".log" );
        templog.toFile().deleteOnExit();
        BufferedWriter bw = new BufferedWriter( new FileWriter( templog.toFile() ) );
        bw.write( logEvent );
        bw.newLine();
        bw.close();
    }

    @Test
    public void testProcessingValidEntriesProducesEvents()
        throws IOException
    {
        // utility method that pipes stdout to my bytearray
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        TestUtils.captureStdOut( bos );

        LogProcessor proc = new LogProcessor( templog.toString() );
        proc.process();

        String s = bos.toString( "UTF-8" );
        Assert.assertEquals( logEvent, s );
    }
}

bos の内容が調べられる時点では空ですが、ログ ファイルには次の 2 行が含まれています。

>May 1 00:00:01 this is valid
>  

bash スクリプトを使用して作成および書き込みされたファイルにテストを向けると、次のようになります。

$ cat test/endlessLogGenerator.sh
#! /bin/bash
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
out="$DIR/data/logstream.out"
echo > $out
c=0
while :
do
    let c=$((c+1))
    echo $(date +"%b %d %T this is message $c") >> $out
    sleep 1
done

その後、完全に機能します。しかし、テスト ランナーでファイルを作成すると、リスナーが Tailer ハンドラーによって呼び出されることはありません。別のスレッドでファイルを作成しようとしたり、テストで作成されていない既存のファイルに書き込もうとしたり、Tailer に渡して監視した後にテストでファイルに書き込もうとしたりしましたが、何も機能しません。テスト ランナーでファイルへの書き込みを試みると、TailerListener が handle() メソッドを起動することはありません。私はEclipse内でJava 8を搭載したWindows 7でこれを実行しています。テストを実行している JVM によって書き込まれたファイルを使用して TailerListener の handle() メソッドを単体テストした経験のある人はいますか?

ありがとう。

4

1 に答える 1

0

私の問題は、Tailer が例外を飲み込み、静かにストリームを閉じることによって引き起こされたことが判明しました。

Tailer's run() implementation...

....    
    } catch (Exception e) {

        listener.handle(e);

    } finally {
        IOUtils.closeQuietly(reader);
    }
....

私の handle() 実装では、ログから日付を解析していましたが、DateTimeFormatter が正しいパターンで設定されていなかったため、Tailer によってキャッチされた未チェックのランタイム例外がスローされていました。この動作を設計するためのライブラリ実装者の奇妙な選択。

この警告は知っておくと便利な場合があるため、質問を削除するのではなく、そのままにしておきます。

于 2015-03-19T16:31:17.893 に答える