Node.js监视文件的变化并解析它们

时间:2016-07-04 18:56:00

标签: javascript node.js watch logfile

我需要监控文件的变化。由于此文件有大量新条目,我需要“监控”此文件。我需要将新插入的内容添加到此文件中,以便能够解析此内容。

我找到了这段代码:

fs.watchFile('var/log/query.log', function() {
console.log('File Changed ...');
//how to get the new line which is now inserted?
});

2 个答案:

答案 0 :(得分:2)

在bash上你会用tail --follow做类似的事情。

还有一个包tail可用。 你可以在一个文件上观看,并通过一个事件得到新的一行:

const Tail = require('tail').Tail;
var tail = new Tail("var/log/query.log");
tail.watch()
tail.on("line", data => {
  console.log(data);
});

答案 1 :(得分:1)

以下是我如何使用fs.watchFile监控名为Hearthstone的游戏的日志文件并选择新的日志条目以监控游戏时发生的事件的示例。 https://github.com/chevex-archived/hearthstone-log-watcher/blob/master/index.js

var fs = require('fs');
var options = {
  logFile: '~/Library/Preferences/Blizzard/Hearthstone/log.config',
  endOfLineChar: require('os').EOL
};
// Obtain the initial size of the log file before we begin watching it.
var fileSize = fs.statSync(options.logFile).size;
fs.watchFile(options.logFile, function (current, previous) {
  // Check if file modified time is less than last time.
  // If so, nothing changed so don't bother parsing.
  if (current.mtime <= previous.mtime) { return; }

  // We're only going to read the portion of the file that
  // we have not read so far. Obtain new file size.
  var newFileSize = fs.statSync(options.logFile).size;
  // Calculate size difference.
  var sizeDiff = newFileSize - fileSize;
  // If less than zero then Hearthstone truncated its log file
  // since we last read it in order to save space.
  // Set fileSize to zero and set the size difference to the current
  // size of the file.
  if (sizeDiff < 0) {
    fileSize = 0;
    sizeDiff = newFileSize;
  }
  // Create a buffer to hold only the data we intend to read.
  var buffer = new Buffer(sizeDiff);
  // Obtain reference to the file's descriptor.
  var fileDescriptor = fs.openSync(options.logFile, 'r');
  // Synchronously read from the file starting from where we read
  // to last time and store data in our buffer.
  fs.readSync(fileDescriptor, buffer, 0, sizeDiff, fileSize);
  fs.closeSync(fileDescriptor); // close the file
  // Set old file size to the new size for next read.
  fileSize = newFileSize;

  // Parse the line(s) in the buffer.
  parseBuffer(buffer);
});

function stop () {
  fs.unwatchFile(options.logFile);
};

function parseBuffer (buffer) {
  // Iterate over each line in the buffer.
  buffer.toString().split(options.endOfLineChar).forEach(function (line) {
    // Do stuff with the line :)
  });
};

它首先计算文件的初始大小,因为在这个日志观察器模块中我只想读取游戏编写的新数据。我不关心现有数据。然后它开始观察文件的变化。当更改处理程序触发时,我们检查修改的时间是否真的更新,因为当我们关心的数据没有实际更改时,有关该文件的其他一些更改可以触发处理程序。我们希望这个观察者能够尽可能地发挥作用。

然后我们读取文件的新大小并计算与上次的差异。这告诉我们从文件中读取多少数据以仅获取新写入的数据。然后我们将数据存储在缓冲区中并将其解析为字符串。只需用换行符分割字符串即可。使用核心模块os来获取os.EOL将为您运行的操作系统提供正确的行结束字符(Windows行结束字符与linux / unix不同)。

现在你有一个写入文件的行数组:)