src/misc/bunyan.js
function processFile(file, opts, stylize, callback) {
    var stream = fs.createReadStream(file);
    if (/\.gz$/.test(file)) {
        stream = stream.pipe(require('zlib').createGunzip());
    }
    // Manually decode streams - lazy load here as per node/lib/fs.js
    var decoder = new (require('string_decoder')
      .StringDecoder)('utf8');

    streams[file].stream = stream;

    stream.on('error', function (err) {
        streams[file].done = true;
        callback(err);
    });

    var leftover = '';  // Left-over partial line from last chunk.
    stream.on('data', function (data) {
        var chunk = decoder.write(data);
        if (!chunk.length) {
            return;
        }
        var lines = chunk.split(/\r\n|\n/);
        var length = lines.length;
        if (length === 1) {
            leftover += lines[0];
            return;
        }

        if (length > 1) {
            handleLogLine(file, leftover + lines[0], opts, stylize);
        }
        leftover = lines.pop();
        length -= 1;
        for (var i = 1; i < length; i++) {
            handleLogLine(file, lines[i], opts, stylize);
        }
    });

    stream.on('end', function () {
        streams[file].done = true;
        if (leftover) {
            handleLogLine(file, leftover, opts, stylize);
            leftover = '';
        } else {
            emitNextRecord(opts, stylize);
        }
        callback();
    });
}
function processFile(file, opts, stylize, callback) {
    var stream = fs.createReadStream(file);
    if (/\.gz$/.test(file)) {
        stream = stream.pipe(require('zlib').createGunzip());
    }
    // Manually decode streams - lazy load here as per node/lib/fs.js
    var decoder = new (require('string_decoder')
      .StringDecoder)('utf8');

    streams[file].stream = stream;

    stream.on('error', function (err) {
        streams[file].done = true;
        callback(err);
    });

    var leftover = '';  // Left-over partial line from last chunk.
    stream.on('data', function (data) {
        var chunk = decoder.write(data);
        if (!chunk.length) {
            return;
        }
        var lines = chunk.split(/\r\n|\n/);
        var length = lines.length;
        if (length === 1) {
            leftover += lines[0];
            return;
        }

        if (length > 1) {
            handleLogLine(file, leftover + lines[0], opts, stylize);
        }
        leftover = lines.pop();
        length -= 1;
        for (var i = 1; i < length; i++) {
            handleLogLine(file, lines[i], opts, stylize);
        }
    });

    stream.on('end', function () {
        streams[file].done = true;
        if (leftover) {
            handleLogLine(file, leftover, opts, stylize);
            leftover = '';
        } else {
            emitNextRecord(opts, stylize);
        }
        callback();
    });
}
Process all input from the given log file.

@param file {String} Log file path to process.
@params opts {Object} Bunyan options object.
@param stylize {Function} Output stylize function to use.
@param callback {Function} `function ()`