[logger] Fix ESP8266 crash with VERY_VERBOSE log level (#14980)

This commit is contained in:
J. Nick Koston
2026-03-19 14:11:49 -10:00
committed by Jesse Hills
parent 08cab43548
commit daf3502e15
4 changed files with 34 additions and 12 deletions
+20 -9
View File
@@ -56,6 +56,7 @@ from esphome.const import (
PlatformFramework,
)
from esphome.core import CORE, CoroPriority, Lambda, coroutine_with_priority
from esphome.types import ConfigType
CODEOWNERS = ["@esphome/core"]
logger_ns = cg.esphome_ns.namespace("logger")
@@ -323,12 +324,11 @@ CONFIG_SCHEMA = cv.All(
)
@coroutine_with_priority(CoroPriority.DIAGNOSTICS)
async def to_code(config):
baud_rate = config[CONF_BAUD_RATE]
@coroutine_with_priority(CoroPriority.EARLY_INIT)
async def to_code(config: ConfigType) -> None:
baud_rate: int = config[CONF_BAUD_RATE]
level = config[CONF_LEVEL]
CORE.data.setdefault(CONF_LOGGER, {})[CONF_LEVEL] = level
initial_level = LOG_LEVELS[config.get(CONF_INITIAL_LEVEL, level)]
tx_buffer_size = config[CONF_TX_BUFFER_SIZE]
cg.add_define("ESPHOME_LOGGER_TX_BUFFER_SIZE", tx_buffer_size)
log = cg.new_Pvariable(
@@ -347,10 +347,23 @@ async def to_code(config):
HARDWARE_UART_TO_UART_SELECTION[config[CONF_HARDWARE_UART]]
)
)
# pre_setup() must be called before init_log_buffer() because
# init_log_buffer() calls disable_loop() which may log at VV level,
# and global_logger must be set before any logging occurs.
# pre_setup() sets global_logger and must run before any other code
# that may call ESP_LOG* (e.g. setup_preferences contains ESP_LOGVV).
cg.add(log.pre_setup())
initial_level = LOG_LEVELS[config.get(CONF_INITIAL_LEVEL, level)]
cg.add(log.set_log_level(initial_level))
# Schedule the rest of logger setup at DIAGNOSTICS priority, after
# Application is constructed (CORE priority) but before most components.
CORE.add_job(_late_logger_init, config)
@coroutine_with_priority(CoroPriority.DIAGNOSTICS)
async def _late_logger_init(config: ConfigType) -> None:
"""Finish logger setup after Application is constructed."""
log = await cg.get_variable(config[CONF_ID])
level = config[CONF_LEVEL]
baud_rate: int = config[CONF_BAUD_RATE]
if CORE.is_esp32 or CORE.is_libretiny or CORE.is_nrf52:
task_log_buffer_size = config[CONF_TASK_LOG_BUFFER_SIZE]
if task_log_buffer_size > 0:
@@ -363,8 +376,6 @@ async def to_code(config):
cg.add_define("USE_ESPHOME_TASK_LOG_BUFFER")
cg.add(log.init_log_buffer(64)) # Fixed 64 slots for host
cg.add(log.set_log_level(initial_level))
# Enable runtime tag levels if logs are configured or explicitly enabled
logs_config = config[CONF_LOGS]
if logs_config or config[CONF_RUNTIME_TAG_LEVELS]:
+3 -1
View File
@@ -587,7 +587,9 @@ async def _add_looping_components() -> None:
@coroutine_with_priority(CoroPriority.CORE)
async def to_code(config: ConfigType) -> None:
cg.add_global(cg.global_ns.namespace("esphome").using)
# using namespace esphome is hardcoded in writer.py to guarantee it
# precedes all variable declarations regardless of coroutine priority.
# These can be used by user lambdas, put them to default scope
cg.add_global(cg.RawExpression("using std::isnan"))
cg.add_global(cg.RawExpression("using std::min"))
+8 -2
View File
@@ -63,7 +63,13 @@ class CoroPriority(enum.IntEnum):
resolution during code generation.
"""
# Platform initialization - must run first
# Early init - runs before platform init and before Application exists.
# Currently used only to connect logging so ESP_LOG* calls work
# immediately in all subsequent phases.
# Examples: logger (1100)
EARLY_INIT = 1100
# Platform initialization
# Examples: esp32, esp8266, rp2040
PLATFORM = 1000
@@ -83,7 +89,7 @@ class CoroPriority(enum.IntEnum):
CORE = 100
# Diagnostic and debugging systems
# Examples: logger (90)
# Examples: debug component (90)
DIAGNOSTICS = 90
# Status and monitoring systems
+3
View File
@@ -381,7 +381,10 @@ def write_cpp(code_s):
code_format = CPP_BASE_FORMAT
copy_src_tree()
# using namespace esphome must precede all variable declarations since
# codegen types assume this namespace is in scope (esphome_ns = global_ns).
global_s = '#include "esphome.h"\n'
global_s += "using namespace esphome;\n"
global_s += CORE.cpp_global_section
full_file = f"{code_format[0] + CPP_INCLUDE_BEGIN}\n{global_s}{CPP_INCLUDE_END}"