eis/third_party/dsf/include/drsdkBK/drsdk_log.h

196 lines
5.1 KiB
C++

/**
* Filename drsdk_log.h
* Copyright Shanghai Baosight Software Co., Ltd.
* Description The logging component used internally in dsfapi
*
* Author wuzheqiang
* Version 12/19/2024 wuzheqiang Initial Version
**************************************************************/
#ifndef DRSDK_LOG_H
#define DRSDK_LOG_H
#include "data_types.h"
#include <atomic>
#include <condition_variable>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <mutex>
#include <queue>
#include <sstream>
#include <string>
#include <sys/syscall.h>
#include <thread>
#include <unistd.h>
namespace dsfapi
{
#define THREAD_ID syscall(SYS_gettid)
#define RESET "\033[0m"
#define RED "\033[31m" /* Red */
#define YELLOW "\033[33m" /* Yellow */
enum LogLevel : uint8
{
DEBUG,
INFO,
ERROR,
log_level_max
};
static std::map<LogLevel, std::string> g_LogLevelStr = {
{LogLevel::DEBUG, "DEBUG"},
{LogLevel::INFO, "INFO"},
{LogLevel::ERROR, "ERROR"},
};
enum OutputMethod : uint8
{
NONE = 0x00, // 0b00000000
TERMINAL = 0x01, // 0b00000001
FILE = 0x02, // 0b00000010
BOTH = 0x03, // 0b00000011
output_method_max
};
inline std::string CurrentTimestampMicro(int type = 0)
{
using namespace std::chrono;
auto now = system_clock::now();
auto in_time_t = system_clock::to_time_t(now);
auto us = duration_cast<microseconds>(now.time_since_epoch()) % 1000000;
std::tm buf;
localtime_r(&in_time_t, &buf);
std::ostringstream oss;
switch (type)
{
case 0: {
char timeStr[100] = {};
std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &buf);
oss << timeStr;
oss << '.' << std::setfill('0') << std::setw(6) << us.count();
break;
}
case 1: {
char timeStr[100] = {};
std::strftime(timeStr, sizeof(timeStr), "%Y%m%d%H%M%S", &buf);
oss << timeStr;
break;
}
default: {
char timeStr[100] = {};
std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &buf);
oss << timeStr;
break;
}
}
return oss.str();
}
struct LogMessage
{
LogLevel level = LogLevel::INFO;
std::string message = "";
};
class Logger
{
public:
~Logger();
int32 Init(const LogLevel eLogLevel, const OutputMethod eOutPutMethod, const std::string &strLogPath = "");
LogLevel GetLogLevel() const;
void EnqueueMsg(const std::shared_ptr<LogMessage> &pLogMessage);
void Stop();
static Logger &GetInstance()
{
static Logger instance;
return instance;
}
private:
Logger() = default;
void LogWorker();
private:
std::queue<std::shared_ptr<LogMessage>> m_CacheQueue;
std::mutex m_CacheQueueMutex;
std::condition_variable m_CacheQueueCV;
std::unique_ptr<std::thread> m_OutputThread = nullptr;
std::atomic<bool> m_bStopFlag = {false};
std::atomic<bool> m_bInitFlag = {false};
OutputMethod m_OutputMethod = OutputMethod::TERMINAL;
std::ofstream m_LogStream;
std::string m_strLogFile = "";
LogLevel m_LogLevel = LogLevel::INFO;
};
class LogStream
{
public:
LogStream(LogLevel loglevel, const char *filename, const char *funcname, uint32 line)
: m_LogLevel(loglevel), m_nLine(line)
{
m_sFileName = std::string(filename).substr(std::string(filename).find_last_of("/\\") + 1);
m_sFuncName = std::string(funcname);
m_sBuffer.clear();
m_SdkLogLevel = Logger::GetInstance().GetLogLevel();
}
~LogStream()
{
if (!m_sBuffer.str().empty())
{
std::ostringstream sFormatBuffer;
sFormatBuffer << "[" << dsfapi::CurrentTimestampMicro() << "][" << g_LogLevelStr[m_LogLevel] << "]["
<< THREAD_ID << "][" << m_sFileName << ":" << m_nLine << ":" << m_sFuncName << "]"
<< m_sBuffer.str();
std::shared_ptr<LogMessage> pLogMessage = std::make_shared<LogMessage>();
pLogMessage->level = m_LogLevel;
pLogMessage->message = sFormatBuffer.str();
Logger::GetInstance().EnqueueMsg(pLogMessage);
}
}
template <typename T> LogStream &operator<<(const T &msg)
{
if (m_LogLevel >= m_SdkLogLevel)
{
m_sBuffer << msg;
}
return *this;
}
// for std::endl,std::flush
LogStream &operator<<(std::ostream &(*pf)(std::ostream &))
{
if (m_LogLevel >= m_SdkLogLevel)
{
// Not processing; When the final output , std::endl will be added;
// pf(m_sBuffer);
}
return *this;
}
private:
LogLevel m_LogLevel = LogLevel::INFO;
std::string m_sFileName = "";
std::string m_sFuncName = "";
uint32 m_nLine = 0;
std::ostringstream m_sBuffer;
LogLevel m_SdkLogLevel = LogLevel::INFO;
};
#define LOG_DEBUG dsfapi::LogStream(dsfapi::LogLevel::DEBUG, __FILE__, __func__, __LINE__)
#define LOG_INFO dsfapi::LogStream(dsfapi::LogLevel::INFO, __FILE__, __func__, __LINE__)
#define LOG_ERR dsfapi::LogStream(dsfapi::LogLevel::ERROR, __FILE__, __func__, __LINE__)
} // namespace dsfapi
#endif // DRSDK_LOG_H