реализовать `tail -f` в nodejs со слежением за линией, чтобы продолжить с последней позиции после сбоя - PullRequest
0 голосов
/ 26 марта 2020

Я реализую функцию для имитации поведения tail -f для отслеживания файла. Если программа скрипит, я хочу возобновить отслеживание с того места, где остановился в прошлый раз, что-то вроде tail -n. Я добавил счетчик строк, чтобы отслеживать текущую позицию в файле.

const fs = require('fs-extra');
const path = require('path');
const debug = require('debug')('TAIL.JS');

module.exports = async (taskDir) => {
  const fName = path.join(taskDir, 'out.log');
  let fNameStat = await fs.stat(fName);
  let lineCount = 0;
  let lastLine = null;

  if (await fs.exists(`${taskDir}/lastLine.txt`)) {
    lastLine = parseInt(await fs.readFile(`${taskDir}/lastLine.txt`), 10);
  }


  fs.watch(fName, () => {
    const fNameStatChanged = fs.statSync(fName);

    fs.open(fName, 'r', (err, fd) => {
      const newDataLength = fNameStatChanged.size - fNameStat.size;
      let startPosition = fNameStat.size;
      const buffer = Buffer.alloc(newDataLength, 'utf-8');

      debug('File Size: ', fNameStat.size);

      // If crashed after reloading set position param. to lastLine
      if (lastLine) startPosition = lastLine;
      fs.read(fd, buffer, 0, newDataLength, startPosition, async (error, bytesRead, newData) => {
        const change = newData.toString();

        if (error) { console.error(error); }
        if (change.includes('\n')) {
          lineCount += 1;
          await fs.writeFile(path.join(taskDir, 'lastLine.txt'), lineCount);
        }
        console.log(change);
      });
      lastLine = null;
      fNameStat = fs.statSync(fName);
    });
  });
};

Я сохраняю текущую позицию в файл и читаю из нее при перезагрузке. По сути, я хочу установить для параметра position для fs.read() содержимое файла lastLine.txt. Как у меня сейчас, отлично работает при первом запуске и печатает измененные данные, в этом случае позиция меняется вместе с данными. При повторной загрузке после присвоения позиции из файла она становится stati c и печатается только одно число из out.log

Требуемое поведение для функции - начать отслеживание с последней позиции, распечатать все пропустил содержимое на экран и продолжил отслеживать изменения.

Для тестирования я запускаю bash l oop, который печатает текущий индекс и перенаправляет вывод на out.log

...