#pragma once #define __USING_LOG4CPP__ #include #include #include #include "String.DString.hpp" #include "String.Format.tlh" #ifdef Log4CPP_EXPORTS #define Log4CPP_API _declspec(dllexport) #else #define Log4CPP_API _declspec(dllimport) #endif #include "Log4CPP.Define.hpp" #include "Log4CPP.LogLevel.hpp" #include "Log4CPP.Appender.hpp" #include "Log4CPP.TLSLog.hpp" #ifndef Log4CPP_EXPORTS #ifdef _WIN64 #ifdef _DEBUG #pragma comment (lib, "Log4CPP64D.lib") #pragma comment (lib, "Log4CPP.TLSLog64D.lib") #pragma comment (lib, "ECOM.Utility.DString64D.lib") #else #pragma comment (lib, "Log4CPP64.lib") #pragma comment (lib, "Log4CPP.TLSLog64.lib") #pragma comment (lib, "ECOM.Utility.DString64.lib") #endif #else // X86 #ifdef _DEBUG #pragma comment (lib, "Log4CPPD.lib") #pragma comment (lib, "Log4CPP.TLSLogD.lib") #else #pragma comment (lib, "Log4CPP.lib") #pragma comment (lib, "Log4CPP.TLSLog.lib") #endif #endif #endif // Log4CPP_EXPORTS //----------------------------------------------------------------------------- // Logger //----------------------------------------------------------------------------- namespace Log4CPP { namespace Detail { class Logger_Detail; } }; namespace Log4CPP { class Log4CPP_API Logger { public: Logger (); Logger (const char * Name); Logger (const char * Name, const char * DisplayName); Logger (const Logger & from); Logger (Logger && from); ~Logger (); public: Logger & operator = (const Logger & from); Logger & operator = (Logger && from); public: void Close (); public: //< const char * // 忽略级别, 无条件输出日志. 常用于组件启动时的版本/构建等信息 template inline void Force (const char * fmt, Args && ... args) { DoLog ((int) enLogLevel::enTrace, fmt, std::forward (args)...); } template inline void Verbose (const char * fmt, Args && ... args) { if (GetLevel () > enLogLevel::enVerbose) return; DoLog ((int) enLogLevel::enVerbose, fmt, std::forward (args)...); } template inline void Trace (const char * fmt, Args && ... args) { if (GetLevel () > enLogLevel::enTrace) return; DoLog ((int)enLogLevel::enTrace, fmt, std::forward (args)...); } template inline void Debug (const char * fmt, Args && ... args) { if (GetLevel () > enLogLevel::enDebug) return; DoLog ((int) enLogLevel::enDebug, fmt, std::forward (args)...); } template inline void Info (const char* fmt, Args && ... args) { if (GetLevel () > enLogLevel::enInfo) return; DoLog ((int) enLogLevel::enInfo, fmt, std::forward (args)...); } template inline void Notice (const char* fmt, Args && ... args) { if (GetLevel () > enLogLevel::enNotice) return; DoLog ((int) enLogLevel::enNotice, fmt, std::forward (args)...); } template inline void Warn (const char * fmt, Args && ... args) { if (GetLevel () > enLogLevel::enWarn) return; DoLog ((int) enLogLevel::enWarn, fmt, std::forward (args)...); } template inline void Error (const char * fmt, Args && ... args) { if (GetLevel () > enLogLevel::enError) return; DoLog ((int) enLogLevel::enError, fmt, std::forward (args)...); } template inline void Fatal (const char * fmt, Args && ... args) { if (GetLevel () > enLogLevel::enFatal) return; DoLog ((int) enLogLevel::enFatal, fmt, std::forward (args)...); } //> //< StringView template inline void Force (const eSTR::StringView & fmt, Args && ... args) { DoLog ((int) enLogLevel::enTrace, fmt, std::forward (args)...); } template inline void Trace (const eSTR::StringView & fmt, Args && ... args) { if (GetLevel () > enLogLevel::enTrace) return; DoLog ((int) enLogLevel::enTrace, fmt, std::forward (args)...); } template inline void Debug (const eSTR::StringView & fmt, Args && ... args) { if (GetLevel () > enLogLevel::enDebug) return; DoLog ((int) enLogLevel::enDebug, fmt, std::forward (args)...); } template inline void Info (const eSTR::StringView & fmt, Args && ... args) { if (GetLevel () > enLogLevel::enInfo) return; DoLog ((int) enLogLevel::enInfo, fmt, std::forward (args)...); } template inline void Notice (const eSTR::StringView & fmt, Args && ... args) { if (GetLevel () > enLogLevel::enNotice) return; DoLog ((int) enLogLevel::enNotice, fmt, std::forward (args)...); } template inline void Warn (const eSTR::StringView & fmt, Args && ... args) { if (GetLevel () > enLogLevel::enWarn) return; DoLog ((int) enLogLevel::enWarn, fmt, std::forward (args)...); } template inline void Error (const eSTR::StringView & fmt, Args && ... args) { if (GetLevel () > enLogLevel::enError) return; DoLog ((int) enLogLevel::enError, fmt, std::forward (args)...); } template inline void Fatal (const eSTR::StringView & fmt, Args && ... args) { if (GetLevel () > enLogLevel::enFatal) return; DoLog ((int) enLogLevel::enFatal, fmt, std::forward (args)...); } //> template inline void Log (int Level, const char * fmt, Args && ... args) { if (GetLevel () > Level) return; DoLog (Level, fmt, std::forward (args)...); } bool Decide (int Level) const { return (GetLevel () <= Level); } //< 以下 3 个函数中, if (tbuf [0]) 及最后的 tbuf [0] = 0, 是为了避免重入 // 在 Appender.BUS 及 Appender.UDP 中, 执行到最后, MyWriter::WriteLine () 函数体的最后一行 // 有可能再次调用 mLog::XX (), 这有可能再次到这里, tbuf 就会被破坏 public: // 直接把字符串刷到 Appender 中, 不要做格式化 inline void LogNoFormat (int Level, const char * buf, int len, bool bWithLayout = false) { if (GetLevel () > Level) return; auto tbuf = ThreadContext::TLSMessage::Get (); auto size = ThreadContext::TLSMessage::Size () - 4; if (tbuf [0]) return; auto cch = (std::min) (size, len); memcpy (tbuf, buf, cch); tbuf [cch] = 0; Flush (Level, cch, tbuf, bWithLayout); tbuf [0] = 0; } private: template inline void DoLog (int Level, const char * fmt, Args && ... args) { auto tbuf = ThreadContext::TLSMessage::Get (); auto size = ThreadContext::TLSMessage::Size () - 4; if (tbuf [0]) return; auto cch = 0; if (sizeof...(args) == 0) { cch = (int) strlen (fmt); cch = (std::min) (cch, size); memcpy (tbuf, fmt, cch); tbuf [cch] = 0; } else { cch = ECOM::Utility::String::StringFormat (tbuf, size).Format (fmt, std::forward (args)...); tbuf [cch] = 0; } Flush (Level, cch, tbuf, true); tbuf [0] = 0; } template inline void DoLog (int Level, const eSTR::StringView & fmt, Args && ... args) { auto tbuf = ThreadContext::TLSMessage::Get (); auto size = ThreadContext::TLSMessage::Size () - 4; if (tbuf [0]) return; auto cch = 0; if (sizeof...(args) == 0) { cch = fmt.GetLength (); cch = (std::min) (cch, size); memcpy (tbuf, fmt, cch); tbuf [cch] = 0; } else { cch = ECOM::Utility::String::StringFormat (tbuf, size).Format (fmt, std::forward (args)...); tbuf [cch] = 0; } Flush (Level, cch, tbuf, true); tbuf [0] = 0; } //> public: void NewLine (int Level = enLogLevel::enInfo); public: TLogString GetName () const; // { return m_Name; } TLogString GetDisplayName () const; // { return m_DisplayName; } enLogLevel GetLevel () const; // { return m_Level; } void SetLevel (int value); // { m_Level = value; } void Set (const TLogString & key, const TLogString & value); // for arAppender public: // 对 Appender 进行迭代 int GetNbOfAppender () const; int ForEachAppender (std::function fun); int OnEachAppender (std::function fun); Appender * FindAppender (std::function Pred); public: // 添加一个没有任何特殊配置项的 Appender Appender * AddAppender (const char * Type, const char * Name); bool RemoveAppender (const char * Name); public: // 把 from 中已有的 Appender 复制给我自己. 目前主要是 ConfigManager 在使用 void CopyAppenderFrom (const Logger & from); // 把 from 中已有的 Appender 添加到我自己. 目前主要是 ConfigManager 在使用 void AddAppenderFrom (const Logger & from); // 把已有的 Appender 添加到 Logger 中, 目前主要是 ConfigManager 在使用 void AddAppender (std::shared_ptr a); public: void Flush (int Level, int cbBuf, const char * buf, bool bWithLayout); private: static tTraceID GetTraceID (); public: static TLogString ErrorCodeToString (DWORD errorCode); static TLogString LogLevelToString (int level); private: enLogLevel m_Level = enLogLevel::enUndefined; Detail::Logger_Detail * m_pDetail; }; }; //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- namespace Log4CPP { class Log4CPP_API LogManager { private: LogManager () = delete; public: static bool LoadConfigFile (const char * CfgFileName); static bool LoadConfigString (const char * strXML); static Logger * GetLogger (const char * LoggerName); static bool IsExist (const char * LoggerName); static auto NewAppender (const char * Type, const char * Name) -> std::unique_ptr ; static int ForEachLogger (std::function fun); static void CloseAll (); }; };