Knowledge base

Accounting as a contract with the consumer

The field set is a promise, not an eyeballed setting

The task. Any fleet node. The accounting stream must carry what the Hub receiver parses, survive an engine crash and not become the largest store of personal data in the fleet.

What it is made of:

  • records — record types, including tq for proxy failures;
  • record-fields — the fields the receiver expects;
  • iso-times — the timestamp format the parsing is designed for;
  • sync — buffer flushing, so a crash does not take the last records with it;
  • user-string — an origin marker in every record, together with the userString field.

The parts have different scopes. All five live in one <acct-file> block.

How they interact. Three of the five are silent on error: an unnamed field is simply absent, a string without the userString field gives nothing, and a disabled sync gives complete data until the one time it does not. That is why all five are worth naming explicitly.

The main trap is user-string without the field. The line sets the text, but it gets into the record only if userString is listed in record-fields: without the field, the node marker is silently not written.
What the Hub does. It applies this partially. The accounting stream for the webhook is built for the Hub’s parsing: types d, b, rb, t and complaints; for deliveries and bounces timeFirstAttempt, totalSecondsQueued and numRetries are added to the star, for complaints the Feedback-ID header. The other parts are missing: there are no tq records in the stream, the time format is not named — the ISO default applies, buffer flushing and the origin marker are not set — the Hub recognizes the node by the webhook address.
Recommended values

Five lines:

Line Default What to set
records d,b all types the receiver parses
record-fields * — the default fields the star plus the needed fields outside it
iso-times yes yes, named explicitly
sync false true on nodes without backups
user-string none the node name and userString in the fields
The lines and defaults come from the manual (§ 3.3.11.7–3.3.11.8, § 3.3.11.11–3.3.11.12, § 3.3.11.15). The scheme itself is our hypothesis.
Example configuration
<acct-file /var/log/pmta/acct.csv>
    records d, b, rb, t
    record-fields d *, userString, timeFirstAttempt, numRetries
    iso-times yes
    sync true    user-string node-7
</acct-file>
userString is added to the star, otherwise the user-string line gives nothing.
yellow — — directive names, blue — blocks. They are highlighted the same way in the text of the card.
Compatibility
PowerMTA 6.0
described in the manual of this version · platform: any
The vendor does not state the first version for every directive — there is no note here. The name also appears in the 5.0 edition of the manual.
How to check on the node
Look at the accounting block on the node:
grep -n -A12 '<acct-file' /etc/pmta/config
No sync — false applies; no userString in the fields — the node marker is not written.