From 88b3bfbe3e7e2741dfd2a3207b70e904fe725108 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Thu, 6 Feb 2025 22:55:51 +0100 Subject: [PATCH] Logging improvements and C++23 (#206) - Improved logging code by splitting functionality up into different files - Set C++23 as new standard (it was already the implied standard due to some code, but now it's explicit) --- CMakeLists.txt | 2 +- Libraries/lv_screenshot/CMakeLists.txt | 2 +- Tactility/CMakeLists.txt | 2 +- TactilityC/CMakeLists.txt | 2 +- TactilityCore/CMakeLists.txt | 2 +- TactilityCore/Include/Tactility/Log.h | 60 ++-------- TactilityCore/Include/Tactility/LogCommon.h | 15 +++ TactilityCore/Include/Tactility/LogEsp.h | 18 +++ .../Include/Tactility/LogSimulator.h | 27 +++++ TactilityCore/Source/Log.cpp | 107 +----------------- TactilityCore/Source/LogEsp.cpp | 24 ++++ TactilityCore/Source/LogSimulator.cpp | 76 +++++++++++++ TactilityHeadless/CMakeLists.txt | 2 +- 13 files changed, 175 insertions(+), 164 deletions(-) create mode 100644 TactilityCore/Include/Tactility/LogCommon.h create mode 100644 TactilityCore/Include/Tactility/LogEsp.h create mode 100644 TactilityCore/Include/Tactility/LogSimulator.h create mode 100644 TactilityCore/Source/LogEsp.cpp create mode 100644 TactilityCore/Source/LogSimulator.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dde496e7..01c35fbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.20) add_definitions(-DTT_DEBUG) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_ASM_COMPILE_OBJECT "${CMAKE_CXX_COMPILER_TARGET}") diff --git a/Libraries/lv_screenshot/CMakeLists.txt b/Libraries/lv_screenshot/CMakeLists.txt index cc7c6998..d6c43221 100644 --- a/Libraries/lv_screenshot/CMakeLists.txt +++ b/Libraries/lv_screenshot/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/Tactility/CMakeLists.txt b/Tactility/CMakeLists.txt index 2ee287ac..ccd4898b 100644 --- a/Tactility/CMakeLists.txt +++ b/Tactility/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) if (DEFINED ENV{ESP_IDF_VERSION}) diff --git a/TactilityC/CMakeLists.txt b/TactilityC/CMakeLists.txt index 0f25f677..75648ae3 100644 --- a/TactilityC/CMakeLists.txt +++ b/TactilityC/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) if (DEFINED ENV{ESP_IDF_VERSION}) diff --git a/TactilityCore/CMakeLists.txt b/TactilityCore/CMakeLists.txt index d6fcfe97..fad358b3 100644 --- a/TactilityCore/CMakeLists.txt +++ b/TactilityCore/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) if (DEFINED ENV{ESP_IDF_VERSION}) diff --git a/TactilityCore/Include/Tactility/Log.h b/TactilityCore/Include/Tactility/Log.h index 3eeef134..54ae528e 100644 --- a/TactilityCore/Include/Tactility/Log.h +++ b/TactilityCore/Include/Tactility/Log.h @@ -4,13 +4,6 @@ #include #include -#ifdef ESP_PLATFORM -#include -#else -#include -#include -#endif - #if not defined(ESP_PLATFORM) or (defined(CONFIG_SPIRAM_USE_MALLOC) && CONFIG_SPIRAM_USE_MALLOC == 1) #define TT_LOG_ENTRY_COUNT 200 #define TT_LOG_MESSAGE_SIZE 128 @@ -19,17 +12,15 @@ #define TT_LOG_MESSAGE_SIZE 50 #endif -namespace tt { +#ifdef ESP_PLATFORM +#include "LogEsp.h" +#else +#include "LogSimulator.h" +#endif -/** Used for log output filtering */ -enum class LogLevel { - None, /*!< No log output */ - Error, /*!< Critical errors, software module can not recover on its own */ - Warning, /*!< Error conditions from which recovery measures have been taken */ - Info, /*!< Information messages which describe normal flow of events */ - Debug, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */ - Verbose /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */ -}; +#include "LogCommon.h" + +namespace tt { struct LogEntry { LogLevel level = LogLevel::None; @@ -43,38 +34,3 @@ struct LogEntry { std::unique_ptr> copyLogEntries(std::size_t& outIndex); } // namespace tt - - -#ifdef ESP_PLATFORM - -#define TT_LOG_E(tag, format, ...) \ - ESP_LOGE(tag, format, ##__VA_ARGS__) -#define TT_LOG_W(tag, format, ...) \ - ESP_LOGW(tag, format, ##__VA_ARGS__) -#define TT_LOG_I(tag, format, ...) \ - ESP_LOGI(tag, format, ##__VA_ARGS__) -#define TT_LOG_D(tag, format, ...) \ - ESP_LOGD(tag, format, ##__VA_ARGS__) -#define TT_LOG_V(tag, format, ...) \ - ESP_LOGV(tag, format, ##__VA_ARGS__) - -#else - -namespace tt { - -void log(LogLevel level, const char* tag, const char* format, ...); - -} // namespace - -#define TT_LOG_E(tag, format, ...) \ - tt::log(tt::LogLevel::Error, tag, format, ##__VA_ARGS__) -#define TT_LOG_W(tag, format, ...) \ - tt::log(tt::LogLevel::Warning, tag, format, ##__VA_ARGS__) -#define TT_LOG_I(tag, format, ...) \ - tt::log(tt::LogLevel::Info, tag, format, ##__VA_ARGS__) -#define TT_LOG_D(tag, format, ...) \ - tt::log(tt::LogLevel::Debug, tag, format, ##__VA_ARGS__) -#define TT_LOG_V(tag, format, ...) \ - tt::log(tt::LogLevel::Trace, tag, format, ##__VA_ARGS__) - -#endif // ESP_PLATFORM diff --git a/TactilityCore/Include/Tactility/LogCommon.h b/TactilityCore/Include/Tactility/LogCommon.h new file mode 100644 index 00000000..71fd40a0 --- /dev/null +++ b/TactilityCore/Include/Tactility/LogCommon.h @@ -0,0 +1,15 @@ +#pragma once + +namespace tt { + +/** Used for log output filtering */ +enum class LogLevel : int { + None = 0, /*!< No log output */ + Error, /*!< Critical errors, software module can not recover on its own */ + Warning, /*!< Error conditions from which recovery measures have been taken */ + Info, /*!< Information messages which describe normal flow of events */ + Debug, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */ + Verbose /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */ +}; + +} \ No newline at end of file diff --git a/TactilityCore/Include/Tactility/LogEsp.h b/TactilityCore/Include/Tactility/LogEsp.h new file mode 100644 index 00000000..ac0a6e1f --- /dev/null +++ b/TactilityCore/Include/Tactility/LogEsp.h @@ -0,0 +1,18 @@ +#pragma once + +#ifdef ESP_PLATFORM + +#include + +#define TT_LOG_E(tag, format, ...) \ + ESP_LOGE(tag, format, ##__VA_ARGS__) +#define TT_LOG_W(tag, format, ...) \ + ESP_LOGW(tag, format, ##__VA_ARGS__) +#define TT_LOG_I(tag, format, ...) \ + ESP_LOGI(tag, format, ##__VA_ARGS__) +#define TT_LOG_D(tag, format, ...) \ + ESP_LOGD(tag, format, ##__VA_ARGS__) +#define TT_LOG_V(tag, format, ...) \ + ESP_LOGV(tag, format, ##__VA_ARGS__) + +#endif // ESP_PLATFORM diff --git a/TactilityCore/Include/Tactility/LogSimulator.h b/TactilityCore/Include/Tactility/LogSimulator.h new file mode 100644 index 00000000..62aff4e1 --- /dev/null +++ b/TactilityCore/Include/Tactility/LogSimulator.h @@ -0,0 +1,27 @@ +#pragma once + +#ifndef ESP_PLATFORM + +#include "LogCommon.h" + +#include +#include + +namespace tt { + +void log(LogLevel level, const char* tag, const char* format, ...); + +} // namespace + +#define TT_LOG_E(tag, format, ...) \ + tt::log(tt::LogLevel::Error, tag, format, ##__VA_ARGS__) +#define TT_LOG_W(tag, format, ...) \ + tt::log(tt::LogLevel::Warning, tag, format, ##__VA_ARGS__) +#define TT_LOG_I(tag, format, ...) \ + tt::log(tt::LogLevel::Info, tag, format, ##__VA_ARGS__) +#define TT_LOG_D(tag, format, ...) \ + tt::log(tt::LogLevel::Debug, tag, format, ##__VA_ARGS__) +#define TT_LOG_V(tag, format, ...) \ + tt::log(tt::LogLevel::Trace, tag, format, ##__VA_ARGS__) + +#endif // ESP_PLATFORM diff --git a/TactilityCore/Source/Log.cpp b/TactilityCore/Source/Log.cpp index 992f59d8..71c47887 100644 --- a/TactilityCore/Source/Log.cpp +++ b/TactilityCore/Source/Log.cpp @@ -21,7 +21,7 @@ Mutex& getLogMutex() { return *logMutex; } -static void storeLog(LogLevel level, const char* format, va_list args) { +void storeLog(LogLevel level, const char* format, va_list args) { if (getLogMutex().lock(5 / portTICK_PERIOD_MS)) { logEntries[nextLogEntryIndex].level = level; vsnprintf(logEntries[nextLogEntryIndex].message, TT_LOG_MESSAGE_SIZE, format, args); @@ -47,108 +47,3 @@ std::unique_ptr> copyLogEntries(std::si } } // namespace tt - -#ifndef ESP_PLATFORM - -#include "Tactility/Log.h" - -#include -#include -#include - -namespace tt { - -static char toPrefix(LogLevel level) { - switch (level) { - case LogLevel::Error: - return 'E'; - case LogLevel::Warning: - return 'W'; - case LogLevel::Info: - return 'I'; - case LogLevel::Debug: - return 'D'; - case LogLevel::Verbose: - return 'T'; - default: - return '?'; - } -} - -static const char* toColour(LogLevel level) { - switch (level) { - case LogLevel::Error: - return "\033[1;31m"; - case LogLevel::Warning: - return "\033[33m"; - case LogLevel::Info: - return "\033[32m"; - case LogLevel::Debug: - return "\033[1;37m"; - case LogLevel::Verbose: - return "\033[37m"; - default: - return ""; - } -} - -static uint64_t getTimestamp() { -#ifdef ESP_PLATFORM - if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { - return clock() / CLOCKS_PER_SEC * 1000; - } - static uint32_t base = 0; - if (base == 0 && xPortGetCoreID() == 0) { - base = clock() / CLOCKS_PER_SEC * 1000; - } - TickType_t tick_count = xPortInIsrContext() ? xTaskGetTickCountFromISR() : xTaskGetTickCount(); - return base + tick_count * (1000 / configTICK_RATE_HZ); -#else - static uint64_t base = 0; - - struct timeval time {}; - gettimeofday(&time, nullptr); - uint64_t now = ((uint64_t)time.tv_sec * 1000) + (time.tv_usec / 1000); - if (base == 0) { - base = now; - } - return now - base; -#endif -} - -void log(LogLevel level, const char* tag, const char* format, ...) { - std::stringstream buffer; - buffer << toColour(level) << toPrefix(level) << " (" << getTimestamp() << ") " << tag << ": " << format << "\033[0m\n"; - - va_list args; - va_start(args, format); - vprintf(buffer.str().c_str(), args); - va_end(args); - - va_start(args, format); - tt::storeLog(level, buffer.str().c_str(), args); - va_end(args); -} - -} // namespace - -#else // ESP_PLATFORM - -#include - -extern "C" { - -extern void __real_esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...); - -void __wrap_esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...) { - va_list args; - va_start(args, format); - tt::storeLog((tt::LogLevel)level, format, args); - esp_log_writev(level, tag, format, args); - va_end(args); -} - -} - -#endif - diff --git a/TactilityCore/Source/LogEsp.cpp b/TactilityCore/Source/LogEsp.cpp new file mode 100644 index 00000000..0b3c6e93 --- /dev/null +++ b/TactilityCore/Source/LogEsp.cpp @@ -0,0 +1,24 @@ +#ifdef ESP_PLATFORM + +#include "Tactility/LogCommon.h" +#include + +namespace tt { +void storeLog(LogLevel level, const char* format, va_list args); +} + +extern "C" { + +extern void __real_esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...); + +void __wrap_esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...) { + va_list args; + va_start(args, format); + tt::storeLog((tt::LogLevel)level, format, args); + esp_log_writev(level, tag, format, args); + va_end(args); +} + +} + +#endif diff --git a/TactilityCore/Source/LogSimulator.cpp b/TactilityCore/Source/LogSimulator.cpp new file mode 100644 index 00000000..2e63f97b --- /dev/null +++ b/TactilityCore/Source/LogSimulator.cpp @@ -0,0 +1,76 @@ +#ifndef ESP_PLATFORM + +#include "Tactility/Log.h" + +#include +#include +#include + +namespace tt { + +void storeLog(LogLevel level, const char* format, va_list args); + +static char toPrefix(LogLevel level) { + using enum LogLevel; + switch (level) { + case Error: + return 'E'; + case Warning: + return 'W'; + case Info: + return 'I'; + case Debug: + return 'D'; + case Verbose: + return 'T'; + default: + return '?'; + } +} + +static const char* toColour(LogLevel level) { + using enum LogLevel; + switch (level) { + case Error: + return "\033[1;31m"; + case Warning: + return "\033[33m"; + case Info: + return "\033[32m"; + case Debug: + return "\033[1;37m"; + case Verbose: + return "\033[37m"; + default: + return ""; + } +} + +static uint64_t getLogTimestamp() { + static uint64_t base = 0U; + struct timeval time {}; + gettimeofday(&time, nullptr); + uint64_t now = ((uint64_t)time.tv_sec * 1000U) + (time.tv_usec / 1000U); + if (base == 0U) { + base = now; + } + return now - base; +} + +void log(LogLevel level, const char* tag, const char* format, ...) { + std::stringstream buffer; + buffer << toColour(level) << toPrefix(level) << " (" << getLogTimestamp() << ") " << tag << ": " << format << "\033[0m\n"; + + va_list args; + va_start(args, format); + vprintf(buffer.str().c_str(), args); + va_end(args); + + va_start(args, format); + tt::storeLog(level, buffer.str().c_str(), args); + va_end(args); +} + +} // namespace tt + +#endif \ No newline at end of file diff --git a/TactilityHeadless/CMakeLists.txt b/TactilityHeadless/CMakeLists.txt index 8216c2be..92f504ac 100644 --- a/TactilityHeadless/CMakeLists.txt +++ b/TactilityHeadless/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) if (DEFINED ENV{ESP_IDF_VERSION})