如何在 node.js 中进行类似`tail -f logfile.txt`的处理?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8993611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:04:05  来源:igfitidea点击:

How to do `tail -f logfile.txt`-like processing in node.js?

node.js

提问by mike

tail -f logfile.txtoutputs the last 10 lines of logfile.txt, and then continues to output appended data as the file grows.

tail -f logfile.txt输出 logfile.txt 的最后 10 行,然后随着文件的增长继续输出附加数据。

What's the recommended way of doing the -fpart in node.js?

-f在 node.js中执行该部分的推荐方法是什么?

The following outputs the entire file (ignoring the "show the last 10 lines") and then exits.

以下输出整个文件(忽略“显示最后 10 行”)然后退出。

var fs = require('fs');
var rs = fs.createReadStream('logfile.txt', { flags: 'r', encoding: 'utf8'});
rs.on('data', function(data) {
  console.log(data);
});

I understand the event-loop is exiting because after the stream end & close event there are no more events -- I'm curious about the best way of continuing to monitor the stream.

我知道事件循环正在退出,因为在流结束和关闭事件之后没有更多的事件——我很好奇继续监视流的最佳方式。

回答by Rohan Singh

The canonical way to do this is with fs.watchFile.

执行此操作的规范方法是使用fs.watchFile.

Alternatively, you could just use the node-tail module, which uses fs.watchFileinternally and has already done the work for you. Here is an example of using it straight from the documentation:

或者,您可以只使用node-tail 模块,它在fs.watchFile内部使用并且已经为您完成了工作。这是直接从文档中使用它的示例:

Tail = require('tail').Tail;

tail = new Tail("fileToTail");

tail.on("line", function(data) {
  console.log(data);
});

回答by Tackle

node.js APi documentationon fs.watchFilestates:

关于fs.watchFile状态的node.js APi 文档

Stability: 2 - Unstable. Use fs.watch instead, if available.

稳定性:2 - 不稳定。如果可用,请改用 fs.watch。

Funny though that it says almostthe exact same thing for fs.watch:

虽然搞怪,它说,几乎在同样的事情fs.watch

Stability: 2 - Unstable. Not available on all platforms.

稳定性:2 - 不稳定。并非在所有平台上都可用。

In any case, I went ahead and did yet another small webapp, TailGate, that will tail your files using the fs.watchvariant.

无论如何,我继续做了另一个小网络应用程序TailGate,它将使用该fs.watch变体来跟踪您的文件。

Feel free to check it out here: TailGate on github.

随意在这里查看: github 上的 TailGate

回答by Woody

Substack has a file slicemodule that behaves exactly like tail -f, slice-file can stream updates after the initial slice of 10 lines.

Substack 有一个文件切片模块,其行为与tail -f, slice-file 可以在 10 行的初始切片之后流式更新。

var sf = require('slice-file');

var xs = sf('/var/log/mylogfile.txt');
xs.follow(-10).pipe(process.stdout);

Source: https://github.com/substack/slice-file#follow

来源:https: //github.com/substack/slice-file#follow

回答by Andrey Sidorov

you can try to use fs.readinstead of ReadStream

您可以尝试使用fs.read而不是 ReadStream

var fs = require('fs')

var buf = new Buffer(16);
buf.fill(0);
function read(fd)
{
    fs.read(fd, buf, 0, buf.length, null, function(err, bytesRead, buf1) {
        console.log(buf1.toString());
        if (bytesRead != 0) {
            read(fd);
        } else {
            setTimeout(function() {
                read(fd);
            }, 1000);
        }
    }); 
}

fs.open('logfile', 'r', function(err, fd) {
    read(fd);
});

Note that read calls callback even if there is no data and it just reached end of file. Without timeout you'll get 100% cpu here. You could try to use fs.watchFileto get new data immediately.

请注意,即使没有数据并且刚刚到达文件末尾, read 也会调用回调。如果没有超时,您将在这里获得 100% 的 CPU。您可以尝试使用fs.watchFile立即获取新数据。

回答by user1278519

https://github.com/jandre/always-tailseems a great option if you have to worry about log rotating, example from the readme:

如果您不得不担心日志轮换,https://github.com/jandre/always-tail似乎是一个不错的选择,例如自述文件:

var Tail = require('always-tail');
var fs = require('fs');
var filename = "/tmp/testlog";

if (!fs.existsSync(filename)) fs.writeFileSync(filename, "");

var tail = new Tail(filename, '\n');

tail.on('line', function(data) {
  console.log("got line:", data);
});


tail.on('error', function(data) {
  console.log("error:", data);
});

tail.watch();