7#if defined(USE_ESP32) || defined(USE_HOST)
23#if defined(USE_ESP8266)
24#include <HardwareSerial.h>
27#include <HardwareSerial.h>
33#include <driver/uart.h>
37#include <zephyr/kernel.h>
62 virtual void on_log(uint8_t level,
const char *tag,
const char *
message,
size_t message_len) = 0;
65#ifdef USE_LOGGER_LEVEL_LISTENERS
89#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS
92 bool operator()(
const char *a,
const char *b)
const {
return strcmp(a, b) < 0; }
98static constexpr size_t THREAD_NAME_BUF_SIZE = 64;
100#if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR)
113#if defined(USE_LIBRETINY) || defined(USE_ESP32_VARIANT_ESP32)
116#ifdef USE_LOGGER_USB_CDC
119#ifdef USE_LOGGER_USB_SERIAL_JTAG
147 explicit Logger(uint32_t baud_rate,
size_t tx_buffer_size);
148#ifdef USE_ESPHOME_TASK_LOG_BUFFER
151#if defined(USE_ESPHOME_TASK_LOG_BUFFER) || (defined(USE_ZEPHYR) && defined(USE_LOGGER_USB_CDC))
152 void loop()
override;
157#if defined(USE_ARDUINO) && !defined(USE_ESP32)
167#if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR)
175#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS
187 inline uint8_t
level_for(
const char *tag);
189#ifdef USE_LOG_LISTENERS
197#ifdef USE_LOGGER_LEVEL_LISTENERS
204 void log_vprintf_(uint8_t level,
const char *tag,
int line,
const char *format, va_list args);
205#ifdef USE_STORE_LOG_STR_IN_FLASH
206 void log_vprintf_(uint8_t level,
const char *tag,
int line,
const __FlashStringHelper *format,
225#if defined(USE_ESP32) || defined(USE_HOST) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR)
229 const char *thread_name);
231#if defined(USE_ZEPHYR) && defined(USE_LOGGER_USB_CDC)
240 va_list args,
LogBuffer &buf,
const char *thread_name) {
245#ifdef USE_STORE_LOG_STR_IN_FLASH
249 const __FlashStringHelper *format, va_list args,
258#ifdef USE_LOG_LISTENERS
260 listener->on_log(level, tag, buf.
data, buf.
pos);
279 template<
typename FormatType>
281 FormatType format, va_list args,
const char *thread_name) {
284#ifdef USE_STORE_LOG_STR_IN_FLASH
285 if constexpr (std::is_same_v<FormatType, const __FlashStringHelper *>) {
296#ifdef USE_ESPHOME_TASK_LOG_BUFFER
300 const char *thread_name,
const char *text, uint16_t text_length,
315#if defined(USE_ARDUINO) && !defined(USE_ESP32)
318#if defined(USE_ZEPHYR)
321#if defined(USE_ESP32) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR)
340#ifdef USE_LOGGER_RUNTIME_TAG_LEVELS
343#ifdef USE_LOG_LISTENERS
347#ifdef USE_LOGGER_LEVEL_LISTENERS
350#ifdef USE_ESPHOME_TASK_LOG_BUFFER
357#if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_ZEPHYR)
363#if defined(USE_ESP32) || defined(USE_HOST) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR)
374#if defined(USE_ESP32) || defined(USE_LIBRETINY)
381#if defined(USE_ESP32)
382 return pcTaskGetName(task);
383#elif defined(USE_LIBRETINY)
384 return pcTaskGetTaskName(task);
391#elif defined(USE_HOST)
394 pthread_t current_thread = pthread_self();
399 if (pthread_getname_np(current_thread, buff.data(), buff.size()) == 0) {
405#elif defined(USE_ZEPHYR)
407 if (current_task ==
nullptr) {
408 current_task = k_current_get();
413 const char *name = k_thread_name_get(current_task);
418 std::snprintf(buff.data(), buff.size(),
"%p", current_task);
425#if defined(USE_ESP32) || defined(USE_HOST)
430 pthread_setspecific(key_,
reinterpret_cast<void *
>(1));
448#elif defined(USE_LIBRETINY) || defined(USE_ZEPHYR)
467#if defined(USE_ESPHOME_TASK_LOG_BUFFER) && !(defined(USE_ZEPHYR) || defined(USE_LOGGER_USB_CDC))
485 void on_log(uint8_t level,
const char *tag,
const char *
message,
size_t message_len)
override {
487 if (level <= this->
level_) {
void disable_loop()
Disable this component's loop.
Minimal static vector - saves memory by avoiding std::vector overhead.
void trigger(const Ts &...x)
Interface for receiving log messages without std::function overhead.
virtual void on_log(uint8_t level, const char *tag, const char *message, size_t message_len)=0
NonMainTaskRecursionGuard & operator=(const NonMainTaskRecursionGuard &)=delete
~NonMainTaskRecursionGuard()
NonMainTaskRecursionGuard & operator=(NonMainTaskRecursionGuard &&)=delete
NonMainTaskRecursionGuard(const NonMainTaskRecursionGuard &)=delete
NonMainTaskRecursionGuard(pthread_key_t key)
NonMainTaskRecursionGuard(NonMainTaskRecursionGuard &&)=delete
RecursionGuard & operator=(const RecursionGuard &)=delete
RecursionGuard(const RecursionGuard &)=delete
RecursionGuard & operator=(RecursionGuard &&)=delete
RecursionGuard(RecursionGuard &&)=delete
RecursionGuard(bool &flag)
Logger component for all ESPHome logging.
void add_level_listener(LoggerLevelListener *listener)
Register a listener for log level changes.
void HOT notify_listeners_(uint8_t level, const char *tag, const LogBuffer &buf)
void add_log_listener(LogListener *listener)
Register a log listener to receive log messages.
void write_msg_(const char *msg, uint16_t len)
const char *HOT get_thread_name_()
void dump_config() override
const char * get_thread_name_(TaskHandle_t task)
bool HOT is_non_main_task_recursive_() const
uint32_t get_baud_rate() const
const char *HOT get_thread_name_(std::span< char > buff, k_tid_t current_task=nullptr)
NonMainTaskRecursionGuard make_non_main_task_guard_()
const LogString * get_uart_selection_()
uint8_t level_for(const char *tag)
void HOT format_log_to_buffer_with_terminator_P_(uint8_t level, const char *tag, int line, const __FlashStringHelper *format, va_list args, LogBuffer &buf)
StaticVector< LogListener *, ESPHOME_LOG_MAX_LISTENERS > log_listeners_
Stream * get_hw_serial() const
void log_vprintf_(uint8_t level, const char *tag, int line, const char *format, va_list args)
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)
void create_pthread_key()
void pre_setup()
Set up this component.
void HOT format_buffered_message_and_notify_(uint8_t level, const char *tag, uint16_t line, const char *thread_name, const char *text, uint16_t text_length, LogBuffer &buf)
float get_setup_priority() const override
std::map< const char *, uint8_t, CStrCompare > log_levels_
const char *HOT get_thread_name_(std::span< char > buff)
UARTSelection get_uart() const
Get the UART used by the logger.
std::vector< LoggerLevelListener * > level_listeners_
bool non_main_task_recursion_guard_
void disable_loop_when_buffer_empty_()
void HOT format_log_to_buffer_with_terminator_(uint8_t level, const char *tag, int line, const char *format, va_list args, LogBuffer &buf, const char *thread_name)
pthread_key_t log_recursion_key_
RecursionGuard make_non_main_task_guard_()
void HOT write_log_buffer_to_console_(LogBuffer &buf)
uart_port_t get_uart_num() const
void init_log_buffer(size_t total_buffer_size)
void set_log_level(uint8_t level)
Set the default log level for this logger.
void set_baud_rate(uint32_t baud_rate)
Manually set the baud rate for serial, set to 0 to disable.
void set_uart_selection(UARTSelection uart_selection)
bool global_recursion_guard_
Logger(uint32_t baud_rate, size_t tx_buffer_size)
void HOT write_to_console_(LogBuffer &buf)
void log_vprintf_non_main_thread_(uint8_t level, const char *tag, int line, const char *format, va_list args, const char *thread_name)
bool main_task_recursion_guard_
logger::TaskLogBuffer * log_buffer_
Interface for receiving log level changes without std::function overhead.
virtual void on_log_level_change(uint8_t level)=0
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override
LoggerMessageTrigger(Logger *parent, uint8_t level)
Task log buffer for ESP32 platform using FreeRTOS ring buffer.
UARTSelection
Enum for logging UART selection.
@ UART_SELECTION_UART0_SWAP
@ UART_SELECTION_USB_SERIAL_JTAG
bool operator()(const char *a, const char *b) const
void HOT format_body_P(PGM_P format, va_list args)
void write_body(const char *text, uint16_t text_length)
void HOT write_header(uint8_t level, const char *tag, int line, const char *thread_name)
void HOT format_body(const char *format, va_list args)
void terminate_with_newline()