Search code examples
node.jsloggingbackendmonitoringserver-side

How can we keep watching a large log file and output the last 10 lines using node.js without using external package and tail -f?


I am having a large log file on my server and I want to keep watching that log file and get only last 10 lines of that log file without using the tail -f or any other packages which provides the same functionality as tail -f in unix.

We can do this by just traversing the log file from start and get last 10 lines but in case of large log file it will create a problem.

Let me know if there is any other alternatives ?

Thanks!


Solution

  • A (probably naive) attempt to emulate tail -n:

    import fs from 'fs';
    
    const path = 'test.txt';
    const lastLinesLimit = 5;
    
    const fileSize = fs.statSync(path).size;
    const fd = fs.openSync(path);
    
    // Increase the next number appropriately to decrease read calls.
    let bufferSize = Math.min(10, fileSize);
    let buffer = Buffer.alloc(bufferSize);
    
    let stringTail = '';
    let position = fileSize;
    
    while (position !== 0) { // Rapeat from end till start of file.
      position -= bufferSize; // Step back by buffer size.
    
      if (position < 0) { // In case we reach too far:
        bufferSize += position; // decrease buffer size to read just what remains,
        buffer = buffer.subarray(0, position); // decrease buffer appropriately,
        position = 0; // set position at start of file.
      }
    
      fs.readSync(fd, buffer, 0, bufferSize, position); // Read a chunk.
      stringTail = buffer.toString() + stringTail; // Prepend to previously read data.
      if (stringTail.match(/\n(?!$)/g)?.length >= lastLinesLimit) break; // Check if we have enough lines.
    }
    
    console.log(
      stringTail
        .split(/\n(?!$)/)
        .slice(-lastLinesLimit)
        .join('\n')
    );