1 """Support for script and automation tracing and debugging."""
3 from __future__
import annotations
5 from collections.abc
import Mapping
13 from .const
import DATA_TRACE, DATA_TRACE_STORE, DATA_TRACES_RESTORED
14 from .models
import ActionTrace, BaseTrace, RestoredTrace, TraceData
16 _LOGGER = logging.getLogger(__name__)
20 hass: HomeAssistant, key: str, run_id: str
21 ) -> dict[str, BaseTrace]:
22 """Return the requested trace."""
26 return hass.data[DATA_TRACE][key][run_id].as_extended_dict()
30 hass: HomeAssistant, key: str |
None
31 ) -> dict[str, dict[str, str]]:
32 """List contexts for which we have traces."""
36 values: Mapping[str, LimitedSizeDict[str, BaseTrace] |
None] | TraceData
38 values = {key: hass.data[DATA_TRACE].
get(key)}
40 values = hass.data[DATA_TRACE]
42 def _trace_id(run_id: str, key: str) -> dict[str, str]:
43 """Make trace_id for the response."""
44 domain, item_id = key.split(
".", 1)
45 return {
"run_id": run_id,
"domain": domain,
"item_id": item_id}
48 trace.context.id: _trace_id(trace.run_id, key)
49 for key, traces
in values.items()
51 for trace
in traces.values()
56 """Return a serializable list of debug traces for a script or automation."""
57 if traces_for_key := hass.data[DATA_TRACE].
get(key):
58 return [trace.as_short_dict()
for trace
in traces_for_key.values()]
63 hass: HomeAssistant, wanted_domain: str, wanted_key: str |
None
64 ) -> list[dict[str, Any]]:
65 """List traces for a domain."""
70 traces: list[dict[str, Any]] = []
71 for key
in hass.data[DATA_TRACE]:
72 domain = key.split(
".", 1)[0]
73 if domain == wanted_domain:
82 hass: HomeAssistant, trace: ActionTrace, stored_traces: int
84 """Store a trace if its key is valid."""
86 traces = hass.data[DATA_TRACE]
90 traces[key].size_limit = stored_traces
91 traces[key][trace.run_id] = trace
95 """Store a restored trace and move it to the end of the LimitedSizeDict."""
97 traces = hass.data[DATA_TRACE]
100 traces[key][trace.run_id] = trace
101 traces[key].move_to_end(trace.run_id, last=
False)
105 """Restore saved traces."""
106 if DATA_TRACES_RESTORED
in hass.data:
109 hass.data[DATA_TRACES_RESTORED] =
True
111 store = hass.data[DATA_TRACE_STORE]
113 restored_traces = await store.async_load()
or {}
114 except HomeAssistantError:
115 _LOGGER.exception(
"Error loading traces")
118 for key, traces
in restored_traces.items():
120 for json_trace
in reversed(traces):
122 (stored_traces := hass.data[DATA_TRACE].
get(key))
123 and stored_traces.size_limit
is not None
124 and len(stored_traces) >= stored_traces.size_limit
132 _LOGGER.exception(
"Failed to restore trace")
web.Response get(self, web.Request request, str config_key)
None _async_store_restored_trace(HomeAssistant hass, RestoredTrace trace)
list[dict[str, Any]] _get_debug_traces(HomeAssistant hass, str key)
None async_store_trace(HomeAssistant hass, ActionTrace trace, int stored_traces)
dict[str, BaseTrace] async_get_trace(HomeAssistant hass, str key, str run_id)
None async_restore_traces(HomeAssistant hass)
dict[str, dict[str, str]] async_list_contexts(HomeAssistant hass, str|None key)
list[dict[str, Any]] async_list_traces(HomeAssistant hass, str wanted_domain, str|None wanted_key)