Node.js 管道控制台错误到另一个程序(使其异步)

fid*_*der 5 logging asynchronous node.js

从 Expressjs文档:

为了保持您的应用完全异步,您仍然希望通过管道将 console.err() 传递给另一个程序

问题:

  1. 使用 stdout 和 stderr 重定向运行我的节点应用程序是否足以不阻止事件循环?像这样:node app 2>&1 | tee logFile?
  2. 如果 ad.1 答案为真,那么如何在使用 Winston 或 Bunyan 时实现非阻塞日志记录?他们有一些内置的机制来实现这一点,或者他们只是将数据保存到特定文件,浪费当前 Node.js 进程的 CPU 时间?或者也许为了实现真正的异步日志记录,他们应该将数据通过管道传输到执行“保存到文件”的子进程(它仍然是性能积极的吗?)?如果我的思维方式是错误的,谁能解释或纠正我?

  3. 编辑部分:我可以假设从进程 A、B、...等到进程 L 的管道数据对于这个特定进程(A、B、...)比将其写入文件(或通过网络发送)更便宜。重点:我正在为使用 nodejs 集群的应用程序设计记录器。简而言之 - 进程 (L) 之一将处理来自其他进程 (A, B, ...) 的数据流。进程 L 将对消息进行排队(例如逐行或其他一些特殊分隔符)并将其一一记录到文件、数据库或其他任何地方。这种方法的优点是减少了可以花更多时间完成工作的流程负载。另一件事 - 假设是简化该库的使用,因此用户将仅包含此记录器,而无需通过 shell 进行任何额外的交互(流重定向)。 你认为这个解决方案有意义吗?也许你知道一个图书馆已经这样做了?

Rus*_*tos 0

为了回答(1),我们可以深入研究 Express 文档,您将看到 Console 的 Node.js 文档的链接,该链接指向有关进程I/O 的Node 文档。其中描述了 process.stdout 和 process.stderr 的行为方式:

process.stdout 和 process.stderr 与其他 Node.js 流有以下重要区别:

  1. 它们分别由 console.log() 和 console.error() 在内部使用。
  2. 它们无法关闭(end() 将抛出异常)。
  3. 他们永远不会发出“完成”事件。
  4. 写入可能是同步的,具体取决于流连接到的内容以及系统是 Windows 还是 POSIX:
    • 文件:在 Windows 和 POSIX 上同步
    • TTY(终端):在 Windows 上异步,在 POSIX 上同步
    • 管道(和套接字):在 Windows 上同步,在 POSIX 上异步

这样我们就可以尝试了解会发生什么node app 2>&1 | tee logFile:

  • Stdout 和 stderr 通过管道传输到进程tee
  • tee写入终端和文件 logFile。

这里重要的部分是stdout 和 stderr 通过管道传输到进程,这意味着它应该是异步的。

关于 (2),这取决于您如何配置 Bunyan 或 Winston:

  • Winston 有传输的概念,它本质上允许您配置日志的去向。如果您想要异步日志,您应该使用Console Transport以外的任何记录器。使用文件传输应该没问题,因为它应该为此创建一个文件流对象,并且该对象是异步的,并且不会阻塞节点进程。

  • Bunyan 有一个类似的配置选项:Streams。根据他们的文档,它可以接受任何流接口。只要您避免在此处使用 process.stdout 和 process.stderr 流,就应该没问题。