From ee5fec311c9f6ab2c81a8437e0269cce10fb96ce Mon Sep 17 00:00:00 2001 From: user Date: Tue, 21 Jul 2026 13:44:54 +0400 Subject: [PATCH] feat(logger): add log level filtering --- logger/include/log_level.hpp | 14 ++++++++- logger/include/logger.hpp | 7 ++++- logger/src/logger.cpp | 4 +++ tests/logger/logger_test.cpp | 60 ++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 2 deletions(-) diff --git a/logger/include/log_level.hpp b/logger/include/log_level.hpp index 29b4522..2deb17b 100644 --- a/logger/include/log_level.hpp +++ b/logger/include/log_level.hpp @@ -63,8 +63,20 @@ public: return !(*this == other); } + /** + * @brief Проверяет, является ли текущий уровень менее важным. + * + * Используется для фильтрации сообщений: + * сообщения с уровнем ниже заданного уровня Logger + * не должны записываться в журнал. + */ + [[nodiscard]] + bool operator<(const LogLevel &other) const { + return static_cast(type_) < static_cast(other.type_); + } + private: - enum class Type { Debug, Info, Error }; + enum class Type { Debug = 0, Info = 1, Error = 2 }; explicit LogLevel(Type type) : type_(type) {} diff --git a/logger/include/logger.hpp b/logger/include/logger.hpp index 10c4d27..41db5cb 100644 --- a/logger/include/logger.hpp +++ b/logger/include/logger.hpp @@ -140,7 +140,12 @@ private: std::string fileName_; /** - * @brief Уровень логирования по умолчанию. + * @brief Создаёт объект логгера. + * + * @param fileName Имя файла, в который будут записываться сообщения. + * @param defaultLevel Уровень логирования по умолчанию и минимальный уровень + * важности сообщений, которые будут записываться в + * журнал. */ LogLevel defaultLevel_; }; diff --git a/logger/src/logger.cpp b/logger/src/logger.cpp index 46b5dd6..6b831e1 100644 --- a/logger/src/logger.cpp +++ b/logger/src/logger.cpp @@ -12,6 +12,10 @@ Logger::Logger(const std::string &fileName, LogLevel defaultLevel) Logger::~Logger() = default; core::Status Logger::writeMessage(LogLevel level, const std::string &message) { + if (level < defaultLevel_) { + return core::Status::Success(true); + } + // std::ios::app — режим добавления в конец файла // без удаления уже существующих записей. std::ofstream stream(fileName_, std::ios::app); diff --git a/tests/logger/logger_test.cpp b/tests/logger/logger_test.cpp index 4d9a087..9334fb3 100644 --- a/tests/logger/logger_test.cpp +++ b/tests/logger/logger_test.cpp @@ -109,6 +109,64 @@ void testMultipleWrites() { assert(secondLine.find("second message") != std::string::npos); } +void testIgnoreLowerLogLevel() { + helpers::ScopedFile file("filter.log"); + + file.throwIfExists(); + + Logger logger(file.getFileName(), LogLevel::info()); + + // INFO соответствует минимальному уровню логирования, + // поэтому сообщение должно быть записано в журнал + auto infoResult = logger.writeMessage(LogLevel::info(), "info message"); + + assert(infoResult.isSuccess()); + + // DEBUG имеет более низкий приоритет, чем установленный уровень INFO. + // Сообщение не должно попасть в журнал + auto debugResult = logger.writeMessage(LogLevel::debug(), "debug message"); + + assert(debugResult.isSuccess()); + + std::ifstream input(file.getFileName()); + + assert(input.is_open()); + + std::string firstLine; + std::string secondLine; + + std::getline(input, firstLine); + + assert(firstLine.find("info message") != std::string::npos); + + // Проверяем, что после INFO-сообщения отсутствует DEBUG-сообщение. + bool hasSecondLine = static_cast(std::getline(input, secondLine)); + + assert(!hasSecondLine); +} + +void testWriteMessageWithDefaultLevel() { + helpers::ScopedFile file("default_level.log"); + + file.throwIfExists(); + + Logger logger(file.getFileName(), LogLevel::error()); + + auto result = logger.writeMessage("critical message"); + + assert(result.isSuccess()); + + std::ifstream input(file.getFileName()); + + assert(input.is_open()); + + std::string content; + + std::getline(input, content); + + assert(content.find("critical message") != std::string::npos); +} + void runTests() { testLoggerCreation(); testWithLogLevel(); @@ -116,6 +174,8 @@ void runTests() { testWriteLogSuccess(); testWriteLogFailure(); testMultipleWrites(); + testIgnoreLowerLogLevel(); + testWriteMessageWithDefaultLevel(); } } // namespace logger::tests