当我试图让Rsyslog的'omprog'模块与我的python(2.7)代码交互时,我遇到了一个问题。Rsyslog应该向python的stdin发送所需的消息,但它没有收到任何东西。我想知道是否有人在使用这个输出模块时取得了更好的成功?
Rsyslog.conf
module(load="omprog")
template(name="sshmsg" type="string" string="%msg%")
if ($programname == "myprogram") then {
action(type="omprog"
binary="/usr/sshtrack.py"
template="sshmsg")
}
如果我将二进制文件替换为包含下面一行的测试脚本,它就能工作了
测试.sh
!#/bin/sh
cat /dev/stdin >> /var/log/ssh2.log
我还试着用以下方法把shell脚本中的stdin读到一个变量中去
var="$(</dev/stdin)"
和
var="$(cat /dev/stdin)"
上述两种情况都没有导致 变种 含有
最后,当我试图从python脚本中读取stdin时,我什么也没得到。有时,它说资源不可用(errno 11)错误信息。
sshtrack.py
#!/usr/bin/python
import sys
f = open("/var/log/ssh2.log", "a", 0)
while True:
f.write("Starting\n")
for line in sys.stdin:
f.flush()
msg = line.strip()
if not msg:
break
f.write(msg)
f.write("\n")
f.close()
这个问题似乎与 无法正确读取STDIN 除了添加一个非块标志没有任何作用。
我注意到你的模板 sshmsg
不以换行结束。试着把它改成 string="%msg%/n"。尽管这对rsyslog来说并不重要,但Python在看到换行之前是不会给你数据的。
然后它应该可以工作,但你可能看不到任何python的输出,因为它是缓冲的。尝试添加一个 f.flush()
之后 循环中的最后一次写入,或者打开文件的非缓冲区。
omprog
将保持管道打开,发送多行,直到你的程序退出。
注意,不是所有的shell都能理解 $()
语法。
如果是shell脚本,你可以使用 read
来读入一个变量。
#!/bin/bash
# This will read until \n
read log
echo $log
python源代码(用python 3.8.2测试)可以调整为。
#!/usr/bin/env python3
import sys
# Changed from unbuffered to buffered as unbuffered is only possible in binary mode Ref (1):
f = open("/var/log/ssh2.log", "a", 1)
while True:
f.write("Starting\n")
for line in sys.stdin:
f.flush()
msg = line.strip()
if not msg:
break
f.write(msg)
f.write("\n")
f.close()
如果你想得到你执行的脚本的输出(调试),你可以通过调整在 Rsyslog.conf 随着 output
选择权
module(load="omprog")
template(name="sshmsg" type="string" string="%msg%")
if ($programname == "myprogram") then {
action(type="omprog"
binary="/usr/sshtrack.py"
output="/var/log/sshtrack.log"
template="sshmsg")
}