feat(logger): add log level filtering
This commit is contained in:
@@ -63,8 +63,20 @@ public:
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Проверяет, является ли текущий уровень менее важным.
|
||||
*
|
||||
* Используется для фильтрации сообщений:
|
||||
* сообщения с уровнем ниже заданного уровня Logger
|
||||
* не должны записываться в журнал.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool operator<(const LogLevel &other) const {
|
||||
return static_cast<int>(type_) < static_cast<int>(other.type_);
|
||||
}
|
||||
|
||||
private:
|
||||
enum class Type { Debug, Info, Error };
|
||||
enum class Type { Debug = 0, Info = 1, Error = 2 };
|
||||
|
||||
explicit LogLevel(Type type) : type_(type) {}
|
||||
|
||||
|
||||
@@ -140,7 +140,12 @@ private:
|
||||
std::string fileName_;
|
||||
|
||||
/**
|
||||
* @brief Уровень логирования по умолчанию.
|
||||
* @brief Создаёт объект логгера.
|
||||
*
|
||||
* @param fileName Имя файла, в который будут записываться сообщения.
|
||||
* @param defaultLevel Уровень логирования по умолчанию и минимальный уровень
|
||||
* важности сообщений, которые будут записываться в
|
||||
* журнал.
|
||||
*/
|
||||
LogLevel defaultLevel_;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<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() {
|
||||
testLoggerCreation();
|
||||
testWithLogLevel();
|
||||
@@ -116,6 +174,8 @@ void runTests() {
|
||||
testWriteLogSuccess();
|
||||
testWriteLogFailure();
|
||||
testMultipleWrites();
|
||||
testIgnoreLowerLogLevel();
|
||||
testWriteMessageWithDefaultLevel();
|
||||
}
|
||||
|
||||
} // namespace logger::tests
|
||||
|
||||
Reference in New Issue
Block a user