mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Optimize logger callback API by including message length parameter
This commit is contained in:
		| @@ -1459,12 +1459,11 @@ void APIConnection::update_command(const UpdateCommandRequest &msg) { | |||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| bool APIConnection::try_send_log_message(int level, const char *tag, const char *line) { | bool APIConnection::try_send_log_message(int level, const char *tag, const char *line, size_t line_length) { | ||||||
|   if (this->flags_.log_subscription < level) |   if (this->flags_.log_subscription < level) | ||||||
|     return false; |     return false; | ||||||
|  |  | ||||||
|   // Pre-calculate message size to avoid reallocations |   // Pre-calculate message size to avoid reallocations | ||||||
|   const size_t line_length = strlen(line); |  | ||||||
|   uint32_t msg_size = 0; |   uint32_t msg_size = 0; | ||||||
|  |  | ||||||
|   // Add size for level field (field ID 1, varint type) |   // Add size for level field (field ID 1, varint type) | ||||||
|   | |||||||
| @@ -107,7 +107,7 @@ class APIConnection : public APIServerConnection { | |||||||
|   bool send_media_player_state(media_player::MediaPlayer *media_player); |   bool send_media_player_state(media_player::MediaPlayer *media_player); | ||||||
|   void media_player_command(const MediaPlayerCommandRequest &msg) override; |   void media_player_command(const MediaPlayerCommandRequest &msg) override; | ||||||
| #endif | #endif | ||||||
|   bool try_send_log_message(int level, const char *tag, const char *line); |   bool try_send_log_message(int level, const char *tag, const char *line, size_t line_length); | ||||||
|   void send_homeassistant_service_call(const HomeassistantServiceResponse &call) { |   void send_homeassistant_service_call(const HomeassistantServiceResponse &call) { | ||||||
|     if (!this->flags_.service_call_subscription) |     if (!this->flags_.service_call_subscription) | ||||||
|       return; |       return; | ||||||
|   | |||||||
| @@ -104,18 +104,19 @@ void APIServer::setup() { | |||||||
|  |  | ||||||
| #ifdef USE_LOGGER | #ifdef USE_LOGGER | ||||||
|   if (logger::global_logger != nullptr) { |   if (logger::global_logger != nullptr) { | ||||||
|     logger::global_logger->add_on_log_callback([this](int level, const char *tag, const char *message) { |     logger::global_logger->add_on_log_callback( | ||||||
|       if (this->shutting_down_) { |         [this](int level, const char *tag, const char *message, size_t message_len) { | ||||||
|         // Don't try to send logs during shutdown |           if (this->shutting_down_) { | ||||||
|         // as it could result in a recursion and |             // Don't try to send logs during shutdown | ||||||
|         // we would be filling a buffer we are trying to clear |             // as it could result in a recursion and | ||||||
|         return; |             // we would be filling a buffer we are trying to clear | ||||||
|       } |             return; | ||||||
|       for (auto &c : this->clients_) { |           } | ||||||
|         if (!c->flags_.remove) |           for (auto &c : this->clients_) { | ||||||
|           c->try_send_log_message(level, tag, message); |             if (!c->flags_.remove) | ||||||
|       } |               c->try_send_log_message(level, tag, message, message_len); | ||||||
|     }); |           } | ||||||
|  |         }); | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   | |||||||
| @@ -121,7 +121,8 @@ void Logger::log_vprintf_(uint8_t level, const char *tag, int line, const __Flas | |||||||
|   if (this->baud_rate_ > 0) { |   if (this->baud_rate_ > 0) { | ||||||
|     this->write_msg_(this->tx_buffer_ + msg_start); |     this->write_msg_(this->tx_buffer_ + msg_start); | ||||||
|   } |   } | ||||||
|   this->log_callback_.call(level, tag, this->tx_buffer_ + msg_start); |   size_t msg_length = this->tx_buffer_at_ - msg_start - 1;  // -1 to exclude null terminator | ||||||
|  |   this->log_callback_.call(level, tag, this->tx_buffer_ + msg_start, msg_length); | ||||||
|  |  | ||||||
|   global_recursion_guard_ = false; |   global_recursion_guard_ = false; | ||||||
| } | } | ||||||
| @@ -185,7 +186,8 @@ void Logger::loop() { | |||||||
|                                   this->tx_buffer_size_); |                                   this->tx_buffer_size_); | ||||||
|       this->write_footer_to_buffer_(this->tx_buffer_, &this->tx_buffer_at_, this->tx_buffer_size_); |       this->write_footer_to_buffer_(this->tx_buffer_, &this->tx_buffer_at_, this->tx_buffer_size_); | ||||||
|       this->tx_buffer_[this->tx_buffer_at_] = '\0'; |       this->tx_buffer_[this->tx_buffer_at_] = '\0'; | ||||||
|       this->log_callback_.call(message->level, message->tag, this->tx_buffer_); |       size_t msg_len = strlen(this->tx_buffer_);  // Need strlen here since we don't store length in queued messages | ||||||
|  |       this->log_callback_.call(message->level, message->tag, this->tx_buffer_, msg_len); | ||||||
|       // At this point all the data we need from message has been transferred to the tx_buffer |       // At this point all the data we need from message has been transferred to the tx_buffer | ||||||
|       // so we can release the message to allow other tasks to use it as soon as possible. |       // so we can release the message to allow other tasks to use it as soon as possible. | ||||||
|       this->log_buffer_->release_message_main_loop(received_token); |       this->log_buffer_->release_message_main_loop(received_token); | ||||||
| @@ -214,7 +216,7 @@ void Logger::set_log_level(const std::string &tag, uint8_t log_level) { this->lo | |||||||
| UARTSelection Logger::get_uart() const { return this->uart_; } | UARTSelection Logger::get_uart() const { return this->uart_; } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| void Logger::add_on_log_callback(std::function<void(uint8_t, const char *, const char *)> &&callback) { | void Logger::add_on_log_callback(std::function<void(uint8_t, const char *, const char *, size_t)> &&callback) { | ||||||
|   this->log_callback_.add(std::move(callback)); |   this->log_callback_.add(std::move(callback)); | ||||||
| } | } | ||||||
| float Logger::get_setup_priority() const { return setup_priority::BUS + 500.0f; } | float Logger::get_setup_priority() const { return setup_priority::BUS + 500.0f; } | ||||||
|   | |||||||
| @@ -143,7 +143,7 @@ class Logger : public Component { | |||||||
|   inline uint8_t level_for(const char *tag); |   inline uint8_t level_for(const char *tag); | ||||||
|  |  | ||||||
|   /// Register a callback that will be called for every log message sent |   /// Register a callback that will be called for every log message sent | ||||||
|   void add_on_log_callback(std::function<void(uint8_t, const char *, const char *)> &&callback); |   void add_on_log_callback(std::function<void(uint8_t, const char *, const char *, size_t)> &&callback); | ||||||
|  |  | ||||||
|   // add a listener for log level changes |   // add a listener for log level changes | ||||||
|   void add_listener(std::function<void(uint8_t)> &&callback) { this->level_callback_.add(std::move(callback)); } |   void add_listener(std::function<void(uint8_t)> &&callback) { this->level_callback_.add(std::move(callback)); } | ||||||
| @@ -192,7 +192,7 @@ class Logger : public Component { | |||||||
|     if (this->baud_rate_ > 0) { |     if (this->baud_rate_ > 0) { | ||||||
|       this->write_msg_(this->tx_buffer_);  // If logging is enabled, write to console |       this->write_msg_(this->tx_buffer_);  // If logging is enabled, write to console | ||||||
|     } |     } | ||||||
|     this->log_callback_.call(level, tag, this->tx_buffer_); |     this->log_callback_.call(level, tag, this->tx_buffer_, this->tx_buffer_at_); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Write the body of the log message to the buffer |   // Write the body of the log message to the buffer | ||||||
| @@ -246,7 +246,7 @@ class Logger : public Component { | |||||||
|  |  | ||||||
|   // Large objects (internally aligned) |   // Large objects (internally aligned) | ||||||
|   std::map<std::string, uint8_t> log_levels_{}; |   std::map<std::string, uint8_t> log_levels_{}; | ||||||
|   CallbackManager<void(uint8_t, const char *, const char *)> log_callback_{}; |   CallbackManager<void(uint8_t, const char *, const char *, size_t)> log_callback_{}; | ||||||
|   CallbackManager<void(uint8_t)> level_callback_{}; |   CallbackManager<void(uint8_t)> level_callback_{}; | ||||||
| #ifdef USE_ESPHOME_TASK_LOG_BUFFER | #ifdef USE_ESPHOME_TASK_LOG_BUFFER | ||||||
|   std::unique_ptr<logger::TaskLogBuffer> log_buffer_;  // Will be initialized with init_log_buffer |   std::unique_ptr<logger::TaskLogBuffer> log_buffer_;  // Will be initialized with init_log_buffer | ||||||
|   | |||||||
| @@ -57,14 +57,15 @@ void MQTTClientComponent::setup() { | |||||||
|   }); |   }); | ||||||
| #ifdef USE_LOGGER | #ifdef USE_LOGGER | ||||||
|   if (this->is_log_message_enabled() && logger::global_logger != nullptr) { |   if (this->is_log_message_enabled() && logger::global_logger != nullptr) { | ||||||
|     logger::global_logger->add_on_log_callback([this](int level, const char *tag, const char *message) { |     logger::global_logger->add_on_log_callback( | ||||||
|       if (level <= this->log_level_ && this->is_connected()) { |         [this](int level, const char *tag, const char *message, size_t message_len) { | ||||||
|         this->publish({.topic = this->log_message_.topic, |           if (level <= this->log_level_ && this->is_connected()) { | ||||||
|                        .payload = message, |             this->publish({.topic = this->log_message_.topic, | ||||||
|                        .qos = this->log_message_.qos, |                            .payload = std::string(message, message_len), | ||||||
|                        .retain = this->log_message_.retain}); |                            .qos = this->log_message_.qos, | ||||||
|       } |                            .retain = this->log_message_.retain}); | ||||||
|     }); |           } | ||||||
|  |         }); | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,10 +21,12 @@ constexpr int LOG_LEVEL_TO_SYSLOG_SEVERITY[] = { | |||||||
|  |  | ||||||
| void Syslog::setup() { | void Syslog::setup() { | ||||||
|   logger::global_logger->add_on_log_callback( |   logger::global_logger->add_on_log_callback( | ||||||
|       [this](int level, const char *tag, const char *message) { this->log_(level, tag, message); }); |       [this](int level, const char *tag, const char *message, size_t message_len) { | ||||||
|  |         this->log_(level, tag, message, message_len); | ||||||
|  |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Syslog::log_(const int level, const char *tag, const char *message) const { | void Syslog::log_(const int level, const char *tag, const char *message, size_t message_len) const { | ||||||
|   if (level > this->log_level_) |   if (level > this->log_level_) | ||||||
|     return; |     return; | ||||||
|   // Syslog PRI calculation: facility * 8 + severity |   // Syslog PRI calculation: facility * 8 + severity | ||||||
| @@ -34,7 +36,7 @@ void Syslog::log_(const int level, const char *tag, const char *message) const { | |||||||
|   } |   } | ||||||
|   int pri = this->facility_ * 8 + severity; |   int pri = this->facility_ * 8 + severity; | ||||||
|   auto timestamp = this->time_->now().strftime("%b %d %H:%M:%S"); |   auto timestamp = this->time_->now().strftime("%b %d %H:%M:%S"); | ||||||
|   unsigned len = strlen(message); |   unsigned len = message_len; | ||||||
|   // remove color formatting |   // remove color formatting | ||||||
|   if (this->strip_ && message[0] == 0x1B && len > 11) { |   if (this->strip_ && message[0] == 0x1B && len > 11) { | ||||||
|     message += 7; |     message += 7; | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ class Syslog : public Component, public Parented<udp::UDPComponent> { | |||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   int log_level_; |   int log_level_; | ||||||
|   void log_(int level, const char *tag, const char *message) const; |   void log_(int level, const char *tag, const char *message, size_t message_len) const; | ||||||
|   time::RealTimeClock *time_; |   time::RealTimeClock *time_; | ||||||
|   bool strip_{true}; |   bool strip_{true}; | ||||||
|   int facility_{16}; |   int facility_{16}; | ||||||
|   | |||||||
| @@ -287,7 +287,7 @@ void WebServer::setup() { | |||||||
|   if (logger::global_logger != nullptr && this->expose_log_) { |   if (logger::global_logger != nullptr && this->expose_log_) { | ||||||
|     logger::global_logger->add_on_log_callback( |     logger::global_logger->add_on_log_callback( | ||||||
|         // logs are not deferred, the memory overhead would be too large |         // logs are not deferred, the memory overhead would be too large | ||||||
|         [this](int level, const char *tag, const char *message) { |         [this](int level, const char *tag, const char *message, size_t message_len) { | ||||||
|           this->events_.try_send_nodefer(message, "log", millis()); |           this->events_.try_send_nodefer(message, "log", millis()); | ||||||
|         }); |         }); | ||||||
|   } |   } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user