70.1.32. pepsi-status

summarise the health of the Pepsi mail pipeline

Manual section:

1

70.1.32.1.1. Name

pepsi-status - print a human-readable health summary of the queue, stuck messages, delivery and failure statistics, and outbound TLS outcomes.

70.1.32.1.2. Synopsis

pepsi-status [GLOBAL-OPTIONS] [–json] [–limit N]

70.1.32.1.3. Description

pepsi-status prints a one-shot, read-only health report of the Pepsi pipeline, drawn entirely from the shared pepsi database. It is intended to be run interactively or over SSH (for example from a monitoring host); it never modifies a row and issues no database notification, so it is safe to run against a live deployment at any time.

The tool connects to the same database as the other components, through the shared [pepsi-postgres] section; it introduces no configuration of its own. When started as root it continues as the pepsi service account; see Running as root.

The report has five sections:

Queue

The current contents of the pepsi.ingress table, broken down by stage and status, with the age of the oldest message in each bucket and a grand total. This is the live backlog: pending and running rows are work in progress, paused rows are waiting (for example for a payment deadline or a relay retry), and failed/timeout rows need attention.

Stuck messages

The individual messages whose status is failed or timeout, oldest first. For each, the report shows the ingress_id, stage, age, envelope sender and subject, and — when a relay stage recorded one — the structured reason the next hop refused the message (remote MTA, SMTP code, enhanced status and reply text from state.bounce). The list is capped by –limit; the true backlog size is always shown.

Delivery & failures

Cumulative pipeline counters: the total number of messages that completed and left the pipeline, the total stage executions, and per-stage message counts, average processing time, worker timeouts and worker crashes. These are lifetime totals accumulated since the schema was created. Because a successfully delivered message is deleted from the queue, there is no per-message delivery log and therefore no rolling time window: the figures are cumulative, not “in the last hour”.

Outbound TLS

Outbound STARTTLS session outcomes for recent report-days, grouped by policy domain and result type, with non-successful results marked. This data is only present when [pepsi-tlsrpt] SEND_REPORTS is enabled (and is pruned once the daily reports are sent). The section also lists any MX-host addresses the resolver cache currently has marked as failing to connect, with the time of their last successful connection.

Mailbox quotas

One line per local account Pepsi has accounted for, oldest measurement first: usage, effective limit, how full it is, where the figure came from (fsquota/maildirsize/scan) and how long ago the mailbox was measured. Accounts with no quota anywhere never get a row, so the section is empty — and says so — on a deployment that does not use the feature.

Two columns repay a moment’s thought. USED is the last measurement plus everything delivered since; it only ever grows, because nothing tells Pepsi when a user deletes mail over IMAP, so it is an upper bound rather than a fact. MEASURED is how long ago somebody actually looked, and it matters because a refusal at RCPT rests on a measurement being fresh: an account showing “full” against a very old measurement is one pepsi-quota(1) reconcile should be looking at.

70.1.32.1.4. Options

–json

Emit the whole report as a single JSON object (keys queue, problem_total, problems, global, stages, tls_report_days, tls, dns_failures, mailboxes and quota_default_bytes) instead of the human-readable text, for scripting and monitoring.

–limit N

List at most N individual stuck (failed/timeout) messages. Defaults to 50. The reported total backlog is unaffected by this cap.

70.1.32.1.5. Running as root

Pepsi gives every component its own PostgreSQL role, authenticated over the local socket by the operating-system account it runs as, and root is deliberately not one of them. Rather than fail to connect and oblige you to remember sudo -u pepsi pepsi-status, the tool detects that it was started as root and becomes the unprivileged pepsi service account before it connects; the report itself stays strictly read-only.

The configuration file (and any @inline-secret@ fragment it references) is read before the switch, so a root-only configuration is still loaded normally.

If the pepsi account does not exist — an uninstalled source tree, a test rig — the identity is left untouched, a warning is logged, and the connection is attempted as the invoking user, so a setup in which root can reach the database keeps working.

70.1.32.1.6. Global Options

These options may appear before or after the other options.

-c FILE, –config FILE

Read the configuration from FILE instead of searching the default locations.

-L LOGLEVEL, –log LOGLEVEL

Set the logging verbosity. LOGLEVEL is one of error, warn, info, debug or trace (default: info).

-v, –verbose

Show log messages from all sources, including third-party libraries.

-h, –help

Print a usage summary and exit.

-V, –version

Print the version and exit.

70.1.32.1.7. Exit Status

0

Successful completion.

1

An error occurred: a malformed configuration file or a failed database connection or query. The reason is written to the log.

70.1.32.1.8. Examples

Print the full health report:

pepsi-status -c /etc/pepsi/pepsi.conf

Collect the report as JSON for a monitoring system over SSH:

ssh mail.example.com pepsi-status --json

Show up to 200 stuck messages:

pepsi-status -c /etc/pepsi/pepsi.conf --limit 200

70.1.32.1.9. See Also

pepsi-queue(1), pepsi-tlsrpt(1), pepsi-dispatch(1), pepsi.conf(5), pepsi-setup(1)

70.1.32.1.10. Bugs

Report bugs to the Pepsi issue tracker.