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

Node.js管道控制台错误到另一个程序(使其异步),node.js,asynchronous,logging,Node.js,Asynchronous,Logging,来自Expressjs: 要保持应用程序完全异步,您仍然需要管道 将console.err()复制到另一个程序 问题: 运行带有stdout和stderr重定向到而不阻止事件循环的节点应用程序是否足够?像这样:节点应用程序2>&1 | tee日志文件 如果ad.1的答案是正确的,那么如何在使用Winston或Bunyan时实现无阻塞日志记录?他们有一些内置机制来实现这一点,或者他们只是将数据保存到特定文件浪费当前Node.js进程的cpu时间?或者,为了实现真正的异步日志记录,他们应该将数据管道

来自Expressjs:

要保持应用程序完全异步,您仍然需要管道 将console.err()复制到另一个程序

问题:

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

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

  • 为了回答(1),我们可以深入阅读Express文档,您将看到指向Console的Node.js文档的链接,该链接指向控制台上的Node文档。其中描述了process.stdout和process.stderr的行为方式:

    process.stdout和process.stderr与其他Node.js流的重要区别在于:

  • 它们分别由console.log()和console.error()在内部使用
  • 它们无法关闭(end()将抛出)
  • 它们永远不会发出“完成”事件
  • 写入可能是同步的,具体取决于流所连接的对象以及系统是Windows还是POSIX:
    • 文件:在Windows和POSIX上同步
    • TTYs(终端):在Windows上异步,在POSIX上同步
    • 管道(和套接字):在Windows上同步,在POSIX上异步
  • 有了这些,我们可以尝试了解节点应用程序2>和1的日志文件将发生什么:

    • Stdout和stderr通过管道连接到进程
      tee
    • tee
      写入终端和文件日志文件
    这里的重要部分是,stdout和stderr通过管道传输到进程,这意味着它应该是异步的

    关于(2),这取决于您如何配置班扬或温斯顿:

    • Winston有传输的概念,它本质上允许您配置日志的去向。如果需要异步日志,则应使用除。使用文件传输应该是可以的,因为它应该为这个和那个创建一个异步的文件流对象,并且不会阻塞节点进程

    • 班扬有一个类似的配置选项:。根据他们的文档,它可以接受任何流接口。只要您避免在这里使用process.stdout和process.stderr流,就应该可以了


    让我们先设置一些地面

    写入终端屏幕(
    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.stderr与其他Node.js流的重要区别在于:

  • 它们分别由console.log()和console.error()在内部使用
  • 它们无法关闭(end()将抛出)
  • 它们永远不会发出“完成”事件
  • 写入可能是同步的,具体取决于流所连接的对象以及系统是Windows还是POSIX:
    • 文件:在Windows和POSIX上同步
    • TTYs(终端):在Windows上异步,在POSIX上同步
    • 管道(和插座)