soldair / node-tailfd

Tail a file. This will continue to work even if a file is unlinked rotated or truncated. It is also ok if the path doesnt exist before watching it
MIT License
8 stars 1 forks source link

First line is not emitted when file previously didn't exist #1

Closed maxkueng closed 11 years ago

maxkueng commented 11 years ago

Hello

This is a really awesome module! Thanks! I have noticed that when tailing a file that does not yet exist and then appending lines to it, the first line does not emit a "line" event.

I did some animal testing below.

Thanks and best regards Max

How to reproduce

Watch a file that does not yet exist:

var tail = require('tailfd').tail,
    watcher = tail('./animals.log'); // file does not exist yet

watcher.on('line', function (line, info) {
    console.log(line);
});

Then append some animals:

echo monkey >> animals.log
echo bird >> animals.log
echo spider >> animals.log

The watcher object does not emit a "line" event for "monkey" but it does for "bird" and "spider". Also tried elephants and lions. Same problem.

Workaround #1

Touch the file before writing to it.

Same as above:

var tail = require('tailfd').tail,
    watcher = tail('./animals.log'); // file does not exist yet

watcher.on('line', function (line, info) {
    console.log(line);
});

But touch the file before appending the first line:

touch animals.log
echo monkey >> animals.log
echo bird >> animals.log
echo spider >> animals.log

Emits "line" events for all the animals.

Workaround #2

Set negative start option

With start option -1 :

var tail = require('tailfd').tail,
    watcher = tail('./animals.log', { start: -1 }); // file does not exist yet

watcher.on('line', function (line, info) {
    console.log(line);
});

Append some animals without touching:

echo monkey >> animals.log
echo bird >> animals.log
echo spider >> animals.log

Emits "line" events for all the animals. First line can have a delay.

soldair commented 11 years ago

ha. awesome tests/examples thanks ill fix this.

soldair commented 11 years ago

its interesting. all of my test cases create watchers before creating the file. one thing though all of them specify {start:0} and they seem to get all lines. im on the case =)

soldair commented 11 years ago

ok cool.

the issue was that from my package watchfd i couldn't know when the init state was ENOENT so the default behavior with undefined start was to emit only new lines (the tail).

this is fixed an published to npm as tailfd@0.1.4. A test has been updated to not pass start to ensure no regression.

maxkueng commented 11 years ago

Yeah, you are awesome (and fast)! Thanks so much! Interesting, so it would have also worked with {start : 0} ? I didn't even try that, -1 was kind of out of intuition :)

soldair commented 11 years ago

no problem. yeah start:0 would have worked. -1 gets clamped to 0 because that's just a wrong file offset =)