#pragma once #include #include "IOManipulate.tlh" #include "WString.hpp" #ifdef SYSTEMLOG_EXPORTS #define SYSTEM_LOG_API _declspec(dllexport) #else #define SYSTEM_LOG_API _declspec(dllimport) #endif typedef unsigned int uint; //----------------------------------------------------------------------------- // CSystemLog //----------------------------------------------------------------------------- namespace ECOM { namespace Log { class SYSTEM_LOG_API CSystemLog { public: static bool bLogOn; public: CSystemLog (); CSystemLog (CSystemLog * TieLog); CSystemLog (const CSystemLog & Log); virtual ~CSystemLog () { Flush (); } void Attach (CSystemLog * Log); void Detach (void); bool On (void); void Off (void); int Puts (const char * s) { if (! bLogOn) return 0; m_Detail.Append (s); return (1); } virtual void Flush () { if (pTieLog) pTieLog->Flush (); } public: enum Severity { /// /// 紧急,系统已经不可用,或者核心部件严重损坏 /// STY_EMERGENCY = 0, /// 紧急 /// /// 警报,系统管理员必须立即采取行动 /// STY_ALERT, /// 警报 /// /// 危急,某些非关键部件不可用,系统管理员应尽快采取行动 /// STY_CRITICAL, /// 危急 /// /// 错误,一般的错误信息, /// STY_ERROR, /// 错误 /// /// 警告,警告信息 /// STY_WARNING, /// 警告 /// /// 通知,主要是对系统管理员的某些通知,比如病人信息已经正确修改 /// STY_NOTICE, /// 通知 /// /// 信息,正常信息 /// STY_INFO, /// 信息 /// /// 调试,表明该信息用于调试,比如DICOM的通信信息 /// STY_DEBUG /// 调试 }; DString m_Source; Severity m_Severity; int m_LogID; DString m_Subject; DString m_Detail; int m_nbOfTab; bool m_bTick; DWORD m_ElapseTick; virtual CSystemLog & Banner (const char * banner) { if (! bLogOn) return (*this); Flush (banner, (int)strlen (banner)); Flush ("\r\n", 2); return (*this); } virtual CSystemLog & Banner (const char * banner, int len) { if (!bLogOn) return (*this); Flush (banner, len); Flush ("\r\n", 2); return (*this); } virtual CSystemLog & Banner (const DString & banner) { if (! bLogOn) return (*this); Flush (banner, banner.GetLength () + 1); Flush ("\r\n", 2); return (*this); } /// /// 往日志中添加一项记录。 /// /// 严重程度 /// 标记这项日志 /// 日志的标题 /// 日志的详细内容 /// this, 可用于连续Append virtual CSystemLog & Append (Severity severity, int LogID, const char * Subject, const char * Detail) { if (! bLogOn) return (*this); m_Severity = severity; m_LogID = LogID; m_Subject = Subject; m_Detail += Detail; return (*this); } template inline CSystemLog & _XAppendFormat (const char * lpszFormat, Args... args) { m_Detail += DString::_XFromFormat (lpszFormat, args...); return (*this); } // CSystemLog & AppendFormat (const char * lpszFormat, ...); // CSystemLog & AppendFormatV (const char * lpszFormat, va_list argList); virtual void EndLine (); public: static int LineOfDelayFlush; public: virtual void Flush (const char * Data, int Size) { if (pTieLog) pTieLog->Flush (Data, Size); } virtual void Flush (const DString & str) { if (pTieLog) pTieLog->Flush (str); } /* public: friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, char ch); friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, unsigned char ch); friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, int i); friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, unsigned int i); friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, long l); friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, unsigned long l); friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, string s); */ public: CSystemLog & operator << (int i); CSystemLog & operator << (DWORD d) { return this->operator << (int (d)); } CSystemLog & operator << (unsigned int d) { return this->operator << (int (d)); } CSystemLog & operator << (long l) { return this->operator << (int (l)); } CSystemLog & operator << (unsigned short l) { return this->operator << (int (l)); } CSystemLog & operator << (__int64 l) { return this->operator << (int (l)); } CSystemLog & operator << (unsigned __int64 l) { return this->operator << (int (l)); } CSystemLog & operator << (char ch) { m_Detail += ch; return (*this); } CSystemLog & operator << (const char * s) { m_Detail += s; return (*this); } CSystemLog & operator << (const DString & s) { m_Detail += s; return (*this); } // 日志内容, 如果也用 UNICODE, 日志文件就太大了, 因此日志内容还是继续用 MBCS // 对于 "正在打开 " 之类的日志内容, 信息仍然用 MBCS, 需要把文件名转换成 MBCS CSystemLog & operator << (const wchar_t * s) { m_Detail += WString (s).ToDString (); return (*this); } CSystemLog & operator << (const WString & s) { m_Detail += s.ToDString (); return (*this); } CSystemLog & operator << (const std::string & s) { m_Detail += s.c_str (); return (*this); } protected: CSystemLog * pTieLog; }; //----------------------------------------------------------------------------- // 无操作数操纵算子 //----------------------------------------------------------------------------- inline CSystemLog & flush (CSystemLog & Log) { Log.Flush (); return Log; } inline CSystemLog & endl (CSystemLog & Log) { Log.EndLine (); Log.Flush ("\r\n", 2); return Log; } inline CSystemLog & newline (CSystemLog & Log) { Log.Flush ("\r\n", 2); return Log; } inline CSystemLog & emergency (CSystemLog & Log) { Log.m_Severity = CSystemLog::STY_EMERGENCY; return Log; } inline CSystemLog & alert (CSystemLog & Log) { Log.m_Severity = CSystemLog::STY_ALERT; return Log; } inline CSystemLog & critical (CSystemLog & Log) { Log.m_Severity = CSystemLog::STY_CRITICAL; return Log; } inline CSystemLog & error (CSystemLog & Log) { Log.m_Severity = CSystemLog::STY_ERROR; return Log; } inline CSystemLog & warning (CSystemLog & Log) { Log.m_Severity = CSystemLog::STY_WARNING; return Log; } inline CSystemLog & warn (CSystemLog & Log) { Log.m_Severity = CSystemLog::STY_WARNING; return Log; } inline CSystemLog & notice (CSystemLog & Log) { Log.m_Severity = CSystemLog::STY_NOTICE; return Log; } inline CSystemLog & info (CSystemLog & Log) { Log.m_Severity = CSystemLog::STY_INFO; return Log; } inline CSystemLog & debug (CSystemLog & Log) { Log.m_Severity = CSystemLog::STY_DEBUG; return Log; } // 在日志的末尾写上当前 TICK, 便于比较 inline CSystemLog & tick (CSystemLog & Log) { Log.m_bTick = true; return Log; } inline CSystemLog & operator << (CSystemLog & Log, CSystemLog & (*func) (CSystemLog &)) { return (*func) (Log); } //----------------------------------------------------------------------------- // 一元操作数操纵算子 //----------------------------------------------------------------------------- inline CSystemLog & SetLogID (CSystemLog & log, int LID) { log.m_LogID = LID; return log; } inline fcn_obj LogID (int value) { CSystemLog & (*my_bs) (CSystemLog &, int) = SetLogID; return fcn_obj (my_bs, value); } inline CSystemLog & SetElapse (CSystemLog & log, UINT Tick) { log.m_ElapseTick = Tick; return log; } inline fcn_obj Elapse (UINT Tick) { CSystemLog & (*my_bs) (CSystemLog &, UINT) = SetElapse; return fcn_obj (my_bs, Tick); } inline CSystemLog & SetSource (CSystemLog & log, const char * Source) { log.m_Source = Source; return log; } inline fcn_obj Source (const char * value) { CSystemLog & (*my_bs) (CSystemLog &, const char *) = SetSource; return fcn_obj (my_bs, value); } inline CSystemLog & SetSource (CSystemLog & log, const DString Source) { log.m_Source = Source; return log; } inline fcn_obj Source (DString value) { CSystemLog & (*my_bs) (CSystemLog &, DString) = SetSource; return fcn_obj (my_bs, value); } inline CSystemLog & SetSubject (CSystemLog & log, const char * Subject) { log.m_Subject = Subject; return log; } inline fcn_obj Subject (const char * value) { CSystemLog & (*my_bs) (CSystemLog &, const char *) = SetSubject; return fcn_obj (my_bs, value); } inline CSystemLog & SetSubject (CSystemLog & log, const DString Subject) { log.m_Subject = Subject; return log; } inline fcn_obj Subject (DString value) { CSystemLog & (*my_bs) (CSystemLog &, DString) = SetSubject; return fcn_obj (my_bs, value); } inline CSystemLog & SetSeverity (CSystemLog & log, CSystemLog::Severity s) { log.m_Severity = s; return log; } inline fcn_obj Severity (CSystemLog::Severity value) { CSystemLog & (*my_bs) (CSystemLog &, CSystemLog::Severity) = SetSeverity; return fcn_obj (my_bs, value); } SYSTEM_LOG_API ECOM::Log::CSystemLog & __LogSysError (ECOM::Log::CSystemLog & log, DWORD errcode); // 把 Windows 对错误代码的解释信息写到日志中, eCode=GetLastError () inline fcn_obj syserror (DWORD eCode) { CSystemLog & (*my_bs) (CSystemLog &, DWORD) = __LogSysError; return fcn_obj (my_bs, eCode); } //----------------------------------------------------------------------------- // 二元操作数操纵算子 //----------------------------------------------------------------------------- inline CSystemLog & SetSourceID (CSystemLog & log, DWORD SourceHigh, DWORD SourceLow) { return log; } inline fcn_2obj SourceID (DWORD High, DWORD Low) { CSystemLog & (*my_bs) (CSystemLog &, DWORD, DWORD) = SetSourceID; return fcn_2obj (my_bs, High, Low); } } }