Search code examples
python-2.7stdinrsyslog

Rsyslog, omprog, and python


I have an issue with Rsyslog's 'omprog' module when trying to get it to interact with my python (2.7) code. Rsyslog is supposed to send desired messages to python's stdin, yet it does not receive anything. I wonder if anyone else has had better success with this output module?

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")
}

If I replace the binary with a test shell script containing a line below, it works

test.sh

!#/bin/sh

cat /dev/stdin >> /var/log/ssh2.log

I also tried reading stdin in the shell script into a variable using

var="$(</dev/stdin)"

and

var="$(cat /dev/stdin)"

Neither of the above resulted var containing anything

Finally, when trying to read stdin from python script, I get nothing. Sometimes, it says resource unavailable (errno 11) error message.

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

The issue seems similar to can not read correctly from STDIN except adding a non-block flag did nothing.


Solution

  • I notice that your template sshmsg doesn't end with a newline. Try changing it to string="%msg%\n". Though it won't matter to rsyslog, Python will not be able to give you the data until it sees a newline.

    Then it should work, but you probably not see any output from your python as it is buffered. Try adding an f.flush() after the last write in the loop, or opening the file unbuffered.

    omprog will keep the pipe open, sending multiple lines until your program exits.

    Note, not all shells might understand $() syntax.