JD2022-TU1/main/extern/dtest/dtcore/inc/dtlogger.h

228 lines
8.2 KiB
C++

#pragma once
#include "dtcore/inc/dtstring.h"
#include "dtcore/inc/dtdatetime.h"
#pragma warning(push)
#include <memory>
#pragma warning(pop)
namespace dt
{
class LoggerImpl;
enum class LogLevel
{
Trace,
Debug,
Info,
Success,
Warning,
Error,
Always,
Off
};
class LogContext
{
public:
DT_CORE_DLL_ENTRY LogContext() = default;
DT_CORE_DLL_ENTRY LogContext(const String& key, const String& value, bool visible);
DT_CORE_DLL_ENTRY const String& GetKey() const { return m_Key; }
DT_CORE_DLL_ENTRY const String& GetValue() const { return m_Value; }
DT_CORE_DLL_ENTRY bool IsVisible() const { return m_Visible; }
private:
String m_Key;
String m_Value;
bool m_Visible = false;
};
class LogContexts
{
public:
DT_CORE_DLL_ENTRY LogContexts();
DT_CORE_DLL_ENTRY LogContexts(const Vector<LogContext>& contexts, const LogContexts* parentContexts = nullptr);
DT_CORE_DLL_ENTRY LogContexts(const LogContexts& rhs);
DT_CORE_DLL_ENTRY LogContexts& operator=(const LogContexts& rhs);
DT_CORE_DLL_ENTRY bool operator==(const LogContexts& rhs) const { return m_Snapshot == rhs.m_Snapshot; }
DT_CORE_DLL_ENTRY bool TryGetValue(const String& key, String* value) const;
typedef Vector<LogContext>::ConstIterator ConstIterator;
DT_CORE_DLL_ENTRY ConstIterator Begin() const { return m_Snapshot->Begin(); }
DT_CORE_DLL_ENTRY ConstIterator End() const { return m_Snapshot->End(); }
DT_CORE_DLL_ENTRY ConstIterator begin() const { return m_Snapshot->Begin(); }
DT_CORE_DLL_ENTRY ConstIterator end() const { return m_Snapshot->End(); }
DT_CORE_DLL_ENTRY const LogContext& Back() const { return m_Snapshot->Back(); }
DT_CORE_DLL_ENTRY const LogContext& operator[](SizeT index) const { return (*m_Snapshot)[index]; }
DT_CORE_DLL_ENTRY SizeT Size() const { return m_Snapshot->Size(); }
DT_CORE_DLL_ENTRY bool Empty() const { return m_Snapshot->Empty(); }
DT_CORE_DLL_ENTRY bool HasAnyVisibleContext() const;
private:
std::shared_ptr<const Vector<LogContext>> m_Snapshot;
};
DT_CORE_DLL_ENTRY String& operator<<(String& buf, const LogContexts& contexts);
class LogChannel
{
public:
DT_CORE_DLL_ENTRY LogChannel(const char* name);
DT_CORE_DLL_ENTRY const char* GetName() const { return m_Name; }
private:
const char* m_Name;
};
class LogStatement
{
public:
DT_CORE_DLL_ENTRY LogStatement(const DateTime& date,
const LogChannel& channel,
LogLevel level,
const LogContexts& contexts,
const String& message,
const char* file,
int line);
DT_CORE_DLL_ENTRY LogStatement(const LogStatement& rhs);
DT_CORE_DLL_ENTRY DateTime GetDate() const { return m_Date; }
DT_CORE_DLL_ENTRY const LogChannel& GetChannel() const { return m_Channel; }
DT_CORE_DLL_ENTRY LogLevel GetLevel() const { return m_Level; }
DT_CORE_DLL_ENTRY const char* GetFile() const { return m_File; }
DT_CORE_DLL_ENTRY int GetLine() const { return m_Line; }
DT_CORE_DLL_ENTRY const LogContexts& GetContexts() const { return m_Contexts; }
DT_CORE_DLL_ENTRY const String& GetLogMessage() const { return m_Message; }
private:
LogStatement& operator=(const LogStatement&) = delete;
const DateTime m_Date;
const LogChannel& m_Channel;
const LogLevel m_Level;
const LogContexts m_Contexts;
const String m_Message;
const char* m_File;
const int m_Line;
};
class LogAppender
{
public:
DT_CORE_DLL_ENTRY virtual ~LogAppender() {}
DT_CORE_DLL_ENTRY virtual void Write(LogStatement& msg) = 0;
DT_CORE_DLL_ENTRY virtual void Flush() = 0;
};
class Logger
{
public:
DT_CORE_DLL_ENTRY Logger();
DT_CORE_DLL_ENTRY ~Logger();
DT_CORE_DLL_ENTRY static Logger& Get();
DT_CORE_DLL_ENTRY void SetLevel(LogLevel lvl);
DT_CORE_DLL_ENTRY LogLevel GetLevel() const;
DT_CORE_DLL_ENTRY static const char* GetLevelString(LogLevel lvl);
DT_CORE_DLL_ENTRY static LogLevel GetLevelFromString(const String& level);
DT_CORE_DLL_ENTRY void AddAppender(LogAppender& appender);
DT_CORE_DLL_ENTRY void RemoveAppender(LogAppender& appender);
DT_CORE_DLL_ENTRY void Write(const LogChannel& channel, LogLevel lvl, const String& msg, const char* file, int line);
DT_CORE_DLL_ENTRY void Flush();
DT_CORE_DLL_ENTRY LogContexts GetThreadContexts() const;
DT_CORE_DLL_ENTRY LogContexts GetGlobalContexts() const;
public:
// internal
DT_CORE_DLL_ENTRY void InternalPushThreadContexts(const LogContexts& contexts);
DT_CORE_DLL_ENTRY void InternalPopThreadContexts(const LogContexts& contexts);
DT_CORE_DLL_ENTRY void InternalPushGlobalContexts(const LogContexts& contexts);
DT_CORE_DLL_ENTRY void InternalPopGlobalContexts(const LogContexts& contexts);
private:
friend LoggerImpl;
LoggerImpl* m_Impl;
};
#define DT_LOG_IF(level) \
if (level >= dt::Logger::Get().GetLevel())
#define DT_LOG(level, channel, expr) \
DT_LOG_IF(level) \
{ \
dt::String logText; \
logText << expr; \
dt::Logger::Get().Write(channel, level, logText, __FILE__, __LINE__); \
}
#define DT_LOG_TRACE(channel, expr) DT_LOG(dt::LogLevel::Trace, channel, expr)
#define DT_LOG_DEBUG(channel, expr) DT_LOG(dt::LogLevel::Debug, channel, expr)
#define DT_LOG_INFO(channel, expr) DT_LOG(dt::LogLevel::Info, channel, expr)
#define DT_LOG_SUCCESS(channel, expr) DT_LOG(dt::LogLevel::Success, channel, expr)
#define DT_LOG_WARNING(channel, expr) DT_LOG(dt::LogLevel::Warning, channel, expr)
#define DT_LOG_ERROR(channel, expr) DT_LOG(dt::LogLevel::Error, channel, expr)
#define DT_LOG_ALWAYS(channel, expr) DT_LOG(dt::LogLevel::Always, channel, expr)
#define DT_LOG_IF_TRACE() DT_LOG_IF(dt::LogLevel::Trace)
#define DT_LOG_IF_DEBUG() DT_LOG_IF(dt::LogLevel::Debug)
#define DT_LOG_IF_INFO() DT_LOG_IF(dt::LogLevel::Info)
#define DT_LOG_IF_SUCCESS() DT_LOG_IF(dt::LogLevel::Success)
#define DT_LOG_IF_WARNING() DT_LOG_IF(dt::LogLevel::Warning)
#define DT_LOG_IF_ERROR() DT_LOG_IF(dt::LogLevel::Error)
#define DT_LOG_IF_ALWAYS() DT_LOG_IF(dt::LogLevel::Always)
class LoggerAutoThreadContexts
{
public:
DT_CORE_DLL_ENTRY LoggerAutoThreadContexts(const LogContexts& contexts);
DT_CORE_DLL_ENTRY ~LoggerAutoThreadContexts();
private:
LogContexts m_Contexts;
};
#define DT_LOG_AUTO_THREAD_CONTEXTS(contexts) \
dt::LoggerAutoThreadContexts DT_UNIQUE_IDENTIFIER(logCtx)(contexts);
class LoggerAutoGlobalContexts
{
public:
DT_CORE_DLL_ENTRY LoggerAutoGlobalContexts(const LogContexts& contexts);
DT_CORE_DLL_ENTRY ~LoggerAutoGlobalContexts();
private:
LogContexts m_Contexts;
};
#define DT_LOG_AUTO_GLOBAL_CONTEXTS(contexts) \
dt::LoggerAutoGlobalContexts DT_UNIQUE_IDENTIFIER(logCtx)(contexts);
static LogChannel LogChannelGeneral("General");
static LogChannel LogChannelDatabase("Database");
static LogChannel LogChannelRunner("Runner");
static LogChannel LogChannelServiceAgency("Agency");
static LogChannel LogChannelServiceLog("Log");
static LogChannel LogChannelServiceTest("Test");
static LogChannel LogChannelServiceArtefact("Artefact");
static LogChannel LogChannelServiceConnection("Connection");
static LogChannel LogChannelServiceDetection("Detection");
static LogChannel LogChannelServiceTestManagementTool("TestManagementTool");
static LogChannel LogChannelService("Service");
static LogChannel LogChannelMessage("Message");
static LogChannel LogChannelProfiling("Profiling");
static LogChannel LogChannelStateMachine("State");
static LogChannel LogChannelToken("Token");
static LogChannel LogChannelScript("Script");
static LogChannel LogChannelBloomberg("Bloomberg");
}