Commit 6172dd0
authored
fix(addon): honor web-UI log level; arm kill-signal diagnostics at DEBUG; plumb journald log window (#1734)
* fix(addon): honor web-UI log level in addon logs; arm kill-signal diagnostics at DEBUG
The addon's start.py hardcoded logging.basicConfig(level=INFO) and never
re-applied the effective settings, so the web Settings UI "Log level"
advanced setting could not change addon log verbosity — reporters asked
to enable debug logging saw INFO-only output (surfaced in #1721).
- start.py now re-applies the resolved settings.log_level (including the
/data/feature_flags.json override) to the root logger after ha_mcp
becomes importable, and emits a DEBUG-level canary line so logs prove
the level took effect.
- The confusing "Advanced debug logging" addon toggle is removed from
both addon flavors; kill-signal diagnostics now arm whenever the
effective log level is DEBUG. Supervisor ignores the stale key in
existing options.json with a warning (supervisor/apps/options.py), so
no migration shim is needed.
- Container regression test boots the addon with a DEBUG override file
and asserts the canary + diagnostics arming; unit tests cover the
level-resolution fallback paths.
- Docker/stdio/pip modes are untouched: changes are confined to the
addon entrypoint, addon config schemas, and log-string renames in
kill_signal_diagnostics.py.
* test(e2e): verify web-UI DEBUG log level end-to-end in the inaddon lane
Full user journey against the real dev addon inside HAOS: POST
log_level=DEBUG to the settings advanced API, self-restart via
hassio.addon_restart (severed response tolerated), then assert the
DEBUG canary + kill-signal diagnostics arming lines in the addon's own
container log via ha_get_logs(source=supervisor). Restores INFO after.
Every MCP call uses a fresh streamable-HTTP client so the test never
depends on a connection surviving its own server's restart.
* style: ruff format new test files
* test: fix CodeQL mixed-import alert; bump per-lane skip ceilings for new inaddon test
monkeypatch.setattr takes the dotted-path string form, removing the
import-vs-import-from mix CodeQL flagged. Container and haos lanes each
gain one skip from the new @inaddon_only debug-log-level e2e test.
* test(e2e): narrow polling excepts to transient-error tuple per styleguide
Broad 'except Exception' in the restart-recovery loop could swallow real
bugs (TypeError/KeyError/AssertionError) and retry to timeout. Use
wait_helpers' _POLLING_TRANSIENT_ERRORS plus httpx.HTTPError for the
transport dying mid-restart; bugs now propagate.
* fix(addon): warn loudly when log-level resolution fails; assert INFO path arms nothing
Review findings: the settings-resolution fallback returned INFO with
zero operator signal — recreating the silent-no-op class this PR kills;
now logs a WARNING with the exception. The default-INFO container test
now asserts the DEBUG canary and kill-signal arming/install lines are
ABSENT, guarding the arming gate against regressing to always-on.
* docs: fix stale kill-signal banner and two inaccurate start.py comments
Review findings: the signal-dump banner still named the removed
'Advanced debug logging' toggle; the resolve_effective_log_level
docstring claimed Settings construction requires the HA env vars (it
doesn't — the real hazard is get_global_settings caching a singleton
with placeholder values); 'importable' meant 'imported' in two spots.
* test(e2e): fix ha_call_service args in self-restart; require observed down-window
The restart call passed service='hassio.addon_restart' instead of
domain='hassio' + service='addon_restart', so ha_call_service raised
VALIDATION_FAILED — which the severed-call except swallowed as
'expected', the addon never restarted, and the canary assertion failed
with a misleading message (first inaddon CI run). Args now match
test_addon_lifecycle's _addon_action, and the helper requires observing
the HTTP endpoint go DOWN before polling recovery, so any silently
failed restart fails fast with the real cause.
* test(e2e): rebuild self-restart on the settings /restart endpoint + poll-until-canary
Review findings (code-reviewer agent): the hand-rolled GET liveness
probe fights FastMCP's transport (documented GET-RST behavior in
wait_for_addon_mcp_ready), and a single-shot limit=400 log tail could
scroll the boot markers out under DEBUG verbosity. Now mirrors the
proven readonly-mode machinery: settings /restart endpoint (200
flushes before the background bounce), wait_for_addon_mcp_ready +
fresh client per poll round, poll-until-all-lines with limit=2000 as
the positive restart-took-effect signal, retried INFO restore, and
shared mcp_client warm-up so later tests on the worker get a live
session. Container test now polls briefly for the install-thread's
confirmation line instead of racing it.
* test(e2e): raise AssertionError instead of pytest.fail in poll helper
CodeQL py/mixed-returns: it can't see pytest.fail is NoReturn, so the
helper looked like it mixed explicit and implicit returns. Matches the
readonly-mode test's raise-AssertionError shape.
* test(e2e): assert DEBUG records (scroll-proof) instead of one-shot boot lines; surface backup failure event
Round-2 inaddon CI showed why boot-line assertions can't work through
Supervisor's /addons/<slug>/logs: it serves only a bounded recent
window, and at DEBUG verbosity the start.py boot lines scroll out
within seconds. DEBUG-prefixed records regenerate with every request,
so their presence (vs a zero-DEBUG baseline asserted pre-restart) is a
deterministic proof the web-UI level reached the root logger. The boot
lines stay covered by the testcontainer tests, which read complete
docker logs.
Boy-scout: ha_manage_backup's create-failure paths now include HA's
last_action_event in the error context — CI arm failures previously
read 'Backup creation failed: Backup creation failed' with nothing to
diagnose.
* fix: plumb journald ?lines= window through supervisor log fetches
ha_get_logs(source=supervisor|system_service) silently returned at most
Supervisor's 100-line default window (DEFAULT_LINES in
supervisor/api/const.py) regardless of the tool's limit — found via
#1721's inaddon e2e, where DEBUG-verbosity boot lines scrolled out of
the window within seconds. get_addon_logs and _get_system_service_logs
now forward ?lines= on both the Supervisor-direct path (parsed natively
by supervisor/api/host.py) and the HA-Core hassio proxy (which forwards
request.query upstream). The tool wrappers size the window to the
caller's limit, expanding to SUPERVISOR_SEARCH_WINDOW_LINES (2000) when
a search filter needs history behind it.
The inaddon e2e now asserts the complete proof set: zero-DEBUG INFO
baseline, live DEBUG records after the web-UI DEBUG + self-restart, and
each start.py boot line (canary, kill-signal arming, install
confirmation) located via search over the expanded window — which
exercises the new plumbing end-to-end on a real Supervisor.
* test(e2e): route supervisor mock on bare path, not path+query
The mock matched routes against self.path, which includes the query
string, so the new ?lines= window param 404'd every mocked /logs call
('Unknown path: /audio/logs?lines=100'). Real Supervisor's aiohttp
router matches the bare path and the handler parses the query — mirror
that with urlsplit().path.
* test(e2e): drop AssertionError from the proof-polling transient tuple
Review (Patch76): AssertionError is a must-propagate bug class per the
styleguide section the tuple's own comment cites. The proof-polling
loop now propagates it; the finally-block restore/warm loops keep
retrying on it via a separate _RESTORE_TRANSIENT tuple, where a 5xx
mid-restart legitimately trips the status asserts (same shape as
test_readonly_mode's restore set).
---------
Co-authored-by: kingpanther13 <kingpanther13@users.noreply.github.com>1 parent 69bc4d7 commit 6172dd0
17 files changed
Lines changed: 698 additions & 59 deletions
File tree
- homeassistant-addon-dev
- translations
- homeassistant-addon
- translations
- src/ha_mcp
- client
- tools
- utils
- tests
- addon
- haos_image_build
- src
- e2e
- basic
- haos_only
- utilities
- unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
86 | 86 | | |
87 | 87 | | |
88 | 88 | | |
89 | | - | |
90 | 89 | | |
91 | 90 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
261 | 261 | | |
262 | 262 | | |
263 | 263 | | |
264 | | - | |
265 | | - | |
266 | | - | |
267 | | - | |
268 | | - | |
269 | | - | |
270 | | - | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
73 | | - | |
74 | 73 | | |
75 | 74 | | |
76 | 75 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
202 | 202 | | |
203 | 203 | | |
204 | 204 | | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
205 | 239 | | |
206 | 240 | | |
207 | 241 | | |
| |||
353 | 387 | | |
354 | 388 | | |
355 | 389 | | |
356 | | - | |
357 | 390 | | |
358 | 391 | | |
359 | 392 | | |
| |||
493 | 526 | | |
494 | 527 | | |
495 | 528 | | |
496 | | - | |
497 | | - | |
498 | | - | |
499 | 529 | | |
500 | 530 | | |
501 | 531 | | |
| |||
528 | 558 | | |
529 | 559 | | |
530 | 560 | | |
531 | | - | |
532 | 561 | | |
533 | 562 | | |
534 | 563 | | |
| |||
711 | 740 | | |
712 | 741 | | |
713 | 742 | | |
714 | | - | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
715 | 759 | | |
716 | 760 | | |
717 | 761 | | |
| |||
723 | 767 | | |
724 | 768 | | |
725 | 769 | | |
726 | | - | |
| 770 | + | |
727 | 771 | | |
728 | 772 | | |
729 | 773 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
99 | 99 | | |
100 | 100 | | |
101 | 101 | | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | 102 | | |
110 | 103 | | |
111 | 104 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
606 | 606 | | |
607 | 607 | | |
608 | 608 | | |
609 | | - | |
| 609 | + | |
610 | 610 | | |
611 | 611 | | |
612 | 612 | | |
| |||
621 | 621 | | |
622 | 622 | | |
623 | 623 | | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
624 | 633 | | |
625 | 634 | | |
626 | 635 | | |
| |||
633 | 642 | | |
634 | 643 | | |
635 | 644 | | |
636 | | - | |
| 645 | + | |
637 | 646 | | |
638 | 647 | | |
639 | 648 | | |
640 | 649 | | |
641 | 650 | | |
642 | 651 | | |
| 652 | + | |
643 | 653 | | |
644 | 654 | | |
645 | 655 | | |
646 | | - | |
| 656 | + | |
647 | 657 | | |
648 | 658 | | |
649 | 659 | | |
| |||
652 | 662 | | |
653 | 663 | | |
654 | 664 | | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
655 | 668 | | |
656 | 669 | | |
657 | 670 | | |
| |||
681 | 694 | | |
682 | 695 | | |
683 | 696 | | |
684 | | - | |
| 697 | + | |
685 | 698 | | |
686 | 699 | | |
| 700 | + | |
687 | 701 | | |
688 | 702 | | |
689 | 703 | | |
| |||
694 | 708 | | |
695 | 709 | | |
696 | 710 | | |
| 711 | + | |
697 | 712 | | |
698 | 713 | | |
699 | 714 | | |
| |||
753 | 768 | | |
754 | 769 | | |
755 | 770 | | |
756 | | - | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
757 | 774 | | |
758 | 775 | | |
759 | 776 | | |
| |||
766 | 783 | | |
767 | 784 | | |
768 | 785 | | |
769 | | - | |
| 786 | + | |
770 | 787 | | |
771 | | - | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
772 | 791 | | |
773 | 792 | | |
774 | 793 | | |
| |||
796 | 815 | | |
797 | 816 | | |
798 | 817 | | |
799 | | - | |
| 818 | + | |
800 | 819 | | |
801 | 820 | | |
802 | 821 | | |
803 | 822 | | |
804 | 823 | | |
805 | 824 | | |
| 825 | + | |
806 | 826 | | |
807 | 827 | | |
808 | 828 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
329 | 329 | | |
330 | 330 | | |
331 | 331 | | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
332 | 337 | | |
333 | 338 | | |
334 | 339 | | |
335 | 340 | | |
336 | | - | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
337 | 345 | | |
338 | 346 | | |
339 | 347 | | |
| |||
410 | 418 | | |
411 | 419 | | |
412 | 420 | | |
413 | | - | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
414 | 426 | | |
415 | 427 | | |
416 | 428 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
56 | 61 | | |
57 | 62 | | |
58 | 63 | | |
| |||
752 | 757 | | |
753 | 758 | | |
754 | 759 | | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
755 | 770 | | |
756 | | - | |
| 771 | + | |
757 | 772 | | |
758 | 773 | | |
759 | 774 | | |
| |||
892 | 907 | | |
893 | 908 | | |
894 | 909 | | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
895 | 916 | | |
896 | | - | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
897 | 920 | | |
898 | 921 | | |
899 | 922 | | |
| |||
0 commit comments