mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-10 02:36:29 +00:00
Add diagnostics support (#1870)
* Add diagnostics support Signed-off-by: Pascal Vizeli <pvizeli@syshack.ch> * add aditional data * Fix handling * Better states * Fix opt * Update supervisor/bootstrap.py Co-authored-by: Paulus Schoutsen <balloob@gmail.com> * Only events on supported systems Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
6599ae0ee0
commit
ad988f2a24
1
API.md
1
API.md
@ -47,6 +47,7 @@ The addons from `addons` are only installed one.
|
||||
"wait_boot": "int",
|
||||
"debug": "bool",
|
||||
"debug_block": "bool",
|
||||
"diagnostics": "None|bool",
|
||||
"addons": [
|
||||
{
|
||||
"name": "xy bla",
|
||||
|
@ -14,5 +14,6 @@ pulsectl==20.5.1
|
||||
pytz==2020.1
|
||||
pyudev==0.22.0
|
||||
ruamel.yaml==0.15.100
|
||||
sentry-sdk==0.16.3
|
||||
uvloop==0.14.0
|
||||
voluptuous==0.11.7
|
||||
|
@ -17,6 +17,7 @@ from ..const import (
|
||||
ATTR_DEBUG,
|
||||
ATTR_DEBUG_BLOCK,
|
||||
ATTR_DESCRIPTON,
|
||||
ATTR_DIAGNOSTICS,
|
||||
ATTR_ICON,
|
||||
ATTR_INSTALLED,
|
||||
ATTR_IP_ADDRESS,
|
||||
@ -58,6 +59,7 @@ SCHEMA_OPTIONS = vol.Schema(
|
||||
vol.Optional(ATTR_LOGGING): vol.Coerce(LogLevel),
|
||||
vol.Optional(ATTR_DEBUG): vol.Boolean(),
|
||||
vol.Optional(ATTR_DEBUG_BLOCK): vol.Boolean(),
|
||||
vol.Optional(ATTR_DIAGNOSTICS): vol.Boolean(),
|
||||
}
|
||||
)
|
||||
|
||||
@ -102,6 +104,7 @@ class APISupervisor(CoreSysAttributes):
|
||||
ATTR_LOGGING: self.sys_config.logging,
|
||||
ATTR_DEBUG: self.sys_config.debug,
|
||||
ATTR_DEBUG_BLOCK: self.sys_config.debug_block,
|
||||
ATTR_DIAGNOSTICS: self.sys_config.diagnostics,
|
||||
ATTR_ADDONS: list_addons,
|
||||
ATTR_ADDONS_REPOSITORIES: self.sys_config.addons_repositories,
|
||||
}
|
||||
@ -126,6 +129,9 @@ class APISupervisor(CoreSysAttributes):
|
||||
if ATTR_DEBUG_BLOCK in body:
|
||||
self.sys_config.debug_block = body[ATTR_DEBUG_BLOCK]
|
||||
|
||||
if ATTR_DIAGNOSTICS in body:
|
||||
self.sys_config.diagnostics = body[ATTR_DIAGNOSTICS]
|
||||
|
||||
if ATTR_LOGGING in body:
|
||||
self.sys_config.logging = body[ATTR_LOGGING]
|
||||
|
||||
|
@ -6,6 +6,13 @@ import shutil
|
||||
import signal
|
||||
|
||||
from colorlog import ColoredFormatter
|
||||
import sentry_sdk
|
||||
from sentry_sdk.integrations.aiohttp import AioHttpIntegration
|
||||
from sentry_sdk.integrations.atexit import AtexitIntegration
|
||||
from sentry_sdk.integrations.dedupe import DedupeIntegration
|
||||
from sentry_sdk.integrations.excepthook import ExcepthookIntegration
|
||||
from sentry_sdk.integrations.stdlib import StdlibIntegration
|
||||
from sentry_sdk.integrations.threading import ThreadingIntegration
|
||||
|
||||
from .addons import AddonManager
|
||||
from .api import RestAPI
|
||||
@ -17,6 +24,8 @@ from .const import (
|
||||
ENV_SUPERVISOR_NAME,
|
||||
ENV_SUPERVISOR_SHARE,
|
||||
SOCKET_DOCKER,
|
||||
SUPERVISOR_VERSION,
|
||||
CoreStates,
|
||||
LogLevel,
|
||||
UpdateChannels,
|
||||
)
|
||||
@ -73,6 +82,9 @@ async def initialize_coresys() -> CoreSys:
|
||||
coresys.secrets = SecretsManager(coresys)
|
||||
coresys.scheduler = Scheduler(coresys)
|
||||
|
||||
# diagnostics
|
||||
setup_diagnostics(coresys)
|
||||
|
||||
# bootstrap config
|
||||
initialize_system_data(coresys)
|
||||
|
||||
@ -270,3 +282,54 @@ def supervisor_debugger(coresys: CoreSys) -> None:
|
||||
if coresys.config.debug_block:
|
||||
_LOGGER.info("Wait until debugger is attached")
|
||||
ptvsd.wait_for_attach()
|
||||
|
||||
|
||||
def setup_diagnostics(coresys: CoreSys) -> None:
|
||||
"""Sentry diagnostic backend."""
|
||||
|
||||
def filter_data(event, hint):
|
||||
# Ignore issue if system is not supported or diagnostics is disabled
|
||||
if not coresys.config.diagnostics or not coresys.core.healthy:
|
||||
return None
|
||||
|
||||
# Not full startup - missing information
|
||||
if coresys.core.state in (CoreStates.INITIALIZE, CoreStates.SETUP):
|
||||
return event
|
||||
|
||||
# Update information
|
||||
with sentry_sdk.configure_scope() as scope:
|
||||
scope.set_context(
|
||||
"supervisor",
|
||||
{
|
||||
"machine": coresys.machine,
|
||||
"arch": coresys.arch.default,
|
||||
"docker": coresys.docker.info.version,
|
||||
"channel": coresys.updater.channel,
|
||||
"supervisor": coresys.supervisor.version,
|
||||
"os": coresys.hassos.version,
|
||||
"core": coresys.homeassistant.version,
|
||||
"audio": coresys.plugins.audio.version,
|
||||
"dns": coresys.plugins.dns.version,
|
||||
"multicast": coresys.plugins.multicast.version,
|
||||
"cli": coresys.plugins.cli.version,
|
||||
},
|
||||
)
|
||||
|
||||
return event
|
||||
|
||||
sentry_sdk.init(
|
||||
dsn="https://9c6ea70f49234442b4746e447b24747e@o427061.ingest.sentry.io/5370612",
|
||||
before_send=filter_data,
|
||||
default_integrations=False,
|
||||
integrations=[
|
||||
AioHttpIntegration(),
|
||||
AtexitIntegration(),
|
||||
ExcepthookIntegration(),
|
||||
DedupeIntegration(),
|
||||
StdlibIntegration(),
|
||||
ThreadingIntegration(),
|
||||
],
|
||||
)
|
||||
|
||||
with sentry_sdk.configure_scope() as scope:
|
||||
scope.set_tag("version", SUPERVISOR_VERSION)
|
||||
|
@ -3,12 +3,13 @@ from datetime import datetime
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path, PurePath
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
from .const import (
|
||||
ATTR_ADDONS_CUSTOM_LIST,
|
||||
ATTR_DEBUG,
|
||||
ATTR_DEBUG_BLOCK,
|
||||
ATTR_DIAGNOSTICS,
|
||||
ATTR_LAST_BOOT,
|
||||
ATTR_LOGGING,
|
||||
ATTR_TIMEZONE,
|
||||
@ -101,6 +102,16 @@ class CoreConfig(JsonConfig):
|
||||
"""Set debug wait mode."""
|
||||
self._data[ATTR_DEBUG_BLOCK] = value
|
||||
|
||||
@property
|
||||
def diagnostics(self) -> Optional[bool]:
|
||||
"""Return bool if diagnostics is set otherwise None."""
|
||||
return self._data[ATTR_DIAGNOSTICS]
|
||||
|
||||
@diagnostics.setter
|
||||
def diagnostics(self, value: bool) -> None:
|
||||
"""Set diagnostics settings."""
|
||||
self._data[ATTR_DIAGNOSTICS] = value
|
||||
|
||||
@property
|
||||
def logging(self) -> LogLevel:
|
||||
"""Return log level of system."""
|
||||
|
@ -240,6 +240,7 @@ ATTR_INDEX = "index"
|
||||
ATTR_ACTIVE = "active"
|
||||
ATTR_APPLICATION = "application"
|
||||
ATTR_INIT = "init"
|
||||
ATTR_DIAGNOSTICS = "diagnostics"
|
||||
|
||||
PROVIDE_SERVICE = "provide"
|
||||
NEED_SERVICE = "need"
|
||||
@ -355,6 +356,7 @@ class CoreStates(str, Enum):
|
||||
"""Represent current loading state."""
|
||||
|
||||
INITIALIZE = "initialize"
|
||||
SETUP = "setup"
|
||||
STARTUP = "startup"
|
||||
RUNNING = "running"
|
||||
FREEZE = "freeze"
|
||||
|
@ -55,7 +55,7 @@ class Core(CoreSysAttributes):
|
||||
|
||||
async def setup(self):
|
||||
"""Start setting up supervisor orchestration."""
|
||||
self.state = CoreStates.STARTUP
|
||||
self.state = CoreStates.SETUP
|
||||
|
||||
# Load DBus
|
||||
await self.sys_dbus.load()
|
||||
@ -104,6 +104,7 @@ class Core(CoreSysAttributes):
|
||||
|
||||
async def start(self):
|
||||
"""Start Supervisor orchestration."""
|
||||
self.state = CoreStates.STARTUP
|
||||
await self.sys_api.start()
|
||||
|
||||
# Mark booted partition as healthy
|
||||
|
@ -18,6 +18,7 @@ from .const import (
|
||||
ATTR_CLI,
|
||||
ATTR_DEBUG,
|
||||
ATTR_DEBUG_BLOCK,
|
||||
ATTR_DIAGNOSTICS,
|
||||
ATTR_DNS,
|
||||
ATTR_HASSOS,
|
||||
ATTR_HOMEASSISTANT,
|
||||
@ -176,6 +177,7 @@ SCHEMA_SUPERVISOR_CONFIG = vol.Schema(
|
||||
vol.Optional(ATTR_LOGGING, default=LogLevel.INFO): vol.Coerce(LogLevel),
|
||||
vol.Optional(ATTR_DEBUG, default=False): vol.Boolean(),
|
||||
vol.Optional(ATTR_DEBUG_BLOCK, default=False): vol.Boolean(),
|
||||
vol.Optional(ATTR_DIAGNOSTICS, default=None): vol.Maybe(vol.Boolean()),
|
||||
},
|
||||
extra=vol.REMOVE_EXTRA,
|
||||
)
|
||||
|
@ -19,6 +19,8 @@ def docker():
|
||||
async def coresys(loop, docker):
|
||||
"""Create a CoreSys Mock."""
|
||||
with patch("supervisor.bootstrap.initialize_system_data"), patch(
|
||||
"supervisor.bootstrap.setup_diagnostics"
|
||||
), patch(
|
||||
"supervisor.bootstrap.fetch_timezone", return_value="Europe/Zurich",
|
||||
):
|
||||
coresys_obj = await initialize_coresys()
|
||||
|
Loading…
x
Reference in New Issue
Block a user