1
0
mirror of https://github.com/home-assistant/supervisor.git synced 2025-12-20 02:18:59 +00:00

Add option to Core settings to enable duplicated logs (#6400)

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.
This commit is contained in:
Jan Čermák
2025-12-08 16:35:56 +01:00
committed by GitHub
parent b79130816b
commit cdef1831ba
7 changed files with 48 additions and 0 deletions

View File

@@ -18,6 +18,7 @@ from ..const import (
ATTR_BLK_WRITE, ATTR_BLK_WRITE,
ATTR_BOOT, ATTR_BOOT,
ATTR_CPU_PERCENT, ATTR_CPU_PERCENT,
ATTR_DUPLICATE_LOG_FILE,
ATTR_IMAGE, ATTR_IMAGE,
ATTR_IP_ADDRESS, ATTR_IP_ADDRESS,
ATTR_JOB_ID, ATTR_JOB_ID,
@@ -55,6 +56,7 @@ SCHEMA_OPTIONS = vol.Schema(
vol.Optional(ATTR_AUDIO_OUTPUT): vol.Maybe(str), vol.Optional(ATTR_AUDIO_OUTPUT): vol.Maybe(str),
vol.Optional(ATTR_AUDIO_INPUT): vol.Maybe(str), vol.Optional(ATTR_AUDIO_INPUT): vol.Maybe(str),
vol.Optional(ATTR_BACKUPS_EXCLUDE_DATABASE): vol.Boolean(), vol.Optional(ATTR_BACKUPS_EXCLUDE_DATABASE): vol.Boolean(),
vol.Optional(ATTR_DUPLICATE_LOG_FILE): vol.Boolean(),
} }
) )
@@ -112,6 +114,7 @@ class APIHomeAssistant(CoreSysAttributes):
ATTR_AUDIO_INPUT: self.sys_homeassistant.audio_input, ATTR_AUDIO_INPUT: self.sys_homeassistant.audio_input,
ATTR_AUDIO_OUTPUT: self.sys_homeassistant.audio_output, ATTR_AUDIO_OUTPUT: self.sys_homeassistant.audio_output,
ATTR_BACKUPS_EXCLUDE_DATABASE: self.sys_homeassistant.backups_exclude_database, ATTR_BACKUPS_EXCLUDE_DATABASE: self.sys_homeassistant.backups_exclude_database,
ATTR_DUPLICATE_LOG_FILE: self.sys_homeassistant.duplicate_log_file,
} }
@api_process @api_process
@@ -151,6 +154,9 @@ class APIHomeAssistant(CoreSysAttributes):
ATTR_BACKUPS_EXCLUDE_DATABASE ATTR_BACKUPS_EXCLUDE_DATABASE
] ]
if ATTR_DUPLICATE_LOG_FILE in body:
self.sys_homeassistant.duplicate_log_file = body[ATTR_DUPLICATE_LOG_FILE]
await self.sys_homeassistant.save_data() await self.sys_homeassistant.save_data()
@api_process @api_process

View File

@@ -179,6 +179,7 @@ ATTR_DOCKER = "docker"
ATTR_DOCKER_API = "docker_api" ATTR_DOCKER_API = "docker_api"
ATTR_DOCUMENTATION = "documentation" ATTR_DOCUMENTATION = "documentation"
ATTR_DOMAINS = "domains" ATTR_DOMAINS = "domains"
ATTR_DUPLICATE_LOG_FILE = "duplicate_log_file"
ATTR_ENABLE = "enable" ATTR_ENABLE = "enable"
ATTR_ENABLE_IPV6 = "enable_ipv6" ATTR_ENABLE_IPV6 = "enable_ipv6"
ATTR_ENABLED = "enabled" ATTR_ENABLED = "enabled"

View File

@@ -133,6 +133,7 @@ class PullImageLayerStage(Enum):
return None return None
ENV_DUPLICATE_LOG_FILE = "HA_DUPLICATE_LOG_FILE"
ENV_TIME = "TZ" ENV_TIME = "TZ"
ENV_TOKEN = "SUPERVISOR_TOKEN" ENV_TOKEN = "SUPERVISOR_TOKEN"
ENV_TOKEN_OLD = "HASSIO_TOKEN" ENV_TOKEN_OLD = "HASSIO_TOKEN"

View File

@@ -14,6 +14,7 @@ from ..homeassistant.const import LANDINGPAGE
from ..jobs.const import JobConcurrency from ..jobs.const import JobConcurrency
from ..jobs.decorator import Job from ..jobs.decorator import Job
from .const import ( from .const import (
ENV_DUPLICATE_LOG_FILE,
ENV_TIME, ENV_TIME,
ENV_TOKEN, ENV_TOKEN,
ENV_TOKEN_OLD, ENV_TOKEN_OLD,
@@ -174,6 +175,8 @@ class DockerHomeAssistant(DockerInterface):
} }
if restore_job_id: if restore_job_id:
environment[ENV_RESTORE_JOB_ID] = restore_job_id environment[ENV_RESTORE_JOB_ID] = restore_job_id
if self.sys_homeassistant.duplicate_log_file:
environment[ENV_DUPLICATE_LOG_FILE] = "1"
await self._run( await self._run(
tag=(self.sys_homeassistant.version), tag=(self.sys_homeassistant.version),
name=self.name, name=self.name,

View File

@@ -23,6 +23,7 @@ from ..const import (
ATTR_AUDIO_OUTPUT, ATTR_AUDIO_OUTPUT,
ATTR_BACKUPS_EXCLUDE_DATABASE, ATTR_BACKUPS_EXCLUDE_DATABASE,
ATTR_BOOT, ATTR_BOOT,
ATTR_DUPLICATE_LOG_FILE,
ATTR_IMAGE, ATTR_IMAGE,
ATTR_MESSAGE, ATTR_MESSAGE,
ATTR_PORT, ATTR_PORT,
@@ -299,6 +300,16 @@ class HomeAssistant(FileConfiguration, CoreSysAttributes):
"""Set whether backups should exclude database by default.""" """Set whether backups should exclude database by default."""
self._data[ATTR_BACKUPS_EXCLUDE_DATABASE] = value self._data[ATTR_BACKUPS_EXCLUDE_DATABASE] = value
@property
def duplicate_log_file(self) -> bool:
"""Return True if Home Assistant should duplicate logs to file."""
return self._data[ATTR_DUPLICATE_LOG_FILE]
@duplicate_log_file.setter
def duplicate_log_file(self, value: bool) -> None:
"""Set whether Home Assistant should duplicate logs to file."""
self._data[ATTR_DUPLICATE_LOG_FILE] = value
async def load(self) -> None: async def load(self) -> None:
"""Prepare Home Assistant object.""" """Prepare Home Assistant object."""
await asyncio.wait( await asyncio.wait(

View File

@@ -10,6 +10,7 @@ from ..const import (
ATTR_AUDIO_OUTPUT, ATTR_AUDIO_OUTPUT,
ATTR_BACKUPS_EXCLUDE_DATABASE, ATTR_BACKUPS_EXCLUDE_DATABASE,
ATTR_BOOT, ATTR_BOOT,
ATTR_DUPLICATE_LOG_FILE,
ATTR_IMAGE, ATTR_IMAGE,
ATTR_PORT, ATTR_PORT,
ATTR_REFRESH_TOKEN, ATTR_REFRESH_TOKEN,
@@ -36,6 +37,7 @@ SCHEMA_HASS_CONFIG = vol.Schema(
vol.Optional(ATTR_AUDIO_OUTPUT, default=None): vol.Maybe(str), vol.Optional(ATTR_AUDIO_OUTPUT, default=None): vol.Maybe(str),
vol.Optional(ATTR_AUDIO_INPUT, default=None): vol.Maybe(str), vol.Optional(ATTR_AUDIO_INPUT, default=None): vol.Maybe(str),
vol.Optional(ATTR_BACKUPS_EXCLUDE_DATABASE, default=False): vol.Boolean(), vol.Optional(ATTR_BACKUPS_EXCLUDE_DATABASE, default=False): vol.Boolean(),
vol.Optional(ATTR_DUPLICATE_LOG_FILE, default=False): vol.Boolean(),
vol.Optional(ATTR_OVERRIDE_IMAGE, default=False): vol.Boolean(), vol.Optional(ATTR_OVERRIDE_IMAGE, default=False): vol.Boolean(),
}, },
extra=vol.REMOVE_EXTRA, extra=vol.REMOVE_EXTRA,

View File

@@ -46,6 +46,7 @@ async def test_homeassistant_start(
"TZ": ANY, "TZ": ANY,
"SUPERVISOR_TOKEN": ANY, "SUPERVISOR_TOKEN": ANY,
"HASSIO_TOKEN": ANY, "HASSIO_TOKEN": ANY,
# no "HA_DUPLICATE_LOG_FILE"
} }
assert run.call_args.kwargs["mounts"] == [ assert run.call_args.kwargs["mounts"] == [
DEV_MOUNT, DEV_MOUNT,
@@ -105,6 +106,28 @@ async def test_homeassistant_start(
assert "volumes" not in run.call_args.kwargs assert "volumes" not in run.call_args.kwargs
async def test_homeassistant_start_with_duplicate_log_file(
coresys: CoreSys, tmp_supervisor_data: Path, path_extern
):
"""Test starting homeassistant with duplicate_log_file enabled."""
coresys.homeassistant.version = AwesomeVersion("2025.12.0")
coresys.homeassistant.duplicate_log_file = True
with (
patch.object(DockerAPI, "run") as run,
patch.object(
DockerHomeAssistant, "is_running", side_effect=[False, False, True]
),
patch("supervisor.homeassistant.core.asyncio.sleep"),
):
await coresys.homeassistant.core.start()
run.assert_called_once()
env = run.call_args.kwargs["environment"]
assert "HA_DUPLICATE_LOG_FILE" in env
assert env["HA_DUPLICATE_LOG_FILE"] == "1"
async def test_landingpage_start( async def test_landingpage_start(
coresys: CoreSys, tmp_supervisor_data: Path, path_extern coresys: CoreSys, tmp_supervisor_data: Path, path_extern
): ):
@@ -133,6 +156,7 @@ async def test_landingpage_start(
"TZ": ANY, "TZ": ANY,
"SUPERVISOR_TOKEN": ANY, "SUPERVISOR_TOKEN": ANY,
"HASSIO_TOKEN": ANY, "HASSIO_TOKEN": ANY,
# no "HA_DUPLICATE_LOG_FILE"
} }
assert run.call_args.kwargs["mounts"] == [ assert run.call_args.kwargs["mounts"] == [
DEV_MOUNT, DEV_MOUNT,