omprog does not capture script output to file

I’ve got a problem where the omprog module of rsyslog doesn’t seem to be using the output parameter to capture the script’s output to file. What am I doing wrong?

My rsyslog server receives a dozen syslog messages per second from an external host, and i want a certain task to occur when any message meets a particular criteria. So, I wrote a Python script that scans for the particular criteria on stdin and performs the task. (This task fires about once every couple hours.) For all other messages, the Python script discards the message and continues listening. The Python script runs infinitely while the pipe is open. This much works perfectly.

Then, I added a few confirmation messages into the Python script so that it will output a "started" message to stdout when it launches, and output a "done" message to stdout when the task happens. I set omprog‘s confirmMessages parameter to off, and the output parameter to a file within /var/log. The output of getenforce tells me that SELinux is off. When I restart rsyslog, the file is never created, and the output is never captured.

So, I touched the file as the syslog user, and restarted rsyslog, but that doesn’t fix it. Doing a systemctl status rsyslog shows that the Python script is running. And I can confirm that the particular is getting executed when the script sees the particular message.

Running the Python script manually does produce output and sits there infinitely until I press Ctrl+D.

I also configured the Python script output to stderr instead of stdout just to see if that made a difference. After restarting rsyslog, there was still no output file.

System: Ubuntu 20.04.2 LTS

rsyslogd: version 8.2001.0

rsyslog config:

if $fromhost-ip == ''     then {

The /var/log/network file is building. The /var/log/watch_vpn_attach.log file is not building.

Does anyone know what I am doing wrong?

Asked By: user3629081


This is probably just a problem of buffering in the Python program. A simple solution is to make sure you add flush=True in the print statements, eg:

import sys,time
for data in sys.stdin:
    print(f"got data at {time.asctime()}: {data}",flush=True)
Answered By: meuh
Categories: Answers Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.