SimpleLog.hpp 3.1 KB

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