1 #pragma once 2 #include <plog/Appenders/ConsoleAppender.h> 3 #include <plog/WinApi.h> 4 5 namespace plog 6 { 7 template<class Formatter> 8 class ColorConsoleAppender : public ConsoleAppender<Formatter> 9 { 10 public: 11 #ifdef _WIN32 ColorConsoleAppender()12 ColorConsoleAppender() : m_originalAttr() 13 { 14 if (this->m_isatty) 15 { 16 CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 17 GetConsoleScreenBufferInfo(this->m_stdoutHandle, &csbiInfo); 18 19 m_originalAttr = csbiInfo.wAttributes; 20 } 21 } 22 #else 23 ColorConsoleAppender() {} 24 #endif 25 write(const Record & record)26 virtual void write(const Record& record) 27 { 28 util::nstring str = Formatter::format(record); 29 util::MutexLock lock(this->m_mutex); 30 31 setColor(record.getSeverity()); 32 this->writestr(str); 33 resetColor(); 34 } 35 36 private: setColor(Severity severity)37 void setColor(Severity severity) 38 { 39 if (this->m_isatty) 40 { 41 switch (severity) 42 { 43 #ifdef _WIN32 44 case fatal: 45 SetConsoleTextAttribute(this->m_stdoutHandle, foreground::kRed | foreground::kGreen | foreground::kBlue | foreground::kIntensity | background::kRed); // white on red background 46 break; 47 48 case error: 49 SetConsoleTextAttribute(this->m_stdoutHandle, static_cast<WORD>(foreground::kRed | foreground::kIntensity | (m_originalAttr & 0xf0))); // red 50 break; 51 52 case warning: 53 SetConsoleTextAttribute(this->m_stdoutHandle, static_cast<WORD>(foreground::kRed | foreground::kGreen | foreground::kIntensity | (m_originalAttr & 0xf0))); // yellow 54 break; 55 56 case debug: 57 case verbose: 58 SetConsoleTextAttribute(this->m_stdoutHandle, static_cast<WORD>(foreground::kGreen | foreground::kBlue | foreground::kIntensity | (m_originalAttr & 0xf0))); // cyan 59 break; 60 #else 61 case fatal: 62 std::cout << "\x1B[97m\x1B[41m"; // white on red background 63 break; 64 65 case error: 66 std::cout << "\x1B[91m"; // red 67 break; 68 69 case warning: 70 std::cout << "\x1B[93m"; // yellow 71 break; 72 73 case debug: 74 case verbose: 75 std::cout << "\x1B[96m"; // cyan 76 break; 77 #endif 78 default: 79 break; 80 } 81 } 82 } 83 resetColor()84 void resetColor() 85 { 86 if (this->m_isatty) 87 { 88 #ifdef _WIN32 89 SetConsoleTextAttribute(this->m_stdoutHandle, m_originalAttr); 90 #else 91 std::cout << "\x1B[0m\x1B[0K"; 92 #endif 93 } 94 } 95 96 private: 97 #ifdef _WIN32 98 WORD m_originalAttr; 99 #endif 100 }; 101 } 102