bitz-server  2.0.0
wincolor_sink.h
1 //
2 // Copyright(c) 2016 spdlog
3 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
4 //
5 
6 #pragma once
7 
8 #include "../common.h"
9 #include "../details/null_mutex.h"
10 #include "base_sink.h"
11 
12 #include <mutex>
13 #include <string>
14 #include <unordered_map>
15 #include <wincon.h>
16 
17 namespace spdlog {
18 namespace sinks {
19 /*
20  * Windows color console sink. Uses WriteConsoleA to write to the console with colors
21  */
22 template<class Mutex>
23 class wincolor_sink : public base_sink<Mutex>
24 {
25 public:
26  const WORD BOLD = FOREGROUND_INTENSITY;
27  const WORD RED = FOREGROUND_RED;
28  const WORD GREEN = FOREGROUND_GREEN;
29  const WORD CYAN = FOREGROUND_GREEN | FOREGROUND_BLUE;
30  const WORD WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
31  const WORD YELLOW = FOREGROUND_RED | FOREGROUND_GREEN;
32 
33  wincolor_sink(HANDLE std_handle)
34  : out_handle_(std_handle)
35  {
36  colors_[level::trace] = WHITE;
37  colors_[level::debug] = CYAN;
38  colors_[level::info] = GREEN;
39  colors_[level::warn] = YELLOW | BOLD;
40  colors_[level::err] = RED | BOLD; // red bold
41  colors_[level::critical] = BACKGROUND_RED | WHITE | BOLD; // white bold on red background
42  colors_[level::off] = 0;
43  }
44 
45  ~wincolor_sink() override
46  {
47  this->flush();
48  }
49 
50  wincolor_sink(const wincolor_sink &other) = delete;
51  wincolor_sink &operator=(const wincolor_sink &other) = delete;
52 
53  // change the color for the given level
54  void set_color(level::level_enum level, WORD color)
55  {
56  std::lock_guard<Mutex> lock(base_sink<Mutex>::_mutex);
57  colors_[level] = color;
58  }
59 
60 protected:
61  void _sink_it(const details::log_msg &msg) override
62  {
63  if (msg.color_range_end > msg.color_range_start)
64  {
65  // before color range
66  _print_range(msg, 0, msg.color_range_start);
67 
68  // in color range
69  auto orig_attribs = set_console_attribs(colors_[msg.level]);
70  _print_range(msg, msg.color_range_start, msg.color_range_end);
71  ::SetConsoleTextAttribute(out_handle_, orig_attribs); // reset to orig colors
72  // after color range
73  _print_range(msg, msg.color_range_end, msg.formatted.size());
74  }
75  else // print without colors if color range is invalid
76  {
77  _print_range(msg, 0, msg.formatted.size());
78  }
79  }
80 
81  void _flush() override
82  {
83  // windows console always flushed?
84  }
85 
86 private:
87  HANDLE out_handle_;
88  std::unordered_map<level::level_enum, WORD, level::level_hasher> colors_;
89 
90  // set color and return the orig console attributes (for resetting later)
91  WORD set_console_attribs(WORD attribs)
92  {
93  CONSOLE_SCREEN_BUFFER_INFO orig_buffer_info;
94  GetConsoleScreenBufferInfo(out_handle_, &orig_buffer_info);
95  WORD back_color = orig_buffer_info.wAttributes;
96  // retrieve the current background color
97  back_color &= static_cast<WORD>(~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY));
98  // keep the background color unchanged
99  SetConsoleTextAttribute(out_handle_, attribs | back_color);
100  return orig_buffer_info.wAttributes; // return orig attribs
101  }
102 
103  // print a range of formatted message to console
104  void _print_range(const details::log_msg &msg, size_t start, size_t end)
105  {
106  DWORD size = static_cast<DWORD>(end - start);
107  WriteConsoleA(out_handle_, msg.formatted.data() + start, size, nullptr, nullptr);
108  }
109 };
110 
111 //
112 // windows color console to stdout
113 //
114 template<class Mutex>
115 class wincolor_stdout_sink : public wincolor_sink<Mutex>
116 {
117 public:
119  : wincolor_sink<Mutex>(GetStdHandle(STD_OUTPUT_HANDLE))
120  {
121  }
122 };
123 
126 
127 //
128 // windows color console to stderr
129 //
130 template<class Mutex>
131 class wincolor_stderr_sink : public wincolor_sink<Mutex>
132 {
133 public:
135  : wincolor_sink<Mutex>(GetStdHandle(STD_ERROR_HANDLE))
136  {
137  }
138 };
139 
142 
143 } // namespace sinks
144 } // namespace spdlog
const Char * data() const FMT_NOEXCEPT
Definition: format.h:3280
Definition: wincolor_sink.h:23
Definition: wincolor_sink.h:131
Definition: async_logger.h:26
std::size_t size() const
Definition: format.h:3271
Definition: log_msg.h:16
Definition: wincolor_sink.h:115
Definition: base_sink.h:23