2018-10-24 16:08:42 +02:00
|
|
|
|
|
|
|
module.exports = function(RED) {
|
|
|
|
"use strict";
|
|
|
|
var fs = require('fs');
|
|
|
|
var Tail = require('tail').Tail;
|
|
|
|
|
|
|
|
function TailNode(n) {
|
|
|
|
RED.nodes.createNode(this,n);
|
|
|
|
|
2019-08-15 23:03:13 +02:00
|
|
|
this.filename = n.filename || "";
|
2018-10-24 16:08:42 +02:00
|
|
|
this.filetype = n.filetype || "text";
|
2019-07-12 13:22:13 +02:00
|
|
|
this.split = new RegExp(n.split.replace(/\\r/g,'\r').replace(/\\n/g,'\n').replace(/\\t/g,'\t') || "[\r]{0,1}\n");
|
2018-10-24 16:08:42 +02:00
|
|
|
var node = this;
|
|
|
|
|
2022-01-16 18:23:45 +01:00
|
|
|
node.tout = null;
|
|
|
|
|
2018-10-24 16:08:42 +02:00
|
|
|
var fileTail = function() {
|
|
|
|
if (fs.existsSync(node.filename)) {
|
|
|
|
if (node.filetype === "text") {
|
|
|
|
node.tail = new Tail(node.filename,{separator:node.split, flushAtEOF:true});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
node.tail = new Tail(node.filename,{separator:null, flushAtEOF:true, encoding:"binary"});
|
|
|
|
}
|
|
|
|
|
|
|
|
node.tail.on("line", function(data) {
|
|
|
|
if (data.length > 0) {
|
|
|
|
var msg = { topic:node.filename };
|
|
|
|
if (node.filetype === "text") {
|
|
|
|
msg.payload = data.toString();
|
|
|
|
node.send(msg);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
msg.payload = Buffer.from(data,"binary");
|
|
|
|
node.send(msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
node.tail.on("error", function(err) {
|
2019-08-15 23:03:13 +02:00
|
|
|
node.status({ fill: "red",shape:"ring", text: "node-red:common.status.error" });
|
2018-10-24 16:08:42 +02:00
|
|
|
node.error(err.toString());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
2022-01-16 18:23:45 +01:00
|
|
|
scheduleRestart();
|
2019-07-12 13:22:13 +02:00
|
|
|
node.warn(RED._("tail.errors.filenotfound") + ": "+node.filename);
|
2018-10-24 16:08:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-16 18:23:45 +01:00
|
|
|
var scheduleRestart = function() {
|
|
|
|
node.tout = setTimeout(function() {
|
|
|
|
node.tout = null;
|
|
|
|
fileTail();
|
|
|
|
}, 10000);
|
|
|
|
};
|
|
|
|
|
|
|
|
var cancelRestart = function() {
|
|
|
|
if (isRestartPending()) {
|
|
|
|
clearTimeout(node.tout);
|
|
|
|
node.tout = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var isRestartPending = function() {
|
|
|
|
return node.tout !== null;
|
|
|
|
};
|
|
|
|
|
2019-08-15 23:03:13 +02:00
|
|
|
if (node.filename !== "") {
|
|
|
|
node.status({});
|
|
|
|
fileTail();
|
|
|
|
} else {
|
|
|
|
node.status({ fill: "grey", text: "tail.state.stopped" });
|
|
|
|
node.on('input', function (msg) {
|
|
|
|
if (!msg.hasOwnProperty("filename")) {
|
|
|
|
node.error(RED._("tail.state.nofilename"));
|
|
|
|
} else if (msg.filename === "") {
|
|
|
|
node.filename = "";
|
|
|
|
if (node.tail) { node.tail.unwatch(); }
|
2022-01-16 18:23:45 +01:00
|
|
|
cancelRestart();
|
2019-08-15 23:03:13 +02:00
|
|
|
node.status({ fill: "grey", text: "tail.state.stopped" });
|
|
|
|
} else {
|
|
|
|
node.filename = msg.filename;
|
|
|
|
if (node.tail) { node.tail.unwatch(); }
|
2022-01-16 18:23:45 +01:00
|
|
|
if (!isRestartPending()) { fileTail(); }
|
2019-08-15 23:03:13 +02:00
|
|
|
node.status({ fill: "green", text: node.filename });
|
2019-08-16 09:28:14 +02:00
|
|
|
}
|
2019-08-15 23:03:13 +02:00
|
|
|
});
|
|
|
|
}
|
2018-10-24 16:08:42 +02:00
|
|
|
|
|
|
|
node.on("close", function() {
|
|
|
|
/* istanbul ignore else */
|
|
|
|
if (node.tail) { node.tail.unwatch(); }
|
|
|
|
delete node.tail;
|
2022-01-16 18:23:45 +01:00
|
|
|
cancelRestart();
|
2018-10-24 16:08:42 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
RED.nodes.registerType("tail",TailNode);
|
|
|
|
}
|