16

I am working on a monitoring program that reads the /var/log/auth.log file. I am using Apache Commons IO Tailer class to read the file in real time. To get started, I wanted to test the real-time reading part on a simple file, and manually enter some code in the console line. Here is my code:

public class Main {
    public static void main(String[] args) {
        TailerListener listener = new MyListener();
        Tailer tailer = Tailer.create(new File("log.txt"), listener, 500);
        while(true) {

        }
    }
}

public class MyListener extends TailerListenerAdapter {
    @Override
    public void handle(String line) {
        System.out.println(line);
    }
}

And from the terminal : sudo echo "Hello" >> log.txt The problem is when I try to write manually something in the file, it does not print it in the console. I tried to find a concrete example of usage of Tailer class, but no luck. What am I doing wrong here?

Duncan Jones
  • 59,308
  • 24
  • 169
  • 227
user2435860
  • 738
  • 3
  • 9
  • 19
  • `while(true) {}` is never a good idea. Are you launching the MyListener in a separate thread? You should at least add a `Thread.sleep(...)` to your loop. – SebastianH Apr 10 '14 at 12:17
  • I'm not sure why you got a down-vote. Seems a clear question with code that demonstrates the problem. – Duncan Jones Apr 10 '14 at 13:44
  • could you please rate it? I tried to make it clear, expose the problem, and show the sample of my code. I respected stackoverflow's conditions – user2435860 Apr 10 '14 at 13:48

2 Answers2

19

Based on my testing, Tailer will only print a line when you've added a newline to the file. So try sudo echo "Hello\n" >> log.txt

Also note that if you call create, you start a thread but have no handle on it. Hence why you had to have a while/true loop.

You could try this instead:

public static void main(String[] args) {
    TailerListener listener = new MyListener();
    Tailer tailer = new Tailer(new File("log.txt"), listener, 500);        
    tailer.run();
}
Duncan Jones
  • 59,308
  • 24
  • 169
  • 227
  • 2
    OK, so I've done what you said, and it is working. One thing though, i prints the output twice. for instance, if I try to write in the terminal echo "Hello" >> log.txt, it will print "Hello" twice in the console. Why is that? – user2435860 Apr 10 '14 at 12:35
  • 4
    @user2435860 I would guess that's because you've still got `Tailer tailer = Tailer.create` rather than `Tailer tailer = new Tailer`? That mistake would cause you to have two threads running, each printing to stdout. – Duncan Jones Apr 10 '14 at 12:49
  • Thank you very much, that solved my problem. I thought that using create is the only way to create a new instance. I had the feeling that the constructor is not public, so this is why I used tha Factory method using create. Now it works perfectly. Now I can pass to the next step which is parsing. Thanks a lot! Cheers! – user2435860 Apr 10 '14 at 13:08
1

Your code should work. For me, this does works as expected.

package de.lhorn.stackoverflowplayground;

import java.io.File;
import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListenerAdapter;

public class App {

    private static final int SLEEP = 500;

    public static void main(String[] args) throws Exception {
        App app = new App();
        app.run();
    }

    private void run() throws InterruptedException {
        MyListener listener = new MyListener();
        Tailer tailer = Tailer.create(new File("/tmp/log.txt"), listener, SLEEP);
        while (true) {
            Thread.sleep(SLEEP);
        }
    }

    public class MyListener extends TailerListenerAdapter {

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

    }
}