|
/********************************************************************
|
|
* 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__
|