У меня есть класс регистрации в C ++. Это синглтон с поддержкой многопоточности.
То, чего я хотел достичь (и в основном достиг):
- имеет универсальный c класс регистратора
- синглтон
- используйте его с оператором вставки потока, а не как вызов функции
Класс записывает в std :: stringstream, а в std :: endl сбрасывает содержимое std :: stringstream в файл. Большим недостатком является то, что std :: endl требуется один раз и только один раз за вызов, чтобы все работало правильно в многопоточном приложении. не уверен, что это хороший подход, но пока это нормально, и в моем случае я могу go с этим недостатком
Моя проблема в том, что вызов std :: setfill () при входе в систему тупик. Похоже, этот вызов не отправляется моему классу Logger и выполняется за пределами его критической секции.
Можно ли этого добиться? Класс логгера с полной поддержкой manips?
Журнал вызовов
LOGI << "Some message " << aVariable << std::endl; // OK
LOGI << std::setw(20) << var << std::endl // OK
LOGI << std::setfill('-') << std::setw(50) << var << std::endl; // NOT OK because of setfill() call !!!!
Пример кода класса
#define LOGFATAL Logger::GetLogger(LOGLEVEL_FATAL, __FUNCTION__)
#define LOGE Logger::GetLogger(LOGLEVEL_ERROR, __FUNCTION__)
#define LOGW Logger::GetLogger(LOGLEVEL_WARN, __FUNCTION__)
#define LOGI Logger::GetLogger(LOGLEVEL_INFO, __FUNCTION__)
#define LOGD Logger::GetLogger(LOGLEVEL_DEBUG, __FUNCTION__)
#define LOGV Logger::GetLogger(LOGLEVEL_VERBOSE, __FUNCTION__)
class Logger
{
public:
static void Initialize(const std::string& _logFile, const std::string& _logLevel)
{
isInitialized = true;
logFileName = _logFile;
logLevel = GetLogLevel(_logLevel);
}
static Logger& GetLogger(LogLevel l, const std::string& funcName)
{
if(isInitialized)
csFile->lock();
msgLogLevel = l;
functionName = funcName;
return GetLogger();
}
typedef std::ostream& (*ManipFn)(std::ostream&);
typedef std::ios_base& (*FlagsFn)(std::ios_base&);
template<class T>
Logger& operator<<(const T& output)
{
if (!isInitialized)
return *this;
m_stream << output;
return *this;
}
Logger& operator<<(const ManipFn manip)
{
if (!isInitialized)
return *this;
manip(m_stream);
if (manip == static_cast<ManipFn>(std::flush) ||
manip == static_cast<ManipFn>(std::endl))
{
// flush the stream and unlock the mutex
this->flush();
csFile->unlock();
}
return *this;
}
Logger& operator<<(const FlagsFn manip) /// setiosflags, resetiosflags
{
manip(m_stream);
return *this;
}
...
static Logger& GetLogger()
{
static Logger instance;
return instance;
}
Дайте мне знать, если потребуется дополнительная информация