Rsyslog、omprog 和 python
Rsyslog, omprog, and python
我在尝试让 Rsyslog 的 'omprog' 模块与我的 python (2.7) 代码交互时遇到问题。 Rsyslog 应该将所需的消息发送到 python 的标准输入,但它没有收到任何东西。我想知道是否还有其他人使用此输出模块取得了更好的成功?
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")
}
如果我用包含下面一行的测试 shell 脚本替换二进制文件,它就可以工作
test.sh
!#/bin/sh
cat /dev/stdin >> /var/log/ssh2.log
我还尝试使用
将 shell 脚本中的标准输入读入变量
var="$(</dev/stdin)"
和
var="$(cat /dev/stdin)"
以上都没有导致 var 包含任何东西
最后,当尝试从 python 脚本读取标准输入时,我什么也没得到。有时,它说资源不可用 (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()
这个问题似乎与 can not read correctly from STDIN 类似,只是添加了一个非阻塞标志没有任何作用。
我注意到您的模板 sshmsg
没有以换行符结尾。尝试将其更改为 string="%msg%\n"。虽然这对 rsyslog 无关紧要,但 Python 在看到换行符之前无法为您提供数据。
那么它应该可以工作,但是您可能看不到 python 的任何输出,因为它已被缓冲。尝试在循环中最后一次写入 f.flush()
之后添加一个 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()
如果您想获得执行脚本(调试)的输出,您可以使用 output
选项调整 Rsyslog.conf 中的设置
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")
}
参考 (1):
我在尝试让 Rsyslog 的 'omprog' 模块与我的 python (2.7) 代码交互时遇到问题。 Rsyslog 应该将所需的消息发送到 python 的标准输入,但它没有收到任何东西。我想知道是否还有其他人使用此输出模块取得了更好的成功?
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")
}
如果我用包含下面一行的测试 shell 脚本替换二进制文件,它就可以工作
test.sh
!#/bin/sh
cat /dev/stdin >> /var/log/ssh2.log
我还尝试使用
将 shell 脚本中的标准输入读入变量var="$(</dev/stdin)"
和
var="$(cat /dev/stdin)"
以上都没有导致 var 包含任何东西
最后,当尝试从 python 脚本读取标准输入时,我什么也没得到。有时,它说资源不可用 (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()
这个问题似乎与 can not read correctly from STDIN 类似,只是添加了一个非阻塞标志没有任何作用。
我注意到您的模板 sshmsg
没有以换行符结尾。尝试将其更改为 string="%msg%\n"。虽然这对 rsyslog 无关紧要,但 Python 在看到换行符之前无法为您提供数据。
那么它应该可以工作,但是您可能看不到 python 的任何输出,因为它已被缓冲。尝试在循环中最后一次写入 f.flush()
之后添加一个 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()
如果您想获得执行脚本(调试)的输出,您可以使用 output
选项调整 Rsyslog.conf 中的设置
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")
}
参考 (1):