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
|
---|
12 | ColorConsoleAppender() : m_isatty(!!_isatty(_fileno(stdout))), m_stdoutHandle(), m_originalAttr()
|
---|
13 | {
|
---|
14 | if (m_isatty)
|
---|
15 | {
|
---|
16 | m_stdoutHandle = GetStdHandle(stdHandle::kOutput);
|
---|
17 |
|
---|
18 | CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
|
---|
19 | GetConsoleScreenBufferInfo(m_stdoutHandle, &csbiInfo);
|
---|
20 |
|
---|
21 | m_originalAttr = csbiInfo.wAttributes;
|
---|
22 | }
|
---|
23 | }
|
---|
24 | #else
|
---|
25 | ColorConsoleAppender() : m_isatty(!!::isatty(::fileno(stdout))) {}
|
---|
26 | #endif
|
---|
27 |
|
---|
28 | #ifdef __BORLANDC__
|
---|
29 | static int _isatty(int fd) { return ::isatty(fd); }
|
---|
30 | #endif
|
---|
31 |
|
---|
32 | virtual void write(const Record& record)
|
---|
33 | {
|
---|
34 | util::nstring str = Formatter::format(record);
|
---|
35 | util::MutexLock lock(this->m_mutex);
|
---|
36 |
|
---|
37 | setColor(record.getSeverity());
|
---|
38 | this->writestr(str);
|
---|
39 | resetColor();
|
---|
40 | }
|
---|
41 |
|
---|
42 | private:
|
---|
43 | void setColor(Severity severity)
|
---|
44 | {
|
---|
45 | if (m_isatty)
|
---|
46 | {
|
---|
47 | switch (severity)
|
---|
48 | {
|
---|
49 | #ifdef _WIN32
|
---|
50 | case fatal:
|
---|
51 | SetConsoleTextAttribute(m_stdoutHandle, foreground::kRed | foreground::kGreen | foreground::kBlue | foreground::kIntensity | background::kRed); // white on red background
|
---|
52 | break;
|
---|
53 |
|
---|
54 | case error:
|
---|
55 | SetConsoleTextAttribute(m_stdoutHandle, static_cast<WORD>(foreground::kRed | foreground::kIntensity | (m_originalAttr & 0xf0))); // red
|
---|
56 | break;
|
---|
57 |
|
---|
58 | case warning:
|
---|
59 | SetConsoleTextAttribute(m_stdoutHandle, static_cast<WORD>(foreground::kRed | foreground::kGreen | foreground::kIntensity | (m_originalAttr & 0xf0))); // yellow
|
---|
60 | break;
|
---|
61 |
|
---|
62 | case debug:
|
---|
63 | case verbose:
|
---|
64 | SetConsoleTextAttribute(m_stdoutHandle, static_cast<WORD>(foreground::kGreen | foreground::kBlue | foreground::kIntensity | (m_originalAttr & 0xf0))); // cyan
|
---|
65 | break;
|
---|
66 | #else
|
---|
67 | case fatal:
|
---|
68 | std::cout << "\x1B[97m\x1B[41m"; // white on red background
|
---|
69 | break;
|
---|
70 |
|
---|
71 | case error:
|
---|
72 | std::cout << "\x1B[91m"; // red
|
---|
73 | break;
|
---|
74 |
|
---|
75 | case warning:
|
---|
76 | std::cout << "\x1B[93m"; // yellow
|
---|
77 | break;
|
---|
78 |
|
---|
79 | case debug:
|
---|
80 | case verbose:
|
---|
81 | std::cout << "\x1B[96m"; // cyan
|
---|
82 | break;
|
---|
83 | #endif
|
---|
84 | default:
|
---|
85 | break;
|
---|
86 | }
|
---|
87 | }
|
---|
88 | }
|
---|
89 |
|
---|
90 | void resetColor()
|
---|
91 | {
|
---|
92 | if (m_isatty)
|
---|
93 | {
|
---|
94 | #ifdef _WIN32
|
---|
95 | SetConsoleTextAttribute(m_stdoutHandle, m_originalAttr);
|
---|
96 | #else
|
---|
97 | std::cout << "\x1B[0m\x1B[0K";
|
---|
98 | #endif
|
---|
99 | }
|
---|
100 | }
|
---|
101 |
|
---|
102 | private:
|
---|
103 | bool m_isatty;
|
---|
104 | #ifdef _WIN32
|
---|
105 | HANDLE m_stdoutHandle;
|
---|
106 | WORD m_originalAttr;
|
---|
107 | #endif
|
---|
108 | };
|
---|
109 | }
|
---|