feat(logger): add log level filtering

This commit is contained in:
user
2026-07-21 13:44:54 +04:00
parent 4366eeb92e
commit ee5fec311c
4 changed files with 83 additions and 2 deletions
+13 -1
View File
@@ -63,8 +63,20 @@ public:
return !(*this == other); return !(*this == other);
} }
/**
* @brief Проверяет, является ли текущий уровень менее важным.
*
* Используется для фильтрации сообщений:
* сообщения с уровнем ниже заданного уровня Logger
* не должны записываться в журнал.
*/
[[nodiscard]]
bool operator<(const LogLevel &other) const {
return static_cast<int>(type_) < static_cast<int>(other.type_);
}
private: private:
enum class Type { Debug, Info, Error }; enum class Type { Debug = 0, Info = 1, Error = 2 };
explicit LogLevel(Type type) : type_(type) {} explicit LogLevel(Type type) : type_(type) {}
+6 -1
View File
@@ -140,7 +140,12 @@ private:
std::string fileName_; std::string fileName_;
/** /**
* @brief Уровень логирования по умолчанию. * @brief Создаёт объект логгера.
*
* @param fileName Имя файла, в который будут записываться сообщения.
* @param defaultLevel Уровень логирования по умолчанию и минимальный уровень
* важности сообщений, которые будут записываться в
* журнал.
*/ */
LogLevel defaultLevel_; LogLevel defaultLevel_;
}; };
+4
View File
@@ -12,6 +12,10 @@ Logger::Logger(const std::string &fileName, LogLevel defaultLevel)
Logger::~Logger() = default; Logger::~Logger() = default;
core::Status Logger::writeMessage(LogLevel level, const std::string &message) { core::Status Logger::writeMessage(LogLevel level, const std::string &message) {
if (level < defaultLevel_) {
return core::Status::Success(true);
}
// std::ios::app — режим добавления в конец файла // std::ios::app — режим добавления в конец файла
// без удаления уже существующих записей. // без удаления уже существующих записей.
std::ofstream stream(fileName_, std::ios::app); std::ofstream stream(fileName_, std::ios::app);
+60
View File
@@ -109,6 +109,64 @@ void testMultipleWrites() {
assert(secondLine.find("second message") != std::string::npos); 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<bool>(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() { void runTests() {
testLoggerCreation(); testLoggerCreation();
testWithLogLevel(); testWithLogLevel();
@@ -116,6 +174,8 @@ void runTests() {
testWriteLogSuccess(); testWriteLogSuccess();
testWriteLogFailure(); testWriteLogFailure();
testMultipleWrites(); testMultipleWrites();
testIgnoreLowerLogLevel();
testWriteMessageWithDefaultLevel();
} }
} // namespace logger::tests } // namespace logger::tests