Merge branch 'logger_strlen' into integration

This commit is contained in:
J. Nick Koston 2025-07-07 08:47:27 -05:00
commit b9262f967b
No known key found for this signature in database
9 changed files with 39 additions and 34 deletions

View File

@ -1459,12 +1459,11 @@ void APIConnection::update_command(const UpdateCommandRequest &msg) {
}
#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)
return false;
// Pre-calculate message size to avoid reallocations
const size_t line_length = strlen(line);
uint32_t msg_size = 0;
// Add size for level field (field ID 1, varint type)

View File

@ -107,7 +107,7 @@ class APIConnection : public APIServerConnection {
bool send_media_player_state(media_player::MediaPlayer *media_player);
void media_player_command(const MediaPlayerCommandRequest &msg) override;
#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) {
if (!this->flags_.service_call_subscription)
return;

View File

@ -104,18 +104,19 @@ void APIServer::setup() {
#ifdef USE_LOGGER
if (logger::global_logger != nullptr) {
logger::global_logger->add_on_log_callback([this](int level, const char *tag, const char *message) {
if (this->shutting_down_) {
// Don't try to send logs during shutdown
// as it could result in a recursion and
// we would be filling a buffer we are trying to clear
return;
}
for (auto &c : this->clients_) {
if (!c->flags_.remove)
c->try_send_log_message(level, tag, message);
}
});
logger::global_logger->add_on_log_callback(
[this](int level, const char *tag, const char *message, size_t message_len) {
if (this->shutting_down_) {
// Don't try to send logs during shutdown
// as it could result in a recursion and
// we would be filling a buffer we are trying to clear
return;
}
for (auto &c : this->clients_) {
if (!c->flags_.remove)
c->try_send_log_message(level, tag, message, message_len);
}
});
}
#endif

View File

@ -121,7 +121,8 @@ void Logger::log_vprintf_(uint8_t level, const char *tag, int line, const __Flas
if (this->baud_rate_ > 0) {
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;
}
@ -185,7 +186,8 @@ void Logger::loop() {
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->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
// 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);
@ -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_; }
#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));
}
float Logger::get_setup_priority() const { return setup_priority::BUS + 500.0f; }

View File

@ -143,7 +143,7 @@ class Logger : public Component {
inline uint8_t level_for(const char *tag);
/// 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
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) {
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
@ -246,7 +246,7 @@ class Logger : public Component {
// Large objects (internally aligned)
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_{};
#ifdef USE_ESPHOME_TASK_LOG_BUFFER
std::unique_ptr<logger::TaskLogBuffer> log_buffer_; // Will be initialized with init_log_buffer

View File

@ -57,14 +57,15 @@ void MQTTClientComponent::setup() {
});
#ifdef USE_LOGGER
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) {
if (level <= this->log_level_ && this->is_connected()) {
this->publish({.topic = this->log_message_.topic,
.payload = message,
.qos = this->log_message_.qos,
.retain = this->log_message_.retain});
}
});
logger::global_logger->add_on_log_callback(
[this](int level, const char *tag, const char *message, size_t message_len) {
if (level <= this->log_level_ && this->is_connected()) {
this->publish({.topic = this->log_message_.topic,
.payload = std::string(message, message_len),
.qos = this->log_message_.qos,
.retain = this->log_message_.retain});
}
});
}
#endif

View File

@ -21,10 +21,12 @@ constexpr int LOG_LEVEL_TO_SYSLOG_SEVERITY[] = {
void Syslog::setup() {
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_)
return;
// 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;
auto timestamp = this->time_->now().strftime("%b %d %H:%M:%S");
unsigned len = strlen(message);
unsigned len = message_len;
// remove color formatting
if (this->strip_ && message[0] == 0x1B && len > 11) {
message += 7;

View File

@ -17,7 +17,7 @@ class Syslog : public Component, public Parented<udp::UDPComponent> {
protected:
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_;
bool strip_{true};
int facility_{16};

View File

@ -287,7 +287,7 @@ void WebServer::setup() {
if (logger::global_logger != nullptr && this->expose_log_) {
logger::global_logger->add_on_log_callback(
// 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());
});
}