Comment se passer de systemd-journald quand on utilise rsyslog

Le jeudi 22 juin 2023 par Benjamin Boudoir

Bookworm est sorti la semaine dernière et parmis les changements important : rsyslog n'est plus installé par défaut.

L'argument étant que systemd-journald dupliquait déjà les journaux, donc autant supprimer rsyslog. Pour tout un tas de raison, si vous avez besoin de rsyslog, il est possible de l'installer. Cependant il est à noter qu'en faisant de la sorte (et c'est le cas dans Debian depuis le passage à systemd), rsyslog récupère ses journaux depuis systemd-journald, qui a pris le contrôle de /dev/log. Hors, lorsque vous passer par systemd-journald pour récupérer vos journaux dans rsyslog, vous avez deux possibilités :

  • Le module imuxsock: rapide, mais, parfois, systemd-journald décidera de ne pas transférer toutes les entrées
  • Le module imjournal: qui récupère toutes les entrées, mais est lent

C'est dans la doc.

Vous ne voulez donc pas utiliser rsyslog ET systemd-journald.

Donc comment se passer complètement de systemd-jounald ?

En cherchant sur le net, vous verrez essentiellement des gens modifier la configuration de systemd-journald pour le faire passer en stockage volatile, mais ça ne règle pas le problème de performance. La solution est pourtant assez simple et se trouve dans deux fichiers :

  • /lib/systemd/system/systemd-journald-dev-log.socket
  • /lib/systemd/system/syslog.socket

Tout ce qu'il y a a faire, c'est modifier syslog.socket pour le faire écouter sur /dev/log plutôt que /run/systemd/journal/dev-log (directive ListenDatagram) et modifier systemd-journald-dev-log.socket pour ne pas écraser /dev/log (directive Symlinks que vous pouvez remplacer par ce que vous voulez).

Ensuite, vous rechargez systemd, vous pouvez stoper systemd-journald et relancer rsyslog.

Et si vous avez besoin de l'automatiser, voici à quoi ça ressemble avec ansible :

- name: Stop using systemd-journald
  lineinfile:
      regexp: '^(Symlinks=/dev/log).*'
      backrefs: yes
      line: '\1_systemd'
      dest: /lib/systemd/system/systemd-journald-dev-log.socket
  notify:
    - reload systemd
    - stop journald

- name: Use rsyslog instead
  lineinfile:
      regexp: '^(ListenDatagram)=.*'
      backrefs: yes
      line: '\1=/dev/log'
      dest: /lib/systemd/system/syslog.socket
  notify:
    - reload systemd
    - restart rsyslog

Et les handlers :

- name: stop journald
  systemd:
    name: "{{ item }}"
    state: stopped
    enabled: false
    masked: true
  with_items:
    - systemd-journald.socket
    - systemd-journald-audit.socket
    - systemd-journald-dev-log.socket
    - systemd-journald

- name: reload systemd
  systemd:
    daemon_reload: true