npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

tail-stream

v0.3.4

Published

Like 'tail -f' but a stream.

Downloads

2,949

Readme

NPM Build Status

About

tail-stream has one function: ts.createReadStream which is like fs.createReadStream, but does not stop reading the file when end of file is reached. Instead, it watches the file using fs.watch if available or fs.watchFile otherwise, and streams data as the file grows.

Options

  • beginAt: Where to begin reading. This can be an offset in number of bytes or 'end' (default: 0).
  • detectTruncate: Perform truncate detection (default: true)
  • onTruncate: What to do when truncate is detected. Set to 'end' to end the stream, or 'reset' to seek to the beginning of the file and resume reading (default: 'end').
  • onMove: What to do when the file is moved/renamed. Can be 'error' to give an error, 'end' to end the stream, 'follow' to continue streaming the file, or 'stay' to wait for another file to appear at the file's old path and resume streaming from the new file when it appears (default: 'follow').
  • endOnError: If set to true, the stream will end if an error occurs (default: false).
  • useWatch: If true, fs.watch will be used if available, otherwise fs.watchFile will be used. If false, fs.watchFile will always be used (default: true).
  • waitForCreate: Set this to true if the watched file does not yet exist.

Events

error

If opts.endOnError is set, then error events are never emitted. Only end events.

eof

eof events are emitted whenever the end of file is encountered. eof events can be emitted multiple times if someone is writing to the file slower than it is being read.

end

The 'end' event is only emitted if an error is encountered and opts.endOnError is true, or if the file is truncated and opts.onTruncate is set to 'end'.

move

move events are emitted if opts.onMove is set to either 'follow' or 'stay'. If the operating system has support for it, the event callback receives two arguments the old, pre-move absolute path of the file and the new, post-move absolute path of the file. For more information on operating system support, see the FAQ below.

truncate

truncate events are emitted whenever the filesize is changed to less than the previous file size. It sends along the new size and previous size as arguments.

truncate events are emitted unless opts.detectTruncate is set to false.

replace

If opts.onMove is set to 'stay' and the original file was moved then the new 'replace' event is emitted when a new file appears at the old path of the original file.

Example

More examples available in the examples directory.

var ts = require('tail-stream');

var tstream = ts.createReadStream('foo', {
    beginAt: 0,
    onMove: 'follow',
    detectTruncate: true,
    onTruncate: 'end',
    endOnError: false
});

tstream.on('data', function(data) {
    console.log("got data: " + data);
});

tstream.on('eof', function() {
    console.log("reached end of file");
});

tstream.on('move', function(oldpath, newpath) {
    console.log("file moved from: " + oldpath + " to " + newpath);
});

tstream.on('truncate', function(newsize, oldsize) {
    console.log("file truncated from: " + oldsize + " to " + newsize);
});

tstream.on('end', function() {
    console.log("ended");
});

tstream.on('error', function(err) {
    console.log("error: " + err); 
});

FAQ

How do I use this to follow a rotating log?

You need to set the onMove option to 'stay'. Look at examples/log_rotate.js to see how it's done.

What happens if the file is deleted?

If endOnError is set, then the stream ends. If endOnError is not set, then an error event is emittted stating that the file was deleted.

What happens if the file is changed but the length stays the same?

An 'eof' event is emitted. No other events are emitted.

What happens if the file is moved/renamed?

If onMove is 'follow'

If the operating system has the /proc/self/fd folder (only modern Linux and *nix with procfs) then everything will work as expected.

If the operating system does not have the /proc/self/fd folder, but fs.watch is available, then the 'move' event callback will receive null instead of the new file path, and subsequent move events will receive null instead of both the old and new file paths. Also, if truncate detection is enabled it will stop functioning after move, meaning that subsequent truncates will only result in an eof event.

If the operating system does not have the /proc/self/fd folder, and fs.watch is not available, then the move/rename is detected as a file deletion, resulting in an error event stating that the file was deleted.

If onMove is 'error' or 'end'

If the operating system has the /proc/self/fd folder or fs.watch is available, then everything works as expected.

If the operating system does not have the /proc/self/fd folder, and fs.watch is not available, then the move/rename is detected as a file deletion, resulting in an error event stating that the file was deleted.

If onMove is 'stay'

This always works as expected, but fs.watchFile is used when waiting for a replacement file to appear. Since fs.watchFile relies on stat polling, there can be a delay between when the replacement file appears and when it is reported. fs.watch is still used when not waiting for a replacement file to appear.

ToDo

  • Test on other operating systems.

Gotchas

Fails on travis-ci for node v0.12 even though it succeeds on v0.10 and v6.10 and works on my local machine on v0.12

License

License is GPLv3.