Уровень многословия в простой реализации Logger C++
В настоящее время я реализую простой Logger для проекта из-за моего обучения на C++.
У меня уже есть базовый класс Logger, так как есть несколько различных приложений, и следующий шаг - реализация уровней многословия. Проблема в том, что я не уверен, правильно ли я понял концепцию уровней многословия, и поэтому я хотел получить некоторую обратную связь, прежде чем я начну их реализовывать. Так что из моего понимания уровень многословия в целом работает следующим образом:
Пользователь сначала создает два Logger: fe:
FileLogger fl;
VSLogger vl;
после этого он может установить уровень детализации как:
fl.setLoggerLevel(DEBUG);
vl.setLoggerLevel(FATAL_ERROR);
после этого он может войти, как он хочет, например:
fl.logg("New Object of Type .... created");
ASSERT(1,2, "1==2");
в то время как assert пишет в VSLogger с уровнем фатальной ошибки
и в файле Ouput это, вероятно, будет выглядеть так:
13:36 Msg: New Object of Type .... created (LEVEL:DEBUG);
и в Visual Studio это, вероятно, будет выглядеть так:
13:36 Msg: Assert (1==2) failed (LEVEL:FATAL_ERROR)
Это смысл уровня многословия, или я неправильно понял концепции уровня многословия в целом?
2 ответа
Я не понимаю, почему пользователь должен работать с двумя регистраторами. Потребляющий код не должен заботиться о целях регистрации.
Другая проблема заключается в том, что ваш потребительский код не проходит нигде по серьезности. Всякий раз, когда вы вызываете функцию регистрации, вы передаете серьезность. Код потребления не заботится о текущем многословии, он просто передает серьезность и полагается на реализацию средства ведения журнала, чтобы знать, превышает ли серьезность уровень многословия. (Из этого правила есть исключение, когда вы проверяете уровень детализации, чтобы избежать накладных расходов при создании сообщения журнала в высокопроизводительном коде)
Я бы предпочел использовать один регистратор в качестве пользователя с двумя подключенными выходами, которые могут иметь разный уровень детализации.
В простейшем случае я бы создал глобальную функцию Logger& GetLogger()
что приводит к пользовательскому коду, как GetLogger().LogDebug("New Object of Type .... created");
Сначала создайте интерфейс:
public class ILogger
{
public:
virtual LogDebug(string message)=0;
...
}
Затем создайте один экземпляр, который поддерживает подписку:
public class DispatchingLogger:ILogger
{
private:
vector<ILogger*> loggers;
public:
override LogDebug(string message)
{
foreach(ILogger logger in loggers)
{
logger.LogDebug(message);
}
}
void Subscribe(ILogger* logger)
{
loggers.add(logger);
}
}
Тогда глобальный GetLogger()
функция возвращает один экземпляр DispatchingLogger
, И вы можете подписать несколько реализаций с разными уровнями детализации. И пользовательские классы, которые реализуют ILogger
может тоже зарегистрироваться.
(Я знаю, что мой синтаксис C++ неправильный, немного с тех пор, как я работал с C++)
Уровень многословия показывает, какие сообщения (или, скорее, какой критичности) должны быть зарегистрированы.
Например
Set verbosity to INFO
Log a trace message //the message will not be logged
Log a debug message //the message will not be logged
Log an info message //the message will be logged
Log a warning //the message will be logged
Log an error or a fatal error. // will be logged