SystemLog.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. #pragma once
  2. #include <string>
  3. #include "IOManipulate.tlh"
  4. #include "WString.hpp"
  5. #ifdef SYSTEMLOG_EXPORTS
  6. #define SYSTEM_LOG_API _declspec(dllexport)
  7. #else
  8. #define SYSTEM_LOG_API _declspec(dllimport)
  9. #endif
  10. typedef unsigned int uint;
  11. //-----------------------------------------------------------------------------
  12. // CSystemLog
  13. //-----------------------------------------------------------------------------
  14. namespace ECOM
  15. {
  16. namespace Log
  17. {
  18. class SYSTEM_LOG_API CSystemLog
  19. {
  20. public:
  21. static bool bLogOn;
  22. public:
  23. CSystemLog ();
  24. CSystemLog (CSystemLog * TieLog);
  25. CSystemLog (const CSystemLog & Log);
  26. virtual ~CSystemLog ()
  27. {
  28. Flush ();
  29. }
  30. void Attach (CSystemLog * Log);
  31. void Detach (void);
  32. bool On (void);
  33. void Off (void);
  34. int Puts (const char * s)
  35. {
  36. if (! bLogOn) return 0;
  37. m_Detail.Append (s);
  38. return (1);
  39. }
  40. virtual void Flush ()
  41. {
  42. if (pTieLog)
  43. pTieLog->Flush ();
  44. }
  45. public:
  46. enum Severity
  47. {
  48. /// <summary>
  49. /// 紧急,系统已经不可用,或者核心部件严重损坏
  50. /// </summary>
  51. STY_EMERGENCY = 0, /// 紧急
  52. /// <summary>
  53. /// 警报,系统管理员必须立即采取行动
  54. /// </summary>
  55. STY_ALERT, /// 警报
  56. /// <summary>
  57. /// 危急,某些非关键部件不可用,系统管理员应尽快采取行动
  58. /// </summary>
  59. STY_CRITICAL, /// 危急
  60. /// <summary>
  61. /// 错误,一般的错误信息,
  62. /// </summary>
  63. STY_ERROR, /// 错误
  64. /// <summary>
  65. /// 警告,警告信息
  66. /// </summary>
  67. STY_WARNING, /// 警告
  68. /// <summary>
  69. /// 通知,主要是对系统管理员的某些通知,比如病人信息已经正确修改
  70. /// </summary>
  71. STY_NOTICE, /// 通知
  72. /// <summary>
  73. /// 信息,正常信息
  74. /// </summary>
  75. STY_INFO, /// 信息
  76. /// <summary>
  77. /// 调试,表明该信息用于调试,比如DICOM的通信信息
  78. /// </summary>
  79. STY_DEBUG /// 调试
  80. };
  81. DString m_Source;
  82. Severity m_Severity;
  83. int m_LogID;
  84. DString m_Subject;
  85. DString m_Detail;
  86. int m_nbOfTab;
  87. bool m_bTick;
  88. DWORD m_ElapseTick;
  89. virtual CSystemLog & Banner (const char * banner)
  90. {
  91. if (! bLogOn) return (*this);
  92. Flush (banner, (int)strlen (banner));
  93. Flush ("\r\n", 2);
  94. return (*this);
  95. }
  96. virtual CSystemLog & Banner (const char * banner, int len)
  97. {
  98. if (!bLogOn) return (*this);
  99. Flush (banner, len);
  100. Flush ("\r\n", 2);
  101. return (*this);
  102. }
  103. virtual CSystemLog & Banner (const DString & banner)
  104. {
  105. if (! bLogOn) return (*this);
  106. Flush (banner, banner.GetLength () + 1);
  107. Flush ("\r\n", 2);
  108. return (*this);
  109. }
  110. /// <summary>
  111. /// 往日志中添加一项记录。
  112. /// </summary>
  113. /// <param name="severity">严重程度</param>
  114. /// <param name="LogID">标记这项日志</param>
  115. /// <param name="Subject">日志的标题</param>
  116. /// <param name="Detail">日志的详细内容</param>
  117. /// <returns>this, 可用于连续Append</returns>
  118. virtual CSystemLog & Append (Severity severity, int LogID, const char * Subject, const char * Detail)
  119. {
  120. if (! bLogOn) return (*this);
  121. m_Severity = severity;
  122. m_LogID = LogID;
  123. m_Subject = Subject;
  124. m_Detail += Detail;
  125. return (*this);
  126. }
  127. template <typename... Args>
  128. inline CSystemLog & _XAppendFormat (const char * lpszFormat, Args... args)
  129. {
  130. m_Detail += DString::_XFromFormat (lpszFormat, args...);
  131. return (*this);
  132. }
  133. // CSystemLog & AppendFormat (const char * lpszFormat, ...);
  134. // CSystemLog & AppendFormatV (const char * lpszFormat, va_list argList);
  135. virtual void EndLine ();
  136. public:
  137. static int LineOfDelayFlush;
  138. public:
  139. virtual void Flush (const char * Data, int Size)
  140. {
  141. if (pTieLog)
  142. pTieLog->Flush (Data, Size);
  143. }
  144. virtual void Flush (const DString & str)
  145. {
  146. if (pTieLog)
  147. pTieLog->Flush (str);
  148. }
  149. /*
  150. public:
  151. friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, char ch);
  152. friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, unsigned char ch);
  153. friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, int i);
  154. friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, unsigned int i);
  155. friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, long l);
  156. friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, unsigned long l);
  157. friend SYSTEM_LOG_API CSystemLog & operator << (CSystemLog & Log, string s);
  158. */
  159. public:
  160. CSystemLog & operator << (int i);
  161. CSystemLog & operator << (DWORD d) { return this->operator << (int (d)); }
  162. CSystemLog & operator << (unsigned int d) { return this->operator << (int (d)); }
  163. CSystemLog & operator << (long l) { return this->operator << (int (l)); }
  164. CSystemLog & operator << (unsigned short l) { return this->operator << (int (l)); }
  165. CSystemLog & operator << (__int64 l) { return this->operator << (int (l)); }
  166. CSystemLog & operator << (unsigned __int64 l) { return this->operator << (int (l)); }
  167. CSystemLog & operator << (char ch)
  168. {
  169. m_Detail += ch;
  170. return (*this);
  171. }
  172. CSystemLog & operator << (const char * s)
  173. {
  174. m_Detail += s;
  175. return (*this);
  176. }
  177. CSystemLog & operator << (const DString & s)
  178. {
  179. m_Detail += s;
  180. return (*this);
  181. }
  182. // 日志内容, 如果也用 UNICODE, 日志文件就太大了, 因此日志内容还是继续用 MBCS
  183. // 对于 "正在打开 <A:\\AA.DCM>" 之类的日志内容, 信息仍然用 MBCS, 需要把文件名转换成 MBCS
  184. CSystemLog & operator << (const wchar_t * s)
  185. {
  186. m_Detail += WString (s).ToDString ();
  187. return (*this);
  188. }
  189. CSystemLog & operator << (const WString & s)
  190. {
  191. m_Detail += s.ToDString ();
  192. return (*this);
  193. }
  194. CSystemLog & operator << (const std::string & s)
  195. {
  196. m_Detail += s.c_str ();
  197. return (*this);
  198. }
  199. protected:
  200. CSystemLog * pTieLog;
  201. };
  202. //-----------------------------------------------------------------------------
  203. // 无操作数操纵算子
  204. //-----------------------------------------------------------------------------
  205. inline CSystemLog & flush (CSystemLog & Log)
  206. {
  207. Log.Flush ();
  208. return Log;
  209. }
  210. inline CSystemLog & endl (CSystemLog & Log)
  211. {
  212. Log.EndLine ();
  213. Log.Flush ("\r\n", 2);
  214. return Log;
  215. }
  216. inline CSystemLog & newline (CSystemLog & Log)
  217. {
  218. Log.Flush ("\r\n", 2);
  219. return Log;
  220. }
  221. inline CSystemLog & emergency (CSystemLog & Log)
  222. {
  223. Log.m_Severity = CSystemLog::STY_EMERGENCY;
  224. return Log;
  225. }
  226. inline CSystemLog & alert (CSystemLog & Log)
  227. {
  228. Log.m_Severity = CSystemLog::STY_ALERT;
  229. return Log;
  230. }
  231. inline CSystemLog & critical (CSystemLog & Log)
  232. {
  233. Log.m_Severity = CSystemLog::STY_CRITICAL;
  234. return Log;
  235. }
  236. inline CSystemLog & error (CSystemLog & Log)
  237. {
  238. Log.m_Severity = CSystemLog::STY_ERROR;
  239. return Log;
  240. }
  241. inline CSystemLog & warning (CSystemLog & Log)
  242. {
  243. Log.m_Severity = CSystemLog::STY_WARNING;
  244. return Log;
  245. }
  246. inline CSystemLog & warn (CSystemLog & Log)
  247. {
  248. Log.m_Severity = CSystemLog::STY_WARNING;
  249. return Log;
  250. }
  251. inline CSystemLog & notice (CSystemLog & Log)
  252. {
  253. Log.m_Severity = CSystemLog::STY_NOTICE;
  254. return Log;
  255. }
  256. inline CSystemLog & info (CSystemLog & Log)
  257. {
  258. Log.m_Severity = CSystemLog::STY_INFO;
  259. return Log;
  260. }
  261. inline CSystemLog & debug (CSystemLog & Log)
  262. {
  263. Log.m_Severity = CSystemLog::STY_DEBUG;
  264. return Log;
  265. }
  266. // 在日志的末尾写上当前 TICK, 便于比较
  267. inline CSystemLog & tick (CSystemLog & Log)
  268. {
  269. Log.m_bTick = true;
  270. return Log;
  271. }
  272. inline CSystemLog & operator << (CSystemLog & Log, CSystemLog & (*func) (CSystemLog &))
  273. {
  274. return (*func) (Log);
  275. }
  276. //-----------------------------------------------------------------------------
  277. // 一元操作数操纵算子
  278. //-----------------------------------------------------------------------------
  279. inline CSystemLog & SetLogID (CSystemLog & log, int LID)
  280. {
  281. log.m_LogID = LID;
  282. return log;
  283. }
  284. inline fcn_obj <CSystemLog, int>
  285. LogID (int value)
  286. {
  287. CSystemLog & (*my_bs) (CSystemLog &, int) = SetLogID;
  288. return fcn_obj <CSystemLog, int> (my_bs, value);
  289. }
  290. inline CSystemLog & SetElapse (CSystemLog & log, UINT Tick)
  291. {
  292. log.m_ElapseTick = Tick;
  293. return log;
  294. }
  295. inline fcn_obj <CSystemLog, UINT>
  296. Elapse (UINT Tick)
  297. {
  298. CSystemLog & (*my_bs) (CSystemLog &, UINT) = SetElapse;
  299. return fcn_obj <CSystemLog, UINT> (my_bs, Tick);
  300. }
  301. inline CSystemLog & SetSource (CSystemLog & log, const char * Source)
  302. {
  303. log.m_Source = Source;
  304. return log;
  305. }
  306. inline fcn_obj <CSystemLog, const char *>
  307. Source (const char * value)
  308. {
  309. CSystemLog & (*my_bs) (CSystemLog &, const char *) = SetSource;
  310. return fcn_obj <CSystemLog, const char *> (my_bs, value);
  311. }
  312. inline CSystemLog & SetSource (CSystemLog & log, const DString Source)
  313. {
  314. log.m_Source = Source;
  315. return log;
  316. }
  317. inline fcn_obj <CSystemLog, DString>
  318. Source (DString value)
  319. {
  320. CSystemLog & (*my_bs) (CSystemLog &, DString) = SetSource;
  321. return fcn_obj <CSystemLog, DString> (my_bs, value);
  322. }
  323. inline CSystemLog & SetSubject (CSystemLog & log, const char * Subject)
  324. {
  325. log.m_Subject = Subject;
  326. return log;
  327. }
  328. inline fcn_obj <CSystemLog, const char *>
  329. Subject (const char * value)
  330. {
  331. CSystemLog & (*my_bs) (CSystemLog &, const char *) = SetSubject;
  332. return fcn_obj <CSystemLog, const char *> (my_bs, value);
  333. }
  334. inline CSystemLog & SetSubject (CSystemLog & log, const DString Subject)
  335. {
  336. log.m_Subject = Subject;
  337. return log;
  338. }
  339. inline fcn_obj <CSystemLog, DString>
  340. Subject (DString value)
  341. {
  342. CSystemLog & (*my_bs) (CSystemLog &, DString) = SetSubject;
  343. return fcn_obj <CSystemLog, DString> (my_bs, value);
  344. }
  345. inline CSystemLog & SetSeverity (CSystemLog & log, CSystemLog::Severity s)
  346. {
  347. log.m_Severity = s;
  348. return log;
  349. }
  350. inline fcn_obj <CSystemLog, CSystemLog::Severity>
  351. Severity (CSystemLog::Severity value)
  352. {
  353. CSystemLog & (*my_bs) (CSystemLog &, CSystemLog::Severity) = SetSeverity;
  354. return fcn_obj <CSystemLog, CSystemLog::Severity> (my_bs, value);
  355. }
  356. SYSTEM_LOG_API ECOM::Log::CSystemLog & __LogSysError (ECOM::Log::CSystemLog & log, DWORD errcode);
  357. // 把 Windows 对错误代码的解释信息写到日志中, eCode=GetLastError ()
  358. inline fcn_obj <CSystemLog, DWORD > syserror (DWORD eCode)
  359. {
  360. CSystemLog & (*my_bs) (CSystemLog &, DWORD) = __LogSysError;
  361. return fcn_obj <CSystemLog, DWORD> (my_bs, eCode);
  362. }
  363. //-----------------------------------------------------------------------------
  364. // 二元操作数操纵算子
  365. //-----------------------------------------------------------------------------
  366. inline CSystemLog & SetSourceID (CSystemLog & log, DWORD SourceHigh, DWORD SourceLow)
  367. {
  368. return log;
  369. }
  370. inline fcn_2obj <CSystemLog, DWORD, DWORD> SourceID (DWORD High, DWORD Low)
  371. {
  372. CSystemLog & (*my_bs) (CSystemLog &, DWORD, DWORD) = SetSourceID;
  373. return fcn_2obj <CSystemLog, DWORD, DWORD> (my_bs, High, Low);
  374. }
  375. }
  376. }