diff --git a/esphome/components/logger/__init__.py b/esphome/components/logger/__init__.py index c8f3c52911..264197c175 100644 --- a/esphome/components/logger/__init__.py +++ b/esphome/components/logger/__init__.py @@ -329,10 +329,11 @@ async def to_code(config): 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( config[CONF_ID], baud_rate, - config[CONF_TX_BUFFER_SIZE], ) if CORE.is_esp32: cg.add(log.create_pthread_key()) diff --git a/esphome/components/logger/logger.cpp b/esphome/components/logger/logger.cpp index 22a95e4835..497809cd2e 100644 --- a/esphome/components/logger/logger.cpp +++ b/esphome/components/logger/logger.cpp @@ -152,10 +152,7 @@ inline uint8_t Logger::level_for(const char *tag) { return this->current_level_; } -Logger::Logger(uint32_t baud_rate, size_t tx_buffer_size) : baud_rate_(baud_rate), tx_buffer_size_(tx_buffer_size) { - // add 1 to buffer size for null terminator - // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) - allocated once, never freed - this->tx_buffer_ = new char[this->tx_buffer_size_ + 1]; +Logger::Logger(uint32_t baud_rate) : baud_rate_(baud_rate) { #if defined(USE_ESP32) || defined(USE_LIBRETINY) this->main_task_ = xTaskGetCurrentTaskHandle(); #elif defined(USE_ZEPHYR) @@ -196,7 +193,7 @@ void Logger::process_messages_() { uint16_t text_length; while (this->log_buffer_->borrow_message_main_loop(message, text_length)) { const char *thread_name = message->thread_name[0] != '\0' ? message->thread_name : nullptr; - LogBuffer buf{this->tx_buffer_, this->tx_buffer_size_}; + LogBuffer buf{this->tx_buffer_, ESPHOME_LOGGER_TX_BUFFER_SIZE}; this->format_buffered_message_and_notify_(message->level, message->tag, message->line, thread_name, message->text_data(), text_length, buf); // Release the message to allow other tasks to use it as soon as possible diff --git a/esphome/components/logger/logger.h b/esphome/components/logger/logger.h index 8bf1edebb8..90722ee79c 100644 --- a/esphome/components/logger/logger.h +++ b/esphome/components/logger/logger.h @@ -143,7 +143,7 @@ enum UARTSelection : uint8_t { */ class Logger : public Component { public: - explicit Logger(uint32_t baud_rate, size_t tx_buffer_size); + explicit Logger(uint32_t baud_rate); #ifdef USE_ESPHOME_TASK_LOG_BUFFER void init_log_buffer(size_t total_buffer_size); #endif @@ -281,7 +281,7 @@ class Logger : public Component { inline void HOT log_message_to_buffer_and_send_(bool &recursion_guard, uint8_t level, const char *tag, int line, FormatType format, va_list args, const char *thread_name) { RecursionGuard guard(recursion_guard); - LogBuffer buf{this->tx_buffer_, this->tx_buffer_size_}; + LogBuffer buf{this->tx_buffer_, ESPHOME_LOGGER_TX_BUFFER_SIZE}; #ifdef USE_STORE_LOG_STR_IN_FLASH if constexpr (std::is_same_v) { this->format_log_to_buffer_with_terminator_P_(level, tag, line, format, args, buf); @@ -312,7 +312,6 @@ class Logger : public Component { // Group 4-byte aligned members first uint32_t baud_rate_; - char *tx_buffer_{nullptr}; #if defined(USE_ARDUINO) && !defined(USE_ESP32) Stream *hw_serial_{nullptr}; #endif @@ -354,7 +353,6 @@ class Logger : public Component { #endif // Group smaller types together at the end - uint16_t tx_buffer_size_{0}; uint8_t current_level_{ESPHOME_LOG_LEVEL_VERY_VERBOSE}; #if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_ZEPHYR) UARTSelection uart_{UART_SELECTION_UART0}; @@ -371,6 +369,9 @@ class Logger : public Component { bool global_recursion_guard_{false}; // Simple global recursion guard for single-task platforms #endif + // Large buffer placed last to keep frequently-accessed member offsets small + char tx_buffer_[ESPHOME_LOGGER_TX_BUFFER_SIZE + 1]; // +1 for null terminator + // --- get_thread_name_ overloads (per-platform) --- #if defined(USE_ESP32) || defined(USE_LIBRETINY) diff --git a/esphome/components/logger/logger_esp32.cpp b/esphome/components/logger/logger_esp32.cpp index 9d64771aec..d6ad77ff4f 100644 --- a/esphome/components/logger/logger_esp32.cpp +++ b/esphome/components/logger/logger_esp32.cpp @@ -89,16 +89,16 @@ void Logger::pre_setup() { switch (this->uart_) { case UART_SELECTION_UART0: this->uart_num_ = UART_NUM_0; - init_uart(this->uart_num_, baud_rate_, tx_buffer_size_); + init_uart(this->uart_num_, baud_rate_, ESPHOME_LOGGER_TX_BUFFER_SIZE); break; case UART_SELECTION_UART1: this->uart_num_ = UART_NUM_1; - init_uart(this->uart_num_, baud_rate_, tx_buffer_size_); + init_uart(this->uart_num_, baud_rate_, ESPHOME_LOGGER_TX_BUFFER_SIZE); break; #ifdef USE_ESP32_VARIANT_ESP32 case UART_SELECTION_UART2: this->uart_num_ = UART_NUM_2; - init_uart(this->uart_num_, baud_rate_, tx_buffer_size_); + init_uart(this->uart_num_, baud_rate_, ESPHOME_LOGGER_TX_BUFFER_SIZE); break; #endif #ifdef USE_LOGGER_USB_CDC diff --git a/esphome/components/logger/logger_host.cpp b/esphome/components/logger/logger_host.cpp index be12b6df6a..fe094f6e9e 100644 --- a/esphome/components/logger/logger_host.cpp +++ b/esphome/components/logger/logger_host.cpp @@ -5,8 +5,8 @@ namespace esphome::logger { void HOT Logger::write_msg_(const char *msg, uint16_t len) { static constexpr size_t TIMESTAMP_LEN = 10; // "[HH:MM:SS]" - // tx_buffer_size_ defaults to 512, so 768 covers default + headroom - char buffer[TIMESTAMP_LEN + 768]; + static constexpr size_t HEADROOM = 128; // Extra space for ANSI codes, newline, etc. + char buffer[TIMESTAMP_LEN + ESPHOME_LOGGER_TX_BUFFER_SIZE + HEADROOM]; time_t rawtime; time(&rawtime); diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 02335e2745..1128df94f0 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -21,6 +21,7 @@ // logger #define ESPHOME_LOG_LEVEL ESPHOME_LOG_LEVEL_VERY_VERBOSE +#define ESPHOME_LOGGER_TX_BUFFER_SIZE 512 #define USE_LOG_LISTENERS #define ESPHOME_LOG_MAX_LISTENERS 8 diff --git a/tests/dummy_main.cpp b/tests/dummy_main.cpp index e6fe733807..52f1fbd319 100644 --- a/tests/dummy_main.cpp +++ b/tests/dummy_main.cpp @@ -13,7 +13,7 @@ using namespace esphome; void setup() { App.pre_setup("livingroom", "LivingRoom", false); - auto *log = new logger::Logger(115200, 512); // NOLINT + auto *log = new logger::Logger(115200); // NOLINT log->pre_setup(); log->set_uart_selection(logger::UART_SELECTION_UART0); App.register_component(log);