7

I would like to directly access to syslog messages from Python by reading /dev/log.

My (very limited) understanding is that the correct way is to read from there is to bind a datagram socket.

import socket

sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.bind('/dev/log')
sock.listen(1)
while True:
    data, addr = sock.recvfrom(1024)
    print(data)

Apparently /dev/log is in use:

Traceback (most recent call last):
  File "readlog.py", line 4, in <module>
    sock.bind('/dev/log')
OSError: [Errno 98] Address already in use

How should I read /dev/log from Python?


EDIT: per @Barmar's comment - only one process can access /dev/log so that part is clear, the device must be clean before reading from it. sudo lsof /dev/log does not show anything.

A answer in a Java thread around this subject mentioned that syslog should be shut down before. I also tried that, lsof | grep "/dev/log" was empty but I got the error nevertheless.
Isn't it possible to have several processes reading from /dev/log?

Community
  • 1
  • 1
WoJ
  • 27,165
  • 48
  • 180
  • 345
  • 1
    No, it's not possible for multiple processes to bind to the same socket, just like multiple processes can't bind to the same TCP or UDP port. – Barmar Nov 24 '16 at 13:48
  • 1
    You can have multiple processes reading from a socket, but they have to inherit it from the process that bound it. And they each get exclusive access to each datagram. – Barmar Nov 24 '16 at 13:50
  • Use `sudo lsof /dev/log` to see what process has it open. – Barmar Nov 24 '16 at 13:51
  • /dev/log already exists, so you need to remove it before you call bind() – nos Nov 24 '16 at 14:03
  • @Barmar: I updated my question with your comments – WoJ Nov 24 '16 at 14:11
  • @nos: isn't `/dev/log` supposed to be always present? It is not created when `syslog` reads from it (in other words, syslog (or rsyslog, or others)) can be disabled at boot and `dev/log` will be there anyway – WoJ Nov 24 '16 at 14:12
  • @WoJ At https://github.com/rsyslog/rsyslog/blob/1ab0d897a4f3518fc3eaf9192044eca2545c05dd/plugins/imuxsock/imuxsock.c#L483 is the code for rsyslog, it unlinks the socket by default – nos Nov 24 '16 at 15:27
  • @nos: OK understood, thanks. I will try that and post an answer if successful. – WoJ Nov 24 '16 at 15:37
  • On my embedded device the `/dev/log` is a symlink, so `lsof /dev/log` doesn't show anything. Doing a `lsof` on the original socket file on the other hand shows systemd is bound to it. – Andreas Mikael Bank Aug 08 '19 at 07:30

1 Answers1

0

There is a socket flag to set, in order to prevent this:

socket.SO_REUSEADDR

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

This flag tells the kernel to reuse a local socket in TIME_WAIT state, without waiting for its natural timeout to expire.

Ref: https://docs.python.org/3/library/socket.html

brunocrt
  • 720
  • 9
  • 11