【问题标题】:Rsyslog, omprog, and pythonRsyslog、omprog 和 python
【发布时间】:2020-05-03 01:13:47
【问题描述】:

我在尝试让 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,除了添加一个非阻塞标志没有任何作用。

【问题讨论】:

    标签: python-2.7 stdin rsyslog


    【解决方案1】:

    我注意到您的模板sshmsg 没有以换行符结尾。尝试将其更改为 string="%msg%\n"。尽管 rsyslog 无关紧要,但 Python 在看到换行符之前无法为您提供数据。

    那么它应该可以工作了,但是你可能看不到任何来自你的 python 的输出,因为它被缓冲了。尝试在循环中的最后一次写入之后添加f.flush(),或者打开无缓冲的文件。

    omprog 将保持管道打开,发送多行直到您的程序退出。

    注意,并不是所有的 shell 都能理解 $() 语法。

    【讨论】:

    • 尝试使用无缓冲选项刷新和打开文件。标准输入似乎仍然是空的。有关更改,请参见 sshtrack.py。我可以在文件中看到“开始”行,但从 Stdin 看不到任何内容。
    • 我刚刚注意到您的模板sshmsg 没有以换行符结尾。尝试将其更改为string="%msg%\n"。尽管 rsyslog 无关紧要,但 python 在看到换行符之前无法为您提供数据。 (此外,如果您删除了无缓冲选项,请将刷新放在 write("\n") 之后)。
    【解决方案2】:

    如果是您的 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):https://stackoverflow.com/a/45263101/13108341

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      • 2015-11-12
      • 1970-01-01
      • 2016-08-10
      • 1970-01-01
      • 2011-12-02
      相关资源
      最近更新 更多