ansible role for debian buster setting up a mailserver with postfix, rspamd, dovecot and clamav and based on PostgreSQL; journal-postfix is a log parser for postfix; Attention: user and domain administration (in PostgreSQL) is not covered here
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3.8 KiB

Parse postfix entries in systemd journal and collect delivery information.

The information on mail deliveries is written to tables in a PostgreSQL database. The database can then be queried by a UI showing delivery status to end users. The UI is not part of this package.

This software is tailor-made for debian buster with systemd as init system. It is meant to run on the same system on which Postfix is running, or on a system receiving the log stream of a Postfix instance in its systemd journal.

Prerequisites / Postfix configuration:

  • Access to a PostgreSQL database.
  • Postfix: Only virtual mailboxes are supported.
  • Postfix: You can use short or long queue_ids (see, but since the uniqueness of short queue_ids is very limited, usage of long queue_ids is strongly recommended.


  • apt install python3-psycopg2 python3-systemd python3-yaml
  • Edit /etc/journal-postfix/main.yml
  • Output is written to the journal (unit journal-postfix). READ IT!

Side effects (database):

  • The configured database user will create the tables
    • delivery_from
    • delivery_to
    • noqueue in the configured database, if they do not yet exist. These tables will be filled with results from parsing the journal. Table noqueue contains deliveries rejected by smtpd before they got a queue_id. Deliveries with queue_id are in tables delivery_from and delivery_to, which are separate, because an email can have only one sender, but more than one recipient. Entries in both tables are related through the queue_id and the approximate date; note that short queue_ids are not unique for a delivery transaction, so consider changing your Postfix configuration to long queue_ids.
  • Log output is written to journald, unit journal-postfix.


  • Edit the config file in YAML format located at /etc/journal-postfix/main.conf


  • The log output of Postfix may contain messages not primarily relevant for delivery, namely messages of levels panic, fatal, error, warning. They are discarded.
  • The postfix server must be configured to use virtual mailboxes; deliveries to local mailboxes are ignored.
  • Parsing is specific to a Postfix version and only version 3.4.5 (the version in Debian buster) is supported; it is intended to support Postfix versions in future stable Debian releases.
  • This script does not support concurrency; we assume that there is only one process writing to the database tables. Thus clustered postfix setups are not supported.


  • If you use dovecot as lmtpd, you will also get dovecot_ids upon successful delivery.
  • If you have configured Postfix to store VERP-ids of outgoing mails in table ‘mail_from’ in the same database, then bounce emails can be associated with original emails. The VERP-ids must have a certain format.
  • The subject of emails will be extracted from log messages starting with “info: header Subject:". To enable these messages configure Postfix like this: Enabled header_checks in ( header_checks = regexp:/etc/postfix/header_checks ) and put this line into /etc/postfix/header_checks: /^Subject:/ INFO
  • You can also import log messages from a log file in syslog format: Run this script directly from command line with options --file (the path to the file to be parsed) and --year (the year of the first message in this log file). Note: For the name of the month to be recognized correctly, the script must be run with this locale. Attention: When running from the command line, log output will not be sent to unit journal-postfix; use this command instead: journalctl --follow SYSLOG_IDENTIFIER=python3