Skip to content

Commit 0e7e8ef

Browse files
committed
Add option to Core settings to enable duplicated logs
Introduce new option `duplicate_log_file` to HA Core configuration that will set an environment variable `HA_DUPLICATE_LOG_FILE=1` for the Core container if enabled. This will serve as a flag for Core to enable the legacy log file, along the standard logging which is handled by Systemd Journal.
1 parent 4d9e283 commit 0e7e8ef

File tree

7 files changed

+48
-0
lines changed

7 files changed

+48
-0
lines changed

supervisor/api/homeassistant.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
ATTR_BLK_WRITE,
1919
ATTR_BOOT,
2020
ATTR_CPU_PERCENT,
21+
ATTR_DUPLICATE_LOG_FILE,
2122
ATTR_IMAGE,
2223
ATTR_IP_ADDRESS,
2324
ATTR_JOB_ID,
@@ -55,6 +56,7 @@
5556
vol.Optional(ATTR_AUDIO_OUTPUT): vol.Maybe(str),
5657
vol.Optional(ATTR_AUDIO_INPUT): vol.Maybe(str),
5758
vol.Optional(ATTR_BACKUPS_EXCLUDE_DATABASE): vol.Boolean(),
59+
vol.Optional(ATTR_DUPLICATE_LOG_FILE): vol.Boolean(),
5860
}
5961
)
6062

@@ -112,6 +114,7 @@ async def info(self, request: web.Request) -> dict[str, Any]:
112114
ATTR_AUDIO_INPUT: self.sys_homeassistant.audio_input,
113115
ATTR_AUDIO_OUTPUT: self.sys_homeassistant.audio_output,
114116
ATTR_BACKUPS_EXCLUDE_DATABASE: self.sys_homeassistant.backups_exclude_database,
117+
ATTR_DUPLICATE_LOG_FILE: self.sys_homeassistant.duplicate_log_file,
115118
}
116119

117120
@api_process
@@ -151,6 +154,9 @@ async def options(self, request: web.Request) -> None:
151154
ATTR_BACKUPS_EXCLUDE_DATABASE
152155
]
153156

157+
if ATTR_DUPLICATE_LOG_FILE in body:
158+
self.sys_homeassistant.duplicate_log_file = body[ATTR_DUPLICATE_LOG_FILE]
159+
154160
await self.sys_homeassistant.save_data()
155161

156162
@api_process

supervisor/const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@
179179
ATTR_DOCKER_API = "docker_api"
180180
ATTR_DOCUMENTATION = "documentation"
181181
ATTR_DOMAINS = "domains"
182+
ATTR_DUPLICATE_LOG_FILE = "duplicate_log_file"
182183
ATTR_ENABLE = "enable"
183184
ATTR_ENABLE_IPV6 = "enable_ipv6"
184185
ATTR_ENABLED = "enabled"

supervisor/docker/const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ def from_status(cls, status: str) -> PullImageLayerStage | None:
133133
return None
134134

135135

136+
ENV_DUPLICATE_LOG_FILE = "HA_DUPLICATE_LOG_FILE"
136137
ENV_TIME = "TZ"
137138
ENV_TOKEN = "SUPERVISOR_TOKEN"
138139
ENV_TOKEN_OLD = "HASSIO_TOKEN"

supervisor/docker/homeassistant.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from ..jobs.const import JobConcurrency
1515
from ..jobs.decorator import Job
1616
from .const import (
17+
ENV_DUPLICATE_LOG_FILE,
1718
ENV_TIME,
1819
ENV_TOKEN,
1920
ENV_TOKEN_OLD,
@@ -174,6 +175,8 @@ async def run(self, *, restore_job_id: str | None = None) -> None:
174175
}
175176
if restore_job_id:
176177
environment[ENV_RESTORE_JOB_ID] = restore_job_id
178+
if self.sys_homeassistant.duplicate_log_file:
179+
environment[ENV_DUPLICATE_LOG_FILE] = "1"
177180
await self._run(
178181
tag=(self.sys_homeassistant.version),
179182
name=self.name,

supervisor/homeassistant/module.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
ATTR_AUDIO_OUTPUT,
2424
ATTR_BACKUPS_EXCLUDE_DATABASE,
2525
ATTR_BOOT,
26+
ATTR_DUPLICATE_LOG_FILE,
2627
ATTR_IMAGE,
2728
ATTR_MESSAGE,
2829
ATTR_PORT,
@@ -299,6 +300,16 @@ def backups_exclude_database(self, value: bool) -> None:
299300
"""Set whether backups should exclude database by default."""
300301
self._data[ATTR_BACKUPS_EXCLUDE_DATABASE] = value
301302

303+
@property
304+
def duplicate_log_file(self) -> bool:
305+
"""Return True if Home Assistant should duplicate logs to file."""
306+
return self._data[ATTR_DUPLICATE_LOG_FILE]
307+
308+
@duplicate_log_file.setter
309+
def duplicate_log_file(self, value: bool) -> None:
310+
"""Set whether Home Assistant should duplicate logs to file."""
311+
self._data[ATTR_DUPLICATE_LOG_FILE] = value
312+
302313
async def load(self) -> None:
303314
"""Prepare Home Assistant object."""
304315
await asyncio.wait(

supervisor/homeassistant/validate.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
ATTR_AUDIO_OUTPUT,
1111
ATTR_BACKUPS_EXCLUDE_DATABASE,
1212
ATTR_BOOT,
13+
ATTR_DUPLICATE_LOG_FILE,
1314
ATTR_IMAGE,
1415
ATTR_PORT,
1516
ATTR_REFRESH_TOKEN,
@@ -36,6 +37,7 @@
3637
vol.Optional(ATTR_AUDIO_OUTPUT, default=None): vol.Maybe(str),
3738
vol.Optional(ATTR_AUDIO_INPUT, default=None): vol.Maybe(str),
3839
vol.Optional(ATTR_BACKUPS_EXCLUDE_DATABASE, default=False): vol.Boolean(),
40+
vol.Optional(ATTR_DUPLICATE_LOG_FILE, default=False): vol.Boolean(),
3941
vol.Optional(ATTR_OVERRIDE_IMAGE, default=False): vol.Boolean(),
4042
},
4143
extra=vol.REMOVE_EXTRA,

tests/docker/test_homeassistant.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ async def test_homeassistant_start(
4646
"TZ": ANY,
4747
"SUPERVISOR_TOKEN": ANY,
4848
"HASSIO_TOKEN": ANY,
49+
# no "HA_DUPLICATE_LOG_FILE"
4950
}
5051
assert run.call_args.kwargs["mounts"] == [
5152
DEV_MOUNT,
@@ -105,6 +106,28 @@ async def test_homeassistant_start(
105106
assert "volumes" not in run.call_args.kwargs
106107

107108

109+
async def test_homeassistant_start_with_duplicate_log_file(
110+
coresys: CoreSys, tmp_supervisor_data: Path, path_extern
111+
):
112+
"""Test starting homeassistant with duplicate_log_file enabled."""
113+
coresys.homeassistant.version = AwesomeVersion("2025.12.0")
114+
coresys.homeassistant.duplicate_log_file = True
115+
116+
with (
117+
patch.object(DockerAPI, "run") as run,
118+
patch.object(
119+
DockerHomeAssistant, "is_running", side_effect=[False, False, True]
120+
),
121+
patch("supervisor.homeassistant.core.asyncio.sleep"),
122+
):
123+
await coresys.homeassistant.core.start()
124+
125+
run.assert_called_once()
126+
env = run.call_args.kwargs["environment"]
127+
assert "HA_DUPLICATE_LOG_FILE" in env
128+
assert env["HA_DUPLICATE_LOG_FILE"] == "1"
129+
130+
108131
async def test_landingpage_start(
109132
coresys: CoreSys, tmp_supervisor_data: Path, path_extern
110133
):
@@ -133,6 +156,7 @@ async def test_landingpage_start(
133156
"TZ": ANY,
134157
"SUPERVISOR_TOKEN": ANY,
135158
"HASSIO_TOKEN": ANY,
159+
# no "HA_DUPLICATE_LOG_FILE"
136160
}
137161
assert run.call_args.kwargs["mounts"] == [
138162
DEV_MOUNT,

0 commit comments

Comments
 (0)