brbzull0 opened a new pull request, #13842:
URL: https://github.com/apache/trafficserver/pull/13842
Follow-up to #13032. Fixes #13832.
`traffic_ctl --error-level` (#13032) grades a JSONRPC handler failure by the
severity of its annotations. A `config reload` outcome is not a JSONRPC error:
it comes back inside a successful response, as a task state plus task logs, so
the level did not apply to it. On master, `config reload --monitor` exits 2
when the top-level task ends `fail` or `timeout` and 0 on `success`, whatever
its log entries say, and `config status` exits 0 for every reload it shows.
This PR grades a finished reload by its task states and log entries, in
`config reload --monitor` and in `config status`. Nothing changes on the server
or the wire.
### What it does
- **The grade** (`appExitCodeFromReload` in `TrafficCtlStatus.h`): the most
severe log entry of the task and of its sub-tasks, at any depth, is compared
with `--error-level`.
- The state of each task bounds its entries. A task that ended `fail` or
`timeout` counts as at least `error`, also when it logged nothing. The entries
of any other task count as at most `warn`, since its handler did not fail it.
With the default level the exit status therefore follows the task states: 2
when any task, at any depth, ended `fail` or `timeout`.
- A task that ended `timeout` has no outcome: the progress checker marked
it after `proxy.config.admin.reload.timeout`, and its handler can still finish
afterwards. So a reload with such a task exits 75 (EX_TEMPFAIL) below the
level, not 0.
- An entry without a level is not graded: the one-argument `ctx.log(text)`
entries, the reason traffic_server logs when it marks a reload `timeout`, and
the plain-string logs of a traffic_server built before #13090. An entry whose
level is not a known level (an integer out of range, or not an integer) counts
as `emergency`. It is printed as before.
- A reload that is still running, has no state, or is in a state
`traffic_ctl` does not know, is not graded.
- **`config reload --monitor`** grades the first finished state it sees. The
`Details :` hint is printed when the reload did not end `success`, or when its
grade is not 0, which includes 75 for a sub-task that ended `timeout`.
`--monitor` prints text whatever `-f` says, as on master.
- **`config status`** grades the newest reload it shows. With `--count N`,
the older reloads are history and do not change the exit status. `--min-level`
still only filters what is printed: the grade covers every entry with a level,
shown or hidden. `-f json` is graded the same as text.
- **Inline reloads (`--data`)**: the exit status now depends on
`--error-level`, so the "not persisted to disk" note follows how the reload
ended instead.
- Without `--monitor`, it is printed once the reload is scheduled.
- With `--monitor`, it is printed when the reload ended `success`,
whatever its grade, or was still running when the monitor stopped, and not when
it ended `fail` or `timeout`. When the monitor cannot read the state (a status
poll failed, or the reply had no task), it is printed unless the exit status is
2, as before.
- It is not printed when the server refused the request because another
reload was in progress.
How the open points of #13832 were decided:
| Open point | Decision |
|---|---|
| A `fail` task with no entry at or above the level, or no entries | Counts
as at least `error`: exits 2 at the default level. `--error-level fatal` lets
it exit 0 unless a task that failed logged `fatal` or above. |
| `timeout` | Same as `fail`, and 75 instead of 0 below the level. |
| Sub-task entries; `DL_Undefined` | Sub-task entries count, at any depth.
Entries without a level are not graded. |
| `config status --count N` | The newest reload shown decides. |
| `--min-level` and `--error-level` | `--min-level` filters the display
only. |
| (not in the issue) A `success` task with `error` or worse entries | Counts
as at most `warn`: exits 0 at the default level, 2 at `--error-level warn`. Its
handler chose to complete, as `cache.config` does when it drops a bad line. |
### Behaviour changes at the default level
- `config status` exits 2 when the newest reload it shows ended `fail` or
`timeout`. It used to exit 0, so a script that runs it to print the report must
now accept 2. Eight runs in four AuTests under `tests/gold_tests/jsonrpc/`
asserted 0 for that case and now assert 2.
- `config status` and `config reload --monitor` also exit 2, and `--monitor`
prints the `Details :` hint, for a reload that reports `success` while one of
its sub-tasks ended `fail` or `timeout`. traffic_server does not report such a
reload: its parent task takes the worst state of its sub-tasks. Another JSONRPC
node could.
- The inline-reload note is no longer printed when the server refused the
request because another reload was in progress.
For the reloads traffic_server reports, `config reload --monitor`, and so
the `AddConfigReload` test helper, keep their exit status: 0 for `success`,
also with `[Err]` entries, and 2 for `fail` or `timeout`. There, 75 comes from
the monitor's own `--timeout`, or from a request it depends on that failed
below the level (#13032), as before. The first two changes are listed in
`doc/release-notes/upgrading.en.rst`.
### What this PR does not do
- `config reload` without `--monitor`, and with `--show-details`, is not
graded. It returns once the reload is scheduled, or after one snapshot taken
after `--initial-wait`, before there is an outcome. `--monitor` is the way to
wait for one.
- A reload that is still running, has no state, or is in an unknown state is
not graded. `config status` exits 0 for it, not 75. `--monitor` keeps polling
it until `--timeout`, as on master.
- No line explains why a graded reload failed. `config status` prints the
entries as before, minus those `--min-level` hides, and `--monitor` prints the
`Details :` hint.
- Some traffic_server warnings carry no level in the task log, so they are
not graded. The `records.yaml` handler logs its errata with `ctx.log("{}",
zret)`, which stores no level, so `--error-level warn` does not fail a
`records.yaml` reload that only logged warnings. Logging them with their level
is a server change, left for a follow-up.
- After `config reload -D` without `--data`, the "not persisted to disk"
note is still printed, as on master: `-D` writes into the same `configs` node
as `--data` (#13110), and the note is keyed on that node. `virtualhost.yaml`
(#13108) is the first core handler that reads a directive, so `-D` now has a
core use. The fix needs a flag of its own for `--data` content, separate from
the grade; left for a follow-up.
- `config reload --monitor` refused because another reload is in progress
follows that other reload and exits with its grade, as on master it exited with
its state. With `-d` it can exit 0 although the content was refused; only the
note now says nothing was applied.
### Tests
- `src/traffic_ctl/unit_tests/test_traffic_ctl_status.cc`: 12 new `[reload]`
cases: the grade, the bounds of each state, sub-tasks at any depth (including
"A sub-task that failed counts as at least an error, whatever its parent
says"), timeouts, unfinished and unknown states, malformed levels, and decoding
the level.
- `tests/gold_tests/traffic_ctl/traffic_ctl_reload_error_level.test.py`
(new, 71 runs):
- against traffic_server: a `cache.config` reload that rejects a line
(`success` with an `[Err]` entry), a clean reload, and a directory in place of
`cache.config` (`fail`);
- against a second traffic_server with the `cfg_plugin_deferred_test`
plugin and `proxy.config.admin.reload.timeout` at 1 s, so the reload ends
`timeout`;
- against the stand-in JSONRPC node from #13032 (`jsonrpc_error_stub.py`),
for task trees traffic_server does not produce on demand: levels out of range
or not integers, unknown states, sub-tasks that failed or timed out under a
parent that succeeded, `--count`, poll errors, and the inline-reload note.
- The four reload tests under `tests/gold_tests/jsonrpc/`: `config status`
on a failed reload now expects 2.
- Red/green: with the `src/traffic_ctl` sources reverted to master and the
tests kept, the new test and the four updated ones fail. 47 runs fail, 8 in the
four updated tests and 39 in the new one: 46 on the exit code, and one on the
inline note. With the change, all five pass.
- Mutation: two passes over earlier versions of the change, 39 and 46
mutants. Each mutant that survived got a run in the new AuTest that killed it
at the time. The last fix round came after both passes and reworked the
inline-note condition and the clamping of out-of-range levels; no mutation pass
has run on those lines.
### Docs
- `traffic_ctl.en.rst`: how a reload is graded, under `--error-level`; the
`config reload` exit codes; a new exit-code list for `config status`;
`--min-level`; the `--data` note.
- `upgrading.en.rst`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]