UNPKG

pimatic-log-reader

Version:

Provides predicates for log entries in log files of other programs.

199 lines (185 loc) 6.32 kB
// Generated by CoffeeScript 1.10.0 var Tail, environment, events, fs, bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; events = require("events"); fs = require('fs'); environment = process.env['NODE_ENV'] || 'development'; Tail = (function(superClass) { extend(Tail, superClass); Tail.prototype.readBlock = function() { var block, stream; if (this.queue.length >= 1) { block = this.queue.shift(); if (block.end > block.start) { stream = fs.createReadStream(this.filename, { start: block.start, end: block.end - 1, encoding: this.encoding }); stream.on('error', (function(_this) { return function(error) { if (_this.logger) { _this.logger.error("Tail error: " + error); } return _this.emit('error', error); }; })(this)); stream.on('end', (function(_this) { return function() { if (_this.queue.length >= 1) { return _this.internalDispatcher.emit("next"); } }; })(this)); return stream.on('data', (function(_this) { return function(data) { var chunk, i, len, parts, results; _this.buffer += data; parts = _this.buffer.split(_this.separator); _this.buffer = parts.pop(); results = []; for (i = 0, len = parts.length; i < len; i++) { chunk = parts[i]; results.push(_this.emit("line", chunk)); } return results; }; })(this)); } } }; function Tail(filename, options) { var pos, ref, ref1, ref2, ref3, ref4, ref5; this.filename = filename; if (options == null) { options = {}; } this.readBlock = bind(this.readBlock, this); this.separator = (ref = options.separator) != null ? ref : /[\r]{0,1}\n/, this.fsWatchOptions = (ref1 = options.fsWatchOptions) != null ? ref1 : {}, this.fromBeginning = (ref2 = options.fromBeginning) != null ? ref2 : false, this.follow = (ref3 = options.follow) != null ? ref3 : true, this.logger = options.logger, this.useWatchFile = (ref4 = options.useWatchFile) != null ? ref4 : false, this.encoding = (ref5 = options.encoding) != null ? ref5 : "utf-8"; if (this.logger) { this.logger.info("Tail starting..."); this.logger.info("filename: " + this.filename); this.logger.info("encoding: " + this.encoding); } this.buffer = ''; this.internalDispatcher = new events.EventEmitter(); this.queue = []; this.isWatching = false; this.internalDispatcher.on('next', (function(_this) { return function() { return _this.readBlock(); }; })(this)); if (this.fromBeginning) { pos = 0; } this.watch(pos); } Tail.prototype.watch = function(pos) { var err, error1, stats; if (this.isWatching) { return; } this.isWatching = true; try { stats = fs.statSync(this.filename); } catch (error1) { err = error1; if (this.logger) { this.logger.error("watch for " + this.filename + " failed: " + this.err); } this.emit("error", "watch for " + this.filename + " failed: " + this.err); return; } this.pos = pos != null ? pos : stats.size; if (this.logger) { this.logger.info("filesystem.watch present? " + (fs.watch !== void 0)); this.logger.info("useWatchFile: " + this.useWatchFile); } if (!this.useWatchFile && fs.watch) { if (this.logger) { this.logger.info("watch strategy: watch"); } return this.watcher = fs.watch(this.filename, this.fsWatchOptions, (function(_this) { return function(e) { return _this.watchEvent(e); }; })(this)); } else { if (this.logger) { this.logger.info("watch strategy: watchFile"); } return fs.watchFile(this.filename, this.fsWatchOptions, (function(_this) { return function(curr, prev) { return _this.watchFileEvent(curr, prev); }; })(this)); } }; Tail.prototype.watchEvent = function(e) { var err, error1, stats; if (e === 'change') { try { stats = fs.statSync(this.filename); } catch (error1) { err = error1; if (this.logger) { this.logger.error("'change' event for " + this.filename + ". " + this.err); } this.emit("error", "'change' event for " + this.filename + ". " + this.err); return; } if (stats.size < this.pos) { this.pos = stats.size; } if (stats.size > this.pos) { this.queue.push({ start: this.pos, end: stats.size }); this.pos = stats.size; if (this.queue.length === 1) { return this.internalDispatcher.emit("next"); } } } else if (e === 'rename') { this.unwatch(); if (this.follow) { return setTimeout(((function(_this) { return function() { return _this.watch(); }; })(this)), 1000); } else { if (this.logger) { this.logger.error("'rename' event for " + this.filename + ". File not available."); } return this.emit("error", "'rename' event for " + this.filename + ". File not available."); } } }; Tail.prototype.watchFileEvent = function(curr, prev) { if (curr.size > prev.size) { this.queue.push({ start: prev.size, end: curr.size }); if (this.queue.length === 1) { return this.internalDispatcher.emit("next"); } } }; Tail.prototype.unwatch = function() { if (this.watcher) { this.watcher.close(); } else { fs.unwatchFile(this.filename); } this.isWatching = false; return this.queue = []; }; return Tail; })(events.EventEmitter); exports.Tail = Tail;