Skip to content
axxbetadocs
GitHub

Logs

View .mdOpen in Claude

Assert the entries your services log, read from files or sent to Axx over UDP, TCP or HTTP.

A log is where a service’s log lines are: a file Axx reads, or an address Axx listens on while services send their lines to it. Register it with the {word} log with the following properties:, then assert the entries a scenario must produce. Only what the log received after the scenario registered it counts, and every step waits for its entries (10 seconds unless within {duration} says otherwise).

Use logs to prove that something did not happen: have the service log its decision (“line ML-KES-0413-1 rejected: duplicate reference”) and assert that entry, rather than waiting and hoping nothing arrives. Match on data unique to the scenario (a reference, an id): scenarios run in parallel and share the log.

The url says where the lines are:

url Axx
file:///var/log/app.log, file://logs/app.log reads what is appended to the file (relative to axx.yaml); file://.axx/logs/apps.log is the console of the apps Axx starts
udp://0.0.0.0:5140 listens; each datagram is one or more lines (e.g. Docker’s syslog log driver, an app’s syslog handler)
tcp://0.0.0.0:5150 listens; newline-delimited or octet-counted (RFC 6587) messages
http://0.0.0.0:5160/logs, https://... listens; the body of each POST or PUT to that path (e.g. a Fluent Bit or Vector http output). https uses a self-signed certificate

Axx opens listeners before it starts the apps, for the log steps of the scenarios in the run, so services can send from the start; axx up keeps them open between runs. Services in containers reach them at host.docker.internal.

Patterns are regular expressions (Java syntax), searched in the log’s text, not matched against whole lines: ^ and $ match at line boundaries, every match counts, and a pattern can span lines (\n, or (?s) to let . match newlines), which covers multi-line entries such as stack traces.

Given the {word} log with the following properties:
| ... | ... |

Register a log under a name. Properties: url (required; file://, udp://, tcp://, http:// or https://, ${env:..}/${sys:..} are expanded). Assertions only look at what the log receives from now on.

Parameters: {word} (one word, no spaces)

Example:

Given the parcels log with the following properties:
Then [[within {duration} ]]the {word} log has an entry matching {string}

Wait (10s, or the given time) until the log has a match for the regular expression. The pattern is searched in the log’s text: ^ and $ match at line boundaries and a pattern can span lines.

Variants (optional parts in [[...]] above):

  • the {word} log has an entry matching {string}
  • within {duration} the {word} log has an entry matching {string}

Parameters: {duration} (A duration in seconds or minutes, e.g. 5s or 2m), {word} (one word, no spaces), {string} (text in single or double quotes; the quotes are removed)

Example:

Then the parcels log has an entry matching 'registration refused reference=PX-EVT-4003'
Then within 30s the parcels log has an entry matching 'manifest line processed line=ML-MAP-0019-3 status=IMPORTED'
Then [[within {duration} ]]the {word} log has entries matching:
| ... | ... |

Wait until the log has a match for every regular expression in the table (one per row). Each row needs a match of its own: the same pattern in two rows needs two matches.

Variants (optional parts in [[...]] above):

  • the {word} log has entries matching:
  • within {duration} the {word} log has entries matching:

Parameters: {duration} (A duration in seconds or minutes, e.g. 5s or 2m), {word} (one word, no spaces)

Example:

Then the parcels log has entries matching:
Then [[within {duration} ]]the {word} log has {int} entry/entries matching {string}

Wait until the log has the given number of matches for the regular expression, for example one per retry. More matches than that fail the step.

Variants (optional parts in [[...]] above):

  • the {word} log has {int} entry/entries matching {string}
  • within {duration} the {word} log has {int} entry/entries matching {string}

Parameters: {duration} (A duration in seconds or minutes, e.g. 5s or 2m), {word} (one word, no spaces), {int} (a 32-bit integer), {string} (text in single or double quotes; the quotes are removed)

Example:

Then the parcels log has 2 entries matching 'storing parcel PX-DBF-3002 failed, retrying'
Then [[within {duration} ]]the logs have entries matching:
| ... | ... |

Wait until every log in the table has a match for its regular expression (log | pattern rows), for example the service’s own entry and its dependency’s. Each row needs a match of its own.

Variants (optional parts in [[...]] above):

  • the logs have entries matching:
  • within {duration} the logs have entries matching:

Parameters: {duration} (A duration in seconds or minutes, e.g. 5s or 2m)

Example:

Then the logs have entries matching: