root/src/Logger.h @ 2c54c4c3
| 2c54c4c3 | david.sorber | /********************************************************************
|
|
* CONFIDENTIAL - All source code is the propriety and confidential *
|
|||
* information of David Sorber. *
|
|||
* *
|
|||
* Copyright 2024 David Sorber *
|
|||
* Unpublished -- all rights reserved under the copyright laws *
|
|||
* of the United States. *
|
|||
********************************************************************/
|
|||
#ifndef __LOGGER__
|
|||
#define __LOGGER__
|
|||
#include <cstring>
|
|||
#include <iostream>
|
|||
#include <fstream>
|
|||
#include <string>
|
|||
#include <sstream>
|
|||
#include <mutex>
|
|||
#include <sys/time.h>
|
|||
#include "CopyManagerOptions.h"
|
|||
// Defined outside of namespace just for convenience.
|
|||
// NOTE: when using >= C++14 and >= -O1 the following function will be executed
|
|||
// at compile time. This avoids the need for the previous CMake path length trick.
|
|||
inline constexpr size_t PATH_OFFSET(const char* input)
|
|||
{
|
|||
// OTHER NOTE: this assumes truncating the file path after the "lib/"
|
|||
// portion which is currently valid for LH source tree organization.
|
|||
const char* output = std::strstr(input, "src/");
|
|||
if (output == nullptr)
|
|||
{
|
|||
return 0;
|
|||
}
|
|||
return (output - input) + 4;
|
|||
}
|
|||
namespace DBS
|
|||
{
|
|||
// Enumeration representing the log severity levels
|
|||
enum LOG_LEVEL {off=-1, error=0, warn=1, info=2, debug=3, trace=4};
|
|||
// Regular BlnxLog definition, goes to the log file
|
|||
#define BlnxLog(sev) BlackLynx::Lighthouse::Logger::getInstance(sev).internalLog() \
|
|||
<< &(__FILE__[PATH_OFFSET(__FILE__)]) << ":" << __LINE__ << "|"
|
|||
class Logger
|
|||
{
|
|||
public:
|
|||
/**
|
|||
* Logger Destructor
|
|||
*/
|
|||
~Logger();
|
|||
/**
|
|||
* Get the singleton instance
|
|||
*/
|
|||
static Logger& getInstance(
|
|||
enum LOG_LEVEL sev,
|
|||
CopyManagerOptions* configObj=nullptr)
|
|||
{
|
|||
static Logger instance(configObj);
|
|||
if (sev >= 0)
|
|||
{
|
|||
// Lock our mutex and set the severity level
|
|||
instance.lockMutex();
|
|||
instance.setSeverity(sev);
|
|||
}
|
|||
return instance;
|
|||
};
|
|||
/**
|
|||
* Nested class used to get around the "endl" tag, it automatically
|
|||
* handles the "cleanup" at the end of the log message stream in the
|
|||
* destructor
|
|||
*/
|
|||
class InternalLogger
|
|||
{
|
|||
public:
|
|||
InternalLogger(enum LOG_LEVEL severity, Logger &outer)
|
|||
: m_internalSev(severity),
|
|||
r_outerLogger(outer)
|
|||
{
|
|||
}
|
|||
InternalLogger(const InternalLogger &other)
|
|||
: m_internalSev(other.m_internalSev),
|
|||
r_outerLogger(other.r_outerLogger)
|
|||
{
|
|||
}
|
|||
~InternalLogger()
|
|||
{
|
|||
std::string str = m_internalMsgStream.str();
|
|||
if (! str.empty())
|
|||
{
|
|||
r_outerLogger.log_msg(m_internalSev, str);
|
|||
// Clean the output stream for future logging
|
|||
m_internalMsgStream.str("");
|
|||
}
|
|||
// Make sure we unlock!
|
|||
r_outerLogger.unlockMutex();
|
|||
}
|
|||
/**
|
|||
* Overriding the insertion operator to build log message
|
|||
*/
|
|||
template<typename T>
|
|||
InternalLogger& operator<< (const T& msg)
|
|||
{
|
|||
m_internalMsgStream << msg;
|
|||
return *this;
|
|||
}
|
|||
private:
|
|||
enum LOG_LEVEL m_internalSev;
|
|||
Logger& r_outerLogger;
|
|||
std::stringstream m_internalMsgStream;
|
|||
};
|
|||
InternalLogger internalLog()
|
|||
{
|
|||
return InternalLogger(m_severity, *this);
|
|||
}
|
|||
private:
|
|||
/**
|
|||
* Private constructor (singleton)
|
|||
*/
|
|||
Logger(CopyManagerOptions* configObj);
|
|||
/**
|
|||
* Set the log severity level
|
|||
*/
|
|||
void setSeverity(enum LOG_LEVEL sev)
|
|||
{
|
|||
m_severity = sev;
|
|||
}
|
|||
/**
|
|||
* Lock the internal mutex
|
|||
*/
|
|||
void lockMutex()
|
|||
{
|
|||
m_rloggerMutex.lock();
|
|||
}
|
|||
/**
|
|||
* Unlock the internal mutex
|
|||
*/
|
|||
void unlockMutex()
|
|||
{
|
|||
m_rloggerMutex.unlock();
|
|||
}
|
|||
/**
|
|||
* Write a log message to the log file.
|
|||
*
|
|||
* @param level - the severity of the message being logged
|
|||
* @param message - the message to send
|
|||
*/
|
|||
void log_msg(enum LOG_LEVEL level, const std::string& msg);
|
|||
//--------------------------------------------------------------------------
|
|||
/**
|
|||
* The log message to write
|
|||
*/
|
|||
std::ostringstream m_outputStream;
|
|||
/**
|
|||
* Severity level of the log message
|
|||
*/
|
|||
enum LOG_LEVEL m_severity;
|
|||
/**
|
|||
* Mutex for making this singleton thread-safe
|
|||
*/
|
|||
std::mutex m_rloggerMutex;
|
|||
std::ofstream m_logFile;
|
|||
CopyManagerOptions& r_options;
|
|||
};
|
|||
} // DBS
|
|||
#endif // __LOGGER__
|