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):