Skip to content

Commit

Permalink
[fix] Get tailFile function working on latest/all node versions
Browse files Browse the repository at this point in the history
  • Loading branch information
chjj committed Jun 10, 2015
1 parent 7f75b48 commit 45b1eeb
Showing 1 changed file with 84 additions and 35 deletions.
119 changes: 84 additions & 35 deletions lib/winston/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ var util = require('util'),
crypto = require('crypto'),
cycle = require('cycle'),
fs = require('fs'),
StringDecoder = require('string_decoder').StringDecoder,
Stream = require('stream').Stream,
config = require('./config');

//
Expand Down Expand Up @@ -337,60 +339,107 @@ exports.serialize = function (obj, key) {
return msg;
};


//
// ### function tailFile (options, callback)
// #### @options {Object} Options for tail.
// #### @callback {function} Callback to execute on every line.
// `tail -f` a file. Options must include file.
//
exports.tailFile = function tail(options, callback) {
var stream = fs.createReadStream(options.file, { encoding: 'utf8' }),
buff = '',
destroy,
row = 0;

destroy = stream.destroy.bind(stream);
stream.destroy = function () {};
exports.tailFile = function(options, callback) {
var buffer = new Buffer(64 * 1024)
, decode = new StringDecoder('utf8')
, stream = new Stream
, buff = ''
, pos = 0
, row = 0;

if (options.start === -1) {
delete options.start;
}

stream.on('data', function (data) {
var data = (buff + data).split(/\n+/),
l = data.length - 1,
i = 0;

for (; i < l; i++) {
if (options.start == null || row > options.start) {
callback(null, data[i]);
stream.readable = true;
stream.destroy = function() {
stream.destroyed = true;
stream.emit('end');
stream.emit('close');
};

fs.open(options.file, 'a+', 0644, function(err, fd) {
if (err) {
if (!callback) {
stream.emit('error', err);
} else {
callback(err);
}
row++;
stream.destroy();
return;
}

buff = data[l];
});
(function read() {
if (stream.destroyed) {
fs.close(fd);
return;
}

stream.on('error', function (err) {
callback(err);
destroy();
});
return fs.read(fd, buffer, 0, buffer.length, pos, function(err, bytes) {
if (err) {
if (!callback) {
stream.emit('error', err);
} else {
callback(err);
}
stream.destroy();
return;
}

stream.on('end', function () {
if (buff) {
stream.emit('line', buff);
buff = '';
}
if (!bytes) {
if (buff) {
if (options.start == null || row > options.start) {
if (!callback) {
stream.emit('line', buff);
} else {
callback(null, buff);
}
}
row++;
buff = '';
}
return setTimeout(read, 1000);
}

var data = decode.write(buffer.slice(0, bytes));

if (!callback) {
stream.emit('data', data);
}

var data = (buff + data).split(/\n+/)
, l = data.length - 1
, i = 0;

for (; i < l; i++) {
if (options.start == null || row > options.start) {
if (!callback) {
stream.emit('line', data[i]);
} else {
callback(null, data[i]);
}
}
row++;
}

buff = data[l];

pos += bytes;

resume();
return read();
});
})();
});

function resume() {
setTimeout(function () {
stream.resume();
}, 1000);
if (!callback) {
return stream;
}

return destroy;
return stream.destroy;
};

0 comments on commit 45b1eeb

Please sign in to comment.