【问题标题】:How can I redirect the output of a process file write?如何重定向进程文件写入的输出?
【发布时间】:2015-05-15 16:01:07
【问题描述】:

我有一个正在运行的旧版应用程序,它将其输出发送到日志文件。我不想跟踪和管理这些日志文件,而是想在输出到达磁盘之前捕获输出并将其发送到网络上的其他地方(使用 syslog、fluentd 或 logstash 等)。

有什么方法可以在不更改应用程序代码本身的情况下捕获输出?我确实可以选择更改进程启动,所以我可以“包装”它。

我想到了几个选项:

  • 命名管道 - 可以工作,但会受到管道缓冲区和损坏管道的限制。
  • 标准重定向 - 实际上只适用于已知文件描述符,即 stdin、stdout、stderr / 0,1,2

是否有任何理智的方法可以插入我的程序,以便应用程序认为它仍在写入 /var/log/myapp.log 而是被发送到我的日志控制器,然后它可以按照它的意愿进行操作?

【问题讨论】:

  • “管道缓冲区和损坏的管道限制” - 我看不出有任何问题。你能详细说明一下吗?
  • @KarolyHorvath 你不关心吗?想象一个系统每秒输出数千条日志消息。对于基于磁盘的日志文件,它会导致大量磁盘 i/o 和空间使用。如果我可以捕获它并立即将其发送到主机之外,我可以解决这两个问题。但是每秒数千条消息会淹没 /dev/log 或任何其他管道,不是吗?
  • 不应该。如果有疑问,请测试它。注意:它是一个管道,而不是一个基于磁盘的 文件。
  • 当然是这个意思!
  • 如果磁盘跟不上记录器,那么网络也永远无法跟上。

标签: linux io file-descriptor


【解决方案1】:

使用命名管道。 管道缓冲区大小不是您需要担心的问题,如果阅读器端没有死(或提前关闭连接),您不应该获得 SIGPIPES。

您的阅读器可以像

<named_pipe nc some_address some_port &

如果你在作者写信的时候杀死它,作者会得到一个 SIGPIPE。

至于缓冲区大小问题,只要ncing 到some_address someport 更快或与将数据写入命名管道的速率一样快,写入进程就不会被阻塞。如果写入器速度更快,则在缓冲区填满时它会更快。 (但是,写入磁盘或网络也会让你被阻止)。

您不必担心系统确定的管道缓冲区大小;如果管道缓冲区大小对您来说太小,只需修改管道读取器端的缓冲(例如,您可以设置 nc 的 TCP 输出缓冲区大小,这将具有与增加管道缓冲区大小相同的效果)。

如果您从 bash 启动程序并且您的应用将日志文件作为参数,您可以简单地给它&gt;( nc some_address some_port),这将为您创建一个匿名命名管道。

【讨论】:

  • 哦。喜欢。我需要检查日志文件是否被硬编码。但如果没有,那么最好的办法就是在参数中使用它。这也适用于环境变量吗?
  • 匿名命名管道只对当前管道开放 foo=&gt;(cat) echo hi &gt; $foo 理论上可以工作,但实际上不行;如果您通过环境传递参数,则需要使用真实命名的 fifos。
【解决方案2】:

在 linux 上,您可以为您的进程创建一个chroot 环境。所有文件访问现在都在给定根路径的本地,这使您能够为要替换的所有文件准备管道/fifos。这可能需要一段时间才能让整个环境运行,但它可以在完全受控的环境中运行进程。

【讨论】:

    【解决方案3】:

    正如 PSkocik 所说,您可以尝试使用“nc”立即发送日志,但请记住,“nc”在收到 EOF 字符时会自行停止。您可以尝试使用 tail 跟踪日志并将其发送到远程主机

    tail -f named-pipe-log-file|nc remote-host port
    

    在远程主机上,让“nc”在监听模式下运行,使用'nc -lkd port &gt; log'写入本地日志

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-04
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 2016-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多