来自Expressjs documentation:
为了让您的应用完全异步,您仍然想要管道 console.err()到另一个程序
Qestions:
node app 2>&1 | tee logFile
?如果ad.1答案为真,那么在使用Winston或Bunyan时如何实现非阻塞日志记录?他们有一些内置机制来实现这一点,或者他们只是将数据保存到特定文件浪费当前Node.js进程的cpu时间?或者可能要实现trully异步日志记录,他们应该将数据传输到子进程,执行"保存到文件" (它仍然表现积极吗?)?如果我的思维方式错了,任何人都可以解释或纠正我吗?
已编辑的部分:我可以假设从流程A,B,......等到流程L的管道数据对于此特定流程(A,B,...)更便宜而不是写入文件(或通过网络发送)。 要点: 我正在为使用nodejs集群的应用程序设计logger。 简而言之 - 进程(L)之一将处理来自其他人的数据流,(A,B,......)。 进程L将对消息进行排队(例如逐行或其他特殊分隔符)并将其逐个记录到文件,db或其他任何位置。 这种方法的优点是减少了可能花费更多时间完成工作的流程负载。 还有一件事 - 假设是简化这个库的使用,因此用户只需要包含这个记录器而不需要通过shell进行任何额外的交互(流重定向)。 你认为这个解决方案有意义吗?也许你知道一个已经这样做的图书馆?
答案 0 :(得分:1)
让我们先建立一些地面......
写入终端屏幕(console.log()
等),写入文件(fs.writeFile()
,fs.writeFileSync()
等)或将数据发送到流process.stdout.write(data)
等。 )将始终"阻止事件循环"。为什么?因为这些函数的某些部分总是用JavaScript编写。这些函数所需的最少工作量是获取输入并将其交给某些本机代码,但是某些JS将始终执行。
由于JS参与其中,它将不可避免地阻止"阻止"事件循环,因为JavaScript代码总是在一个线程上执行,无论如何。
没有。处理某些日志数据并将其发送到文件或流所需的时间非常少,并且对性能没有显着影响。
你可以做一些通常被称为"同步"的事情来伤害你的应用程序。 I / O操作 - 即写入文件,实际上没有执行任何其他JavaScript代码,直到写完成。执行此操作时,将所有数据交给底层本机代码,理论上可以继续在JS空间中执行其他工作,您有意决定等到本机代码以结果回复您。 这将"阻止"你的事件循环,因为这些I / O操作比执行常规代码要花费更长的时间(磁盘/网络往往是计算机中最慢的部分)。
stdout
/ stderr
。来自Node.js'文档:
process.stdout和process.stder与其他Node.js流的重要区别在于:
- 它们分别由console.log()和console.error()内部使用。
- 他们无法关闭(end()会抛出)。
- 他们永远不会完成'完成'事件
- 写入可能是同步的,具体取决于流的连接方式以及系统是Windows还是POSIX:
醇>
- 文件:Windows和POSIX上的同步
- TTY(终端):在Windows上异步,在POSIX上同步
- 管道(和套接字):在Windows上同步,在POSIX上是异步的
我假设我们正在使用下面的POSIX系统。
在实践中,这意味着当你的Node.js'输出流不是管道输入,而是直接发送到TTY,向控制台写入内容将阻止事件循环,直到将整个数据块发送到屏幕。但是,如果我们将输出流重定向到其他东西(进程,文件等),那么当我们向控制台Node.js写入内容时,它将不会等待操作完成并继续执行其他JavaScript代码它将数据写入该输出流。
在实践中,我们可以在同一时间段执行更多JavaScript 。
有了这些信息,您现在应该能够自己回答所有问题:
stdout
/ stderr
,或者如果不这样做,则只能重定向其中一个流写任何东西到另一个。无论如何,您可以重定向它们,但如果您不使用它们,您将无法获得任何性能优势。如果您对此应用程序的性能非常,请不要使用Winston或Bunyan进行日志记录 - 它们非常慢。请改用pino - 请参阅自述文件中的基准。
答案 1 :(得分:0)
要回答(1)我们可以深入了解Express文档,您将看到指向Console的Node.js文档的链接,该文档链接到process I/O上的Node文档。它描述了process.stdout和process.stderr的行为:
process.stdout和process.stder与其他Node.js流的重要区别在于:
- 它们分别由console.log()和console.error()内部使用。
- 他们无法关闭(end()会抛出)。
- 他们永远不会发出'结束'事件。
- 写入可能是同步的,具体取决于流连接的内容以及系统是Windows还是POSIX:
醇>
- 文件:Windows和POSIX上的同步
- TTY(终端):在Windows上异步,在POSIX上同步
- 管道(和套接字):在Windows上同步,在POSIX上是异步的
有了这个,我们可以尝试了解node app 2>&1 | tee logFile
会发生什么:
tee
tee
写入终端和文件logFile。这里的重要部分是 stdout和stderr通过管道传输到进程,这意味着它应该是异步的。
关于(2)它将取决于你如何配置Bunyan或Winston:
Winston具有Transports的概念,它基本上允许您配置日志的位置。如果您想要异步日志,则应使用Console Transport以外的任何记录器。使用文件传输应该没问题,因为它应该为此创建一个文件流对象,这是异步的,并且不会阻止节点进程。
Bunyan有一个类似的配置选项:Streams。根据他们的文档,它可以接受任何流接口。只要你在这里避免使用process.stdout和process.stderr流就可以了。