Rsyslog omprog模块与Python2.7交互异常:无法接收stdin数据求助
Rsyslog omprog模块无法向Python 2.7脚本传递STDIN数据?
我之前也遇到过类似的问题,咱们一步步来排查和解决:
问题根源分析
首先,你的shell脚本用cat /dev/stdin >> /var/log/ssh2.log能正常工作,是因为cat会持续监听stdin直到进程终止;但用var="$(</dev/stdin)"或var="$(cat /dev/stdin)"时,这两个命令会一次性读取所有输入直到EOF,而rsyslog的omprog模块是持续运行的进程,不会主动发送EOF,所以脚本读完一次输入后就退出了,后续消息无法传递,导致变量为空。
对于Python脚本,有几个明显的问题:
- 你在
while True循环内部调用了f.close(),第一次循环结束后文件就被关闭了,后续的写入操作必然失败; - 默认情况下Python的stdin是行缓冲的,如果rsyslog发送的消息没有换行符,
for line in sys.stdin会一直阻塞等待换行,导致无法读取到内容; - 错误
errno 11(资源不可用)通常是非阻塞IO下的提示,说明你的脚本可能在尝试读取无数据的stdin时触发了非阻塞状态。
解决方案
1. 修正Rsyslog配置
确保模板包含换行符,让每条消息以换行结尾,同时添加omprog的关键参数保障消息传递:
module(load="omprog") template(name="sshmsg" type="string" string="%msg%\n") # 添加\n换行符,适配行缓冲读取 if ($programname == "myprogram") then { action( type="omprog" binary="/usr/sshtrack.py" template="sshmsg" confirmMessages="on" # 启用消息确认,确保rsyslog等待脚本处理完成 resumeRetryCount="-1" # 脚本异常退出时无限重试 ) }
2. 重写Python脚本
修复文件操作逻辑,调整stdin读取方式并关闭缓冲:
#!/usr/bin/python import sys import os # 将stdin设置为无缓冲模式,确保实时读取rsyslog发送的消息 sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', 0) # 用with语句管理文件,避免手动关闭出错 with open("/var/log/ssh2.log", "a") as f: f.write("Script started successfully\n") f.flush() # 立即写入磁盘,避免缓冲延迟 while True: line = sys.stdin.readline() if not line: # stdin被关闭时退出循环 break msg = line.strip() if msg: f.write(f"{msg}\n") f.flush() # 实时写入日志
3. 权限检查
确保脚本和日志文件的权限符合rsyslog运行要求:
- 给Python脚本添加执行权限:
chmod +x /usr/sshtrack.py - 将脚本和日志文件的所有者改为rsyslog运行用户(通常是
syslog):chown syslog:syslog /usr/sshtrack.py /var/log/ssh2.log
4. 手动测试脚本
先确认脚本本身能正常读取stdin:
echo "test message from stdin" | /usr/sshtrack.py
查看/var/log/ssh2.log是否有写入内容,确认脚本逻辑没问题后,重启rsyslog服务:
service rsyslog restart
这样调整后,omprog应该能稳定地将消息传递给Python脚本了。
内容的提问来源于stack exchange,提问作者Minregx
相关产品推荐
相关产品推荐

