如何重定向进程文件写入的输出?
How can I redirect the output of a process file write?
我有一个遗留应用程序 运行 将其输出发送到日志文件。我不想跟踪和管理这些日志文件,而是想在输出到达磁盘之前捕获输出并将其发送到网络上的其他地方(使用 syslog、fluentd 或 logstash 等)。
有什么方法可以在不更改应用程序代码本身的情况下捕获输出?我确实可以选择更改进程启动,所以我可以 "wrap" 它。
我想到了几个选项:
- 命名管道 - 它可以工作,但受管道缓冲区和破损管道限制。
- 标准重定向 - 实际上仅适用于已知文件描述符,即 stdin、stdout、stderr / 0,1,2
是否有任何明智的方法来插入我的程序,以便应用程序认为它仍在写入 /var/log/myapp.log,而是发送到我的日志控制器,然后它可以按照它的意愿进行操作?
在 linux 上,您可以为您的进程创建一个 chroot
环境。所有文件访问现在都在您给定的根路径的本地,这使您可以准备 pipes/fifos 到要替换的所有文件。这可能需要一段时间才能获得整个环境 运行ning,但它可以在完全受控的环境中 运行 该过程。
使用命名管道。
管道缓冲区大小不是您需要担心的事情,如果 reader 端没有死(或提前关闭连接),您不应该得到 SIGPIPES。
您的 reader 可以像
一样简单
<named_pipe nc some_address some_port &
如果你在你的作者正在写它的时候杀了它,作者会得到一个 SIGPIPE。
至于缓冲区大小问题,只要 nc
ing 到 some_address someport
比数据写入命名管道的速率更快或一样快,写入进程就赢了'被阻止。如果编写器速度更快,它将在缓冲区填满时执行。 (但是,写入磁盘或网络也会让您受阻)。
您不必担心系统确定的管道缓冲区大小;只需修改管道 reader 端的缓冲(例如,您可以设置 nc 的 TCP 输出缓冲区大小,这与增加管道缓冲区大小具有相同的效果)如果管道缓冲区大小太小你.
如果您从 bash 启动程序并且您的应用程序将日志文件作为参数,您可以简单地给它 >( nc some_address some_port)
,这将为您创建一个匿名命名管道。
正如 PSkocik 所说,您可以尝试使用 'nc' 立即发送日志,但请记住 'nc' 在收到 EOF 字符时自行停止。您可以尝试使用 tail 跟踪日志并将其发送到远程主机
tail -f named-pipe-log-file|nc remote-host port
在远程主机上,'nc' 运行 处于侦听模式,使用 'nc -lkd port > log'
写入本地日志
我有一个遗留应用程序 运行 将其输出发送到日志文件。我不想跟踪和管理这些日志文件,而是想在输出到达磁盘之前捕获输出并将其发送到网络上的其他地方(使用 syslog、fluentd 或 logstash 等)。
有什么方法可以在不更改应用程序代码本身的情况下捕获输出?我确实可以选择更改进程启动,所以我可以 "wrap" 它。
我想到了几个选项:
- 命名管道 - 它可以工作,但受管道缓冲区和破损管道限制。
- 标准重定向 - 实际上仅适用于已知文件描述符,即 stdin、stdout、stderr / 0,1,2
是否有任何明智的方法来插入我的程序,以便应用程序认为它仍在写入 /var/log/myapp.log,而是发送到我的日志控制器,然后它可以按照它的意愿进行操作?
在 linux 上,您可以为您的进程创建一个 chroot
环境。所有文件访问现在都在您给定的根路径的本地,这使您可以准备 pipes/fifos 到要替换的所有文件。这可能需要一段时间才能获得整个环境 运行ning,但它可以在完全受控的环境中 运行 该过程。
使用命名管道。 管道缓冲区大小不是您需要担心的事情,如果 reader 端没有死(或提前关闭连接),您不应该得到 SIGPIPES。
您的 reader 可以像
一样简单<named_pipe nc some_address some_port &
如果你在你的作者正在写它的时候杀了它,作者会得到一个 SIGPIPE。
至于缓冲区大小问题,只要 nc
ing 到 some_address someport
比数据写入命名管道的速率更快或一样快,写入进程就赢了'被阻止。如果编写器速度更快,它将在缓冲区填满时执行。 (但是,写入磁盘或网络也会让您受阻)。
您不必担心系统确定的管道缓冲区大小;只需修改管道 reader 端的缓冲(例如,您可以设置 nc 的 TCP 输出缓冲区大小,这与增加管道缓冲区大小具有相同的效果)如果管道缓冲区大小太小你.
如果您从 bash 启动程序并且您的应用程序将日志文件作为参数,您可以简单地给它 >( nc some_address some_port)
,这将为您创建一个匿名命名管道。
正如 PSkocik 所说,您可以尝试使用 'nc' 立即发送日志,但请记住 'nc' 在收到 EOF 字符时自行停止。您可以尝试使用 tail 跟踪日志并将其发送到远程主机
tail -f named-pipe-log-file|nc remote-host port
在远程主机上,'nc' 运行 处于侦听模式,使用 'nc -lkd port > log'