【发布时间】:2019-12-02 19:07:46
【问题描述】:
我有多个客户端需要实时发送由 logmessage() bash 函数填充的日志 (/tmp/action.log)(我在 initrd 中)。如果需要,可以修改 logmessage 以对本地套接字执行 Socat。 在服务器端,当一个新的客户端打开一个连接时,它会发送它的 MAC 地址,然后它会时不时地发送线路。 我要避免的是每次向客户端发送消息时都会有一个新进程。 我需要服务器和客户端之间的连接保持活动状态,直到客户端 Socat 被杀死或服务器分叉脚本存在。 我需要多个客户端可以同时发送他们的日志
据我了解,在服务器上,这可以通过以下方式完成:
#!/bin/bash
# Function run per single client.
function process_log() {
read MAC
while read MSG
do
case "$MSG" in
reset)
/bin/rm -f /tmp/test_$MAC.log
;;
endlog)
exit 0;
;;
*)
echo "$MSG" >> /tmp/test_$MAC.log
;;
esac
done
}
export -f process_log
socat -vv TCP-LISTEN:8182,crlf,reuseaddr,fork SYSTEM:"/bin/bash -c 'process_log'"
我的问题是每次我发送消息时连接都会被清除,因此服务器 Socat 会为每一行生成一个新的 bash,这很丑陋并且会占用大量 PID。
我尝试了以下方法来在客户端和服务器之间建立一个稳定的持久套接字:
在客户端,我初始化一个本地 Socat 服务器(一次):
socat UNIX-LISTEN:/tmp/logger.socket,ignoreeof TCP-CONNECT:$SERVER_IP:8182&
echo $! > /tmp/socat.pid
test -S /tmp/logger.socket && socat - UNIX-CONNECT:/tmp/logger.socket <<EOF
$CLIENT_MAC
reset
EOF
我的 logmessage() 确实(多次)(除了填充 /tmp/action.log 和其他控制台内容):
test -S /tmp/logger.socket && socat - UNIX-CONNECT:/tmp/logger.socket <<EOF
$MAC
$*
EOF
在我上面的 logmessage() 中,我必须每次重新发送 MAC 地址,因为每次通话都会关闭连接。 (在我发送 endlog 关键字之前,如果客户端和服务器之间的连接保持活动状态,则应该没有必要)
所以 2 个解决方案:
- 要么在发送 MAC 地址后将日志文件尾部 -f 发送到服务器(但我必须在服务器端处理行以转换为 xml(从而吃掉 PID)
- 或者我可以让 semdmessage() 函数将数据(转换为 xml)发送到保持打开状态的东西。
不幸的是,我没有足够的技能来理解如何以有效的方式使用 Socat,并且无法在网络上找到(确定)类似问题的解决方案)。
【问题讨论】:
标签: bash logging parallel-processing socat