From e8b67a8267b8d19e33bb619ba1bfc9776f2289ce Mon Sep 17 00:00:00 2001 From: Aster Seker Date: Wed, 17 Sep 2025 05:04:33 +0300 Subject: [PATCH 1/2] fix(headers): include config in utils aggregator Ensure pulls configuration macros before enums so the header stays self-contained. --- AGENTS.md | 7 ++ README-RU.md | 20 +++++ README.md | 20 +++++ include/logit_cpp/logit.hpp | 12 +-- .../logit/detail/CompressionWorker.hpp | 2 - include/logit_cpp/logit/detail/LogStream.hpp | 2 - include/logit_cpp/logit/detail/ScopeTimer.hpp | 4 - .../logit_cpp/logit/detail/TaskExecutor.hpp | 2 - .../logit/detail/system_error_macros.hpp | 3 - include/logit_cpp/logit/formatter.hpp | 6 +- include/logit_cpp/logit/log_macros.hpp | 9 ++- include/logit_cpp/logit/loggers.hpp | 12 ++- .../logit/loggers/CrashPosixLogger.hpp | 1 - .../logit/loggers/CrashWindowsLogger.hpp | 1 - .../logit_cpp/logit/loggers/FileLogger.hpp | 4 - include/logit_cpp/logit/utils.hpp | 10 ++- tests/include_formatter_nhr_test.cpp | 18 +++++ tests/include_loggers_nhr_test.cpp | 9 +++ tests/include_only_ilogger_test.cpp | 79 +++++++++++++++++++ tests/include_quickstart_test.cpp | 8 ++ tests/include_utils_nhr_test.cpp | 17 ++++ 21 files changed, 213 insertions(+), 33 deletions(-) create mode 100644 tests/include_formatter_nhr_test.cpp create mode 100644 tests/include_loggers_nhr_test.cpp create mode 100644 tests/include_only_ilogger_test.cpp create mode 100644 tests/include_quickstart_test.cpp create mode 100644 tests/include_utils_nhr_test.cpp diff --git a/AGENTS.md b/AGENTS.md index e923ea7..96e6744 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,6 +17,13 @@ Include a body that describes the change. Keep diffs minimal and focused. Do not refactor or apply style changes beyond the lines you directly touch. +## Include Policy +- Do not use `../` in `#include` directives. +- Within a module (`logit/utils/*`, `logit/formatter/*`, `logit/loggers/*`) only include headers located in the same sub-tree using forward paths (for example `#include "compiler/PatternCompiler.hpp"`). +- Cross-module dependencies must be provided by the nearest umbrella header: include the corresponding aggregator first instead of including a sibling module directly. +- Files under `logit/detail/` may include other detail headers, but must not include public `logit/...` headers. Their public prerequisites must be included by the parent header before they are pulled in. +- Preferred entry points are the self-contained umbrellas in `include/logit_cpp`: ``, ``, ``, and ``. + ## Header naming conventions When adding or renaming headers, follow these rules: diff --git a/README-RU.md b/README-RU.md index 4c80a21..12073c5 100644 --- a/README-RU.md +++ b/README-RU.md @@ -11,6 +11,26 @@ - **Гибкое форматирование и маршрутизация.** Настраивайте шаблоны формата, комбинируйте консольные/файловые/системные бэкенды или подключайте собственные реализации логгеров. - **Асинхронность по умолчанию.** Каждый бэкенд обслуживается исполнителем задач с настраиваемыми размерами очереди и политиками переполнения, а макросы вроде `LOGIT_WARN_ONCE` или `LOGIT_ERROR_THROTTLE` помогают упорядочить повторяющиеся сообщения. +## Структура заголовков + +Библиотека включает несколько самодостаточных «зонтичных» заголовков, которые подготавливают зависимости в правильном порядке: + +| Точка входа | Назначение | +|-------------|------------| +| `` | Подключает конфигурацию, перечисления, утилиты, форматтеры, все логгеры, синглтон `Logger` и публичные макросы. | +| `` | Собирает модуль `logit/utils/`, включая `LogRecord`, утилиты форматирования и работы с аргументами. | +| `` | Предоставляет интерфейсы форматтеров и стандартный компилятор паттернов. | +| `` | Экспортирует готовые бэкенды логгеров и подготавливает их внутренние зависимости. | + +Листовые заголовки используют правило **NHR (Nearest Header Requirement)**: сначала подключите соответствующий зонтик, затем конкретный файл, например: + +```cpp +#include +#include +``` + +Внутренние файлы из `logit/detail/` предназначены только для реализации и не должны подключаться напрямую пользователями. + Ниже приведены примеры макросов; также загляните в каталог `examples/` с отдельными сценариями, включая настройку очереди и обработку аварийного завершения. ## Примеры макросов diff --git a/README.md b/README.md index 2d18371..a898a23 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,26 @@ Key characteristics: - **Flexible formatting and routing.** Customize output patterns, mix console/file/system backends, or supply custom logger implementations. - **Async by default.** Each backend is served by the task executor with configurable queue sizes and overflow policies, plus helpers such as `LOGIT_WARN_ONCE` or `LOGIT_ERROR_THROTTLE` to keep repeated messages under control. +## Header layout + +The library ships with self-contained umbrella headers that provide a predictable include order: + +| Entry point | Purpose | +|-------------|---------| +| `` | Brings in configuration macros, enums, utilities, formatters, loggers, the singleton `Logger` and public macros. | +| `` | Aggregates everything in `logit/utils/`, including `LogRecord`, formatting helpers and argument utilities. | +| `` | Provides formatter interfaces and the default pattern compiler implementation. | +| `` | Exposes the logger backends and prepares their internal dependencies. | + +Leaf headers follow the **Nearest Header Requirement (NHR)**: include the matching umbrella *first* and then the specific header you need, e.g. + +```cpp +#include +#include +``` + +Internal headers under `logit/detail/` are private implementation details and should not be included directly by consumers. + See the macro examples below or browse the `examples/` folder for focused demonstrations, including queue tuning and crash handling. ## Macro Examples diff --git a/include/logit_cpp/logit.hpp b/include/logit_cpp/logit.hpp index 5a16098..6fb77fd 100644 --- a/include/logit_cpp/logit.hpp +++ b/include/logit_cpp/logit.hpp @@ -3,17 +3,19 @@ #define LOGIT_CPP_LOGIT_HPP /// \file logit.hpp -/// \brief Main header file for the LogIt++ library. +/// \brief Unified umbrella header for the LogIt++ library. +/// +/// Including this header provides a fully self-contained entry point that +/// aggregates configuration, utilities, formatters, loggers and the logging +/// façade. No additional includes are required to start using the library. #include "logit/config.hpp" #include "logit/enums.hpp" #include "logit/utils.hpp" -#include "logit/Logger.hpp" -#include "logit/detail/LogStream.hpp" -#include "logit/detail/ScopeTimer.hpp" -#include "logit/log_macros.hpp" #include "logit/formatter.hpp" #include "logit/loggers.hpp" +#include "logit/Logger.hpp" +#include "logit/log_macros.hpp" /// \namespace logit /// \brief The primary namespace for the LogIt++ library. diff --git a/include/logit_cpp/logit/detail/CompressionWorker.hpp b/include/logit_cpp/logit/detail/CompressionWorker.hpp index 7aa9621..81fcdfe 100644 --- a/include/logit_cpp/logit/detail/CompressionWorker.hpp +++ b/include/logit_cpp/logit/detail/CompressionWorker.hpp @@ -21,8 +21,6 @@ # include #endif -#include "../enums.hpp" - namespace logit { namespace detail { /// \brief Compress a file using the specified compression type. diff --git a/include/logit_cpp/logit/detail/LogStream.hpp b/include/logit_cpp/logit/detail/LogStream.hpp index 965f613..d54a592 100644 --- a/include/logit_cpp/logit/detail/LogStream.hpp +++ b/include/logit_cpp/logit/detail/LogStream.hpp @@ -6,8 +6,6 @@ /// \brief Defines the LogStream class for stream-like logging functionality. #include -#include "../Logger.hpp" -#include "../utils/path_utils.hpp" namespace logit { diff --git a/include/logit_cpp/logit/detail/ScopeTimer.hpp b/include/logit_cpp/logit/detail/ScopeTimer.hpp index b370777..db6d778 100644 --- a/include/logit_cpp/logit/detail/ScopeTimer.hpp +++ b/include/logit_cpp/logit/detail/ScopeTimer.hpp @@ -5,10 +5,6 @@ /// \file ScopeTimer.hpp /// \brief RAII timer that logs the duration of a scope. -#include "../config.hpp" -#include "../utils.hpp" -#include "../Logger.hpp" - #include #include diff --git a/include/logit_cpp/logit/detail/TaskExecutor.hpp b/include/logit_cpp/logit/detail/TaskExecutor.hpp index 74280d3..fd53cb4 100644 --- a/include/logit_cpp/logit/detail/TaskExecutor.hpp +++ b/include/logit_cpp/logit/detail/TaskExecutor.hpp @@ -5,8 +5,6 @@ /// \file TaskExecutor.hpp /// \brief Defines the TaskExecutor class, which manages task execution in a separate thread. -#include "../config.hpp" - #include #include #if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__) diff --git a/include/logit_cpp/logit/detail/system_error_macros.hpp b/include/logit_cpp/logit/detail/system_error_macros.hpp index 9d25a09..2799984 100644 --- a/include/logit_cpp/logit/detail/system_error_macros.hpp +++ b/include/logit_cpp/logit/detail/system_error_macros.hpp @@ -9,9 +9,6 @@ /// \file system_error_macros.hpp /// \brief Internal helpers shared by the system error logging macros. -#include "../config.hpp" -#include "../utils/format.hpp" - #if defined(_WIN32) #include #endif diff --git a/include/logit_cpp/logit/formatter.hpp b/include/logit_cpp/logit/formatter.hpp index cfc1d10..46d0fd8 100644 --- a/include/logit_cpp/logit/formatter.hpp +++ b/include/logit_cpp/logit/formatter.hpp @@ -3,8 +3,12 @@ #define _LOGIT_FORMATTER_HPP_INCLUDED /// \file formatter.hpp -/// \brief Aggregates all formatter components for convenient inclusion. +/// \brief Aggregates the formatter subsystem for convenient inclusion. +/// +/// This header is self-contained and pulls in the generic formatter interface alongside the +/// default implementations and pattern compiler support utilities. +#include "utils.hpp" #include "formatter/ILogFormatter.hpp" #include "formatter/SimpleLogFormatter.hpp" #include "formatter/compiler/PatternCompiler.hpp" diff --git a/include/logit_cpp/logit/log_macros.hpp b/include/logit_cpp/logit/log_macros.hpp index 77cae6b..9e4e1b2 100644 --- a/include/logit_cpp/logit/log_macros.hpp +++ b/include/logit_cpp/logit/log_macros.hpp @@ -7,7 +7,12 @@ #endif #include "config.hpp" -#include "utils/format.hpp" +#include "utils.hpp" +#include "Logger.hpp" + +#include "detail/LogStream.hpp" +#include "detail/ScopeTimer.hpp" +#include "detail/system_error_macros.hpp" /// \file log_macros.hpp /// \brief Provides various logging macros for different log levels and options. @@ -71,8 +76,6 @@ static_assert(LOGIT_LEVEL_FATAL == static_cast(logit::LogLevel::LOG_LVL_FAT //------------------------------------------------------------------------------ // System error logging helpers -#include "detail/system_error_macros.hpp" - //------------------------------------------------------------------------------ // Platform-specific error logging macros diff --git a/include/logit_cpp/logit/loggers.hpp b/include/logit_cpp/logit/loggers.hpp index 98192fb..51bda94 100644 --- a/include/logit_cpp/logit/loggers.hpp +++ b/include/logit_cpp/logit/loggers.hpp @@ -3,9 +3,19 @@ #define _LOGIT_LOGGERS_HPP_INCLUDED /// \file loggers.hpp -/// \brief Aggregates all logger implementations for convenient inclusion. +/// \brief Aggregates all public logger backends. +/// +/// This header is self-contained: it prepares common configuration, utility and detail +/// dependencies before including each backend implementation. Include it prior to including +/// any header under `loggers/` to satisfy the nearest-header requirement. +#include "config.hpp" +#include "utils.hpp" #include "detail/TaskExecutor.hpp" +#ifndef __EMSCRIPTEN__ +#include "detail/CompressionWorker.hpp" +#endif + #include "loggers/ILogger.hpp" #include "loggers/ConsoleLogger.hpp" #include "loggers/FileLogger.hpp" diff --git a/include/logit_cpp/logit/loggers/CrashPosixLogger.hpp b/include/logit_cpp/logit/loggers/CrashPosixLogger.hpp index 9f1494e..be78d64 100644 --- a/include/logit_cpp/logit/loggers/CrashPosixLogger.hpp +++ b/include/logit_cpp/logit/loggers/CrashPosixLogger.hpp @@ -6,7 +6,6 @@ /// \brief POSIX crash logger persisting the last messages to a file descriptor. #include "ILogger.hpp" -#include "../utils.hpp" #include #include diff --git a/include/logit_cpp/logit/loggers/CrashWindowsLogger.hpp b/include/logit_cpp/logit/loggers/CrashWindowsLogger.hpp index 5fbc8ca..9f5bc6d 100644 --- a/include/logit_cpp/logit/loggers/CrashWindowsLogger.hpp +++ b/include/logit_cpp/logit/loggers/CrashWindowsLogger.hpp @@ -6,7 +6,6 @@ /// \\brief Windows crash logger persisting the last messages to a file handle. #include "ILogger.hpp" -#include "../utils.hpp" #include #include diff --git a/include/logit_cpp/logit/loggers/FileLogger.hpp b/include/logit_cpp/logit/loggers/FileLogger.hpp index 42d5d6b..9c27fa3 100644 --- a/include/logit_cpp/logit/loggers/FileLogger.hpp +++ b/include/logit_cpp/logit/loggers/FileLogger.hpp @@ -6,10 +6,6 @@ /// \brief File logger implementation that outputs logs to files with rotation and deletion of old logs. #include "ILogger.hpp" -#include "../enums.hpp" -#ifndef __EMSCRIPTEN__ -#include "../detail/CompressionWorker.hpp" -#endif #include #include #include diff --git a/include/logit_cpp/logit/utils.hpp b/include/logit_cpp/logit/utils.hpp index 9bbe60c..4887611 100644 --- a/include/logit_cpp/logit/utils.hpp +++ b/include/logit_cpp/logit/utils.hpp @@ -3,12 +3,14 @@ #define _LOGIT_UTILS_HPP_INCLUDED /// \file utils.hpp -/// \brief Aggregates various utility modules used throughout the project. +/// \brief Aggregates the public utilities module. /// -/// This header includes modules for formatting, handling variable values, argument parsing, -/// encoding utilities, path utilities, and log record management. Including this header -/// provides a single point of access to common utility functions and types. +/// This header is a self-contained entry point that exposes all utility components required +/// by the library: configuration macros, enums, formatting helpers, value wrappers and the +/// log record type. Include +/// it before any header inside `utils/` to satisfy the nearest-header requirement. +#include "config.hpp" #include "enums.hpp" #include "utils/format.hpp" #include "utils/VariableValue.hpp" diff --git a/tests/include_formatter_nhr_test.cpp b/tests/include_formatter_nhr_test.cpp new file mode 100644 index 0000000..2070d9d --- /dev/null +++ b/tests/include_formatter_nhr_test.cpp @@ -0,0 +1,18 @@ +#include +#include + +int main() { + logit::SimpleLogFormatter formatter; + logit::LogRecord record( + logit::LogLevel::LOG_LVL_INFO, + 123, + __FILE__, + __LINE__, + __func__, + "format", + "", + -1, + false); + const std::string formatted = formatter.format(record); + return formatted.empty() ? 1 : 0; +} diff --git a/tests/include_loggers_nhr_test.cpp b/tests/include_loggers_nhr_test.cpp new file mode 100644 index 0000000..4002c8d --- /dev/null +++ b/tests/include_loggers_nhr_test.cpp @@ -0,0 +1,9 @@ +#include +#include + +int main() { + logit::ConsoleLogger logger(false); + logger.set_log_level(logit::LogLevel::LOG_LVL_WARN); + logger.wait(); + return 0; +} diff --git a/tests/include_only_ilogger_test.cpp b/tests/include_only_ilogger_test.cpp new file mode 100644 index 0000000..c5f7d83 --- /dev/null +++ b/tests/include_only_ilogger_test.cpp @@ -0,0 +1,79 @@ +#include +#include + +namespace { +class CountingLogger final : public logit::ILogger { +public: + void log(const logit::LogRecord& record, const std::string& message) override { + ++m_count; + m_last_message = message; + m_last_timestamp = record.timestamp_ms; + m_last_file = record.file; + } + + std::string get_string_param(const logit::LoggerParam& param) const override { + switch (param) { + case logit::LoggerParam::LastFileName: + return m_last_file; + case logit::LoggerParam::LastFilePath: + return m_last_file; + case logit::LoggerParam::LastLogTimestamp: + case logit::LoggerParam::TimeSinceLastLog: + return {}; + } + return {}; + } + + int64_t get_int_param(const logit::LoggerParam& param) const override { + switch (param) { + case logit::LoggerParam::LastLogTimestamp: + return m_last_timestamp; + case logit::LoggerParam::TimeSinceLastLog: + return 0; + case logit::LoggerParam::LastFileName: + case logit::LoggerParam::LastFilePath: + return static_cast(m_count); + } + return 0; + } + + double get_float_param(const logit::LoggerParam&) const override { return 0.0; } + + void set_log_level(logit::LogLevel level) override { m_level = level; } + + logit::LogLevel get_log_level() const override { return m_level; } + + void wait() override {} + + int count() const { return m_count; } + const std::string& last_message() const { return m_last_message; } + +private: + logit::LogLevel m_level = logit::LogLevel::LOG_LVL_TRACE; + int m_count = 0; + std::string m_last_message; + std::string m_last_file; + int64_t m_last_timestamp = 0; +}; +} // namespace + +int main() { + CountingLogger logger; + logger.set_log_level(logit::LogLevel::LOG_LVL_INFO); + + logit::LogRecord record( + logit::LogLevel::LOG_LVL_INFO, + 42, + __FILE__, + __LINE__, + __func__, + "message", + "", + -1, + false); + + logger.log(record, "from test"); + logger.wait(); + + return (logger.count() > 0 && !logger.last_message().empty()) ? 0 : 1; +} diff --git a/tests/include_quickstart_test.cpp b/tests/include_quickstart_test.cpp new file mode 100644 index 0000000..363792c --- /dev/null +++ b/tests/include_quickstart_test.cpp @@ -0,0 +1,8 @@ +#include + +int main() { + LOGIT_ADD_CONSOLE_DEFAULT(); + LOGIT_INFO("quickstart include works"); + LOGIT_WAIT(); + return 0; +} diff --git a/tests/include_utils_nhr_test.cpp b/tests/include_utils_nhr_test.cpp new file mode 100644 index 0000000..f41ddf3 --- /dev/null +++ b/tests/include_utils_nhr_test.cpp @@ -0,0 +1,17 @@ +#include +#include + +int main() { + logit::LogRecord record( + logit::LogLevel::LOG_LVL_DEBUG, + 0, + __FILE__, + __LINE__, + __func__, + "%s", + "", + -1, + true); + record.args_array.emplace_back(42); + return record.logger_index == -1 ? 0 : 1; +} From 9e92237fc1768cd2ce7139b912318192951bda4b Mon Sep 17 00:00:00 2001 From: Aster Seker Date: Wed, 17 Sep 2025 05:33:59 +0300 Subject: [PATCH 2/2] fix(tests): name variable value in utils nhr Provide an argument name when emplacing into LogRecord args_array so the VariableValue constructor matches and the self-contained include test builds on GCC and Clang. --- tests/include_utils_nhr_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/include_utils_nhr_test.cpp b/tests/include_utils_nhr_test.cpp index f41ddf3..57e881f 100644 --- a/tests/include_utils_nhr_test.cpp +++ b/tests/include_utils_nhr_test.cpp @@ -12,6 +12,6 @@ int main() { "", -1, true); - record.args_array.emplace_back(42); + record.args_array.emplace_back("answer", 42); return record.logger_index == -1 ? 0 : 1; }