85.1.41. pepsi-status¶
summarise the health of the Pepsi mail pipeline
- Manual section:
1
85.1.41.1.1. Name¶
pepsi-status - print a human-readable health summary of the queue, stuck messages, delivery and failure statistics, and outbound TLS outcomes.
85.1.41.1.2. Synopsis¶
pepsi-status [GLOBAL-OPTIONS] [–json] [–limit N]
85.1.41.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 six sections:
- Queue
The current contents of the
pepsi.workqueuetable, broken down bystageandstatus, with the age of the oldest message in each bucket and a grand total. This is the live backlog:pendingandrunningrows are work in progress,pausedrows are waiting (for example for a payment deadline or a relay retry), andfailed/timeoutrows need attention.- Stuck messages
The individual messages whose status is
failedortimeout, oldest first. For each, the report shows theworkqueue_id, status, 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, or our own diagnostic, fromstate.bounce), the error text the stage recorded when it failed or deferred the message (state.last_error, shown aserror:), and the reason pepsi-dispatch gave when it failed or timed out the message itself — a crashed or hung worker, or an unconfigured stage (state.dispatch_error, shown asdispatch:). In –json output the three are thebounce,last_erroranddispatch_errorfields of eachproblemsentry. 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 the number of executions it counted (the MESSAGES column, which is the denominator of the average), the 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 TLS session outcomes over the last seven UTC report-days (today’s, in UTC, and the six before it, whatever the server’s time zone), grouped by policy domain and result type, with non-successful results marked. This data is only present when
[pepsi-tlsrpt] SEND_REPORTSis enabled, and only for as long aspepsi-tlsrpt prunekeeps it ([pepsi-tlsrpt] RETAIN_DAYS, also seven days by default), so a shorter retention shortens this section. The section then lists any MX-host addresses the resolver cache currently has marked as failing to connect, with the time of their last successful connection (ornever).- 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. A row exists for every account Pepsi has delivered to — that is what creates one — whether or not it has a quota, so on a deployment that does not use the feature the section still lists those accounts, with-in the LIMIT and FULL columns. It is empty, and says so, only when no local delivery has been accounted for.LIMIT is the limit actually in force, resolved exactly as the delivery path resolves it: the account’s own limit if it has one, otherwise the site default
[pepsi] MAILBOX_QUOTA, with an explicit0on the account meaning unlimited rather than inherit, and the kernel’s own quota tightening whichever won.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
RCPTrests on a measurement being fresh: an account showing “full” against a very old measurement is one pepsi-quota(1)reconcileshould be looking at.- Correspondent key changes
How many correspondents’ encryption keys the Autocrypt newest-wins rule replaced in the last 30 days (rotated), and how many such replacements
ACCEPT_ROTATION = expiredrefused (held), followed by the most recent of both — capped by –limit — with the date, the address, the protocol, the old and new fingerprints and whether the new key was the correspondent’s own (inbound) or introduced by a third party (gossip). A rotation is the one way a message that merely claims to come from a correspondent can change the key we encrypt to them with, which is why it is shown here rather than left in the audit log. The figures are read from thekey.peer.rotateandkey.peer.rotate.heldrows ofpepsi.event_log, which the database writes together with the change itself, so the section reaches back as far as[pepsi-admin] EVENT_RETENTIONkeeps them. See pepsi-stage-autocrypt-learn(1).
Free-form text in the human-readable report — a remote MTA’s reply, a message
subject, a host name from the resolver cache — has its control characters replaced
by spaces before it is printed. All of it is chosen by somebody else, and this tool
is meant to be run over SSH against a live deployment, which is precisely where a
terminal escape sequence would repaint the operator’s screen. The --json output
is unaffected: JSON escaping already covers it.
85.1.41.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,quota_default_bytes,key_change_days,key_changes_rotated,key_changes_heldandkey_changes) instead of the human-readable text, for scripting and monitoring.- –limit N
List at most N individual stuck (
failed/timeout) messages and at most *N* mailbox-quota accounts. Defaults to50. The reported total backlog is unaffected by this cap.The stuck-message section says “showing X of Y” when it is cut off; the mailbox-quota section does not, so on a host with more than N accounted accounts that list is silently the N with the oldest measurements — which is the useful end of it, but raise –limit before concluding an account is absent.
85.1.41.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.
85.1.41.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,debugortrace(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.
85.1.41.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.
85.1.41.1.8. Files¶
When –config is not given, the first existing file from the following list is used. Every Pepsi component shares the same configuration file, so this is the same list each one searches:
$XDG_CONFIG_HOME/pepsi.conf$HOME/.config/pepsi.conf/etc/pepsi/pepsi.conf/etc/pepsi.conf
85.1.41.1.9. 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
85.1.41.1.10. See Also¶
pepsi-queue(1), pepsi-tlsrpt(1), pepsi-quota(1), pepsi-dispatch(1), pepsi.conf(5), pepsi-setup(1)
85.1.41.1.11. Bugs¶
Report bugs to the Pepsi issue tracker.