SimpleLog.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #pragma once
  2. #include <atlcomtime.h>
  3. #include <io.h>
  4. #include <direct.h>
  5. #include "String.Format.tlh"
  6. class SimpleLog
  7. {
  8. private:
  9. FILE * fpLog = nullptr;
  10. enum enLogLevel
  11. {
  12. enDebug = 1,
  13. enInfo = 2,
  14. enWarn = 3,
  15. enError = 4,
  16. enFatal = 5
  17. };
  18. static inline char LogLevelToName (int level)
  19. {
  20. static char Name [6] = { ' ', ' ', ' ', 'W', 'E', 'F' };
  21. if (level < enDebug) return ' ';
  22. else
  23. if (level > enFatal) return ' ';
  24. return Name [level];
  25. }
  26. public:
  27. SimpleLog () = default;
  28. SimpleLog (const char* LogName)
  29. {
  30. Open (LogName);
  31. }
  32. bool Open (const char * LogName)
  33. {
  34. if (fpLog) fclose (fpLog);
  35. char AppPath [_MAX_PATH + _MAX_PATH];
  36. int len = GetModuleFileName (NULL, AppPath, _MAX_PATH);
  37. len--;
  38. while (AppPath [len] != '\\')
  39. AppPath [len--] = '\0';
  40. COleDateTime now = COleDateTime::GetCurrentTime ();
  41. int Y = now.GetYear ();
  42. int M = now.GetMonth ();
  43. int D = now.GetDay ();
  44. int H = now.GetHour ();
  45. int T = now.GetMinute ();
  46. int S = now.GetSecond ();
  47. char logPath[_MAX_PATH];
  48. ECOM::Utility::StringFormat(logPath, _MAX_PATH)
  49. .Format("{$}\\Logs",
  50. AppPath);
  51. if (_access(logPath,0) != 0)
  52. {
  53. assert(_mkdir(logPath) == 0);
  54. }
  55. char logFileName [_MAX_PATH];
  56. ECOM::Utility::StringFormat (logFileName, _MAX_PATH)
  57. .Format ("{$}\\Logs\\{$}.{$:d04}{$:d02}{$:d02}.log",
  58. AppPath, LogName, Y, M, D);
  59. fpLog = fopen (logFileName, "ab+");
  60. assert (fpLog);
  61. return (fpLog != NULL);
  62. }
  63. void Close ()
  64. {
  65. if (fpLog)
  66. fclose (fpLog);
  67. fpLog = nullptr;
  68. }
  69. public:
  70. template <typename... Args>
  71. inline int Debug (const char * fmt, Args... args)
  72. {
  73. return LogOut (enDebug, fmt, args...);
  74. }
  75. template <typename... Args>
  76. inline int Info (const char* fmt, Args... args)
  77. {
  78. return LogOut (enInfo, fmt, args...);
  79. }
  80. template <typename... Args>
  81. inline int Warn (const char* fmt, Args... args)
  82. {
  83. return LogOut (enWarn, fmt, args...);
  84. }
  85. template <typename... Args>
  86. inline int Error (const char* fmt, Args... args)
  87. {
  88. return LogOut (enError, fmt, args...);
  89. }
  90. template <typename... Args>
  91. inline int Fatal (const char* fmt, Args... args)
  92. {
  93. return LogOut (enFatal, fmt, args...);
  94. }
  95. protected:
  96. template <typename... Args>
  97. inline int LogOut (int Level, const char * fmt, Args... args)
  98. {
  99. if (! fpLog) return 0;
  100. static const int MaxLen = 8192;
  101. char * buf = new char [MaxLen];
  102. struct timeb tp;
  103. ftime (&tp);
  104. tm tmNow;
  105. _localtime64_s (&tmNow, &tp.time);
  106. auto Y = tmNow.tm_year + 1900;
  107. auto M = tmNow.tm_mon + 1;
  108. auto D = tmNow.tm_mday;
  109. auto H = tmNow.tm_hour;
  110. auto T = tmNow.tm_min;
  111. auto S = tmNow.tm_sec;
  112. int len1 = ECOM::Utility::StringFormat (buf, MaxLen).Format ("{$} {$:d04}{$:d02}{$:d02} {$:d02}:{$:d02}:{$:d02}:{$:d03} [{$:x04}] ",
  113. LogLevelToName (Level), Y, M, D, H, T, S, tp.millitm, GetCurrentThreadId ());
  114. int len2 = ECOM::Utility::StringFormat (buf+len1, MaxLen-len1).Format (fmt, args...);
  115. buf [len1 + len2 + 0] = '\r';
  116. buf [len1 + len2 + 1] = '\n';
  117. auto rc = (int) Flush (buf, len1+len2+2 );
  118. delete[]buf;
  119. return rc;
  120. }
  121. int Flush (const char * buf, int len)
  122. {
  123. assert (buf);
  124. assert (fpLog);
  125. if (! fpLog) return 0;
  126. auto rc = (int) fwrite (buf, len, 1, fpLog);
  127. fflush (fpLog);
  128. return rc;
  129. }
  130. };