I can explain to you why it behaves this way:
<command 1> | <command 2>
- The shell creates 2 subprocesses (fork), lets call them sp1 and sp2.
- Set up a pipe (I/O) between sp1's output and sp2's input.
- Start (exec) <command 1> in process sp1.
- Start (exec) <command 2> in process sp2.
- Wait for both prcesses to finish.
The last line is the reason why this will work with tail -1 and _not_ with tail -f. The shell will wait untill both processes are ready, tail -f will never be ready, hench: no output.
If you put a trace on your script you will get confirmation for this behavior:
rt_sigaction(SIGINT, {0x80701a0, [], 0x4000000}, {SIG_DFL}, 8) = 0
wait4(-1,
No more output after the above 2 lines. Shell is waiting for one of the processes (the tail -f in this case) to finish.
I don't know how to avoid this (restarting syslogd everytime you run the script won't be an option

, but will work).
You could consider to fetch all the lines from the logfile that haven't been processesed (based on timestamps), put these in a seperate file and use that file.