feat(logger): add log level filtering
This commit is contained in:
@@ -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) {}
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,12 @@ private:
|
|||||||
std::string fileName_;
|
std::string fileName_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Уровень логирования по умолчанию.
|
* @brief Создаёт объект логгера.
|
||||||
|
*
|
||||||
|
* @param fileName Имя файла, в который будут записываться сообщения.
|
||||||
|
* @param defaultLevel Уровень логирования по умолчанию и минимальный уровень
|
||||||
|
* важности сообщений, которые будут записываться в
|
||||||
|
* журнал.
|
||||||
*/
|
*/
|
||||||
LogLevel defaultLevel_;
|
LogLevel defaultLevel_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user