1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. |
2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) |
3 | |
4 | #pragma once |
5 | |
6 | #include <spdlog/details/console_globals.h> |
7 | #include <spdlog/details/null_mutex.h> |
8 | #include <spdlog/sinks/sink.h> |
9 | #include <memory> |
10 | #include <mutex> |
11 | #include <string> |
12 | #include <array> |
13 | |
14 | namespace spdlog { |
15 | namespace sinks { |
16 | |
17 | /** |
18 | * This sink prefixes the output with an ANSI escape sequence color code |
19 | * depending on the severity |
20 | * of the message. |
21 | * If no color terminal detected, omit the escape codes. |
22 | */ |
23 | |
24 | template<typename ConsoleMutex> |
25 | class ansicolor_sink : public sink |
26 | { |
27 | public: |
28 | using mutex_t = typename ConsoleMutex::mutex_t; |
29 | ansicolor_sink(FILE *target_file, color_mode mode); |
30 | ~ansicolor_sink() override = default; |
31 | |
32 | ansicolor_sink(const ansicolor_sink &other) = delete; |
33 | ansicolor_sink(ansicolor_sink &&other) = delete; |
34 | |
35 | ansicolor_sink &operator=(const ansicolor_sink &other) = delete; |
36 | ansicolor_sink &operator=(ansicolor_sink &&other) = delete; |
37 | |
38 | void set_color(level::level_enum color_level, string_view_t color); |
39 | void set_color_mode(color_mode mode); |
40 | bool should_color(); |
41 | |
42 | void log(const details::log_msg &msg) override; |
43 | void flush() override; |
44 | void set_pattern(const std::string &pattern) final; |
45 | void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) override; |
46 | |
47 | // Formatting codes |
48 | const string_view_t reset = "\033[m" ; |
49 | const string_view_t bold = "\033[1m" ; |
50 | const string_view_t dark = "\033[2m" ; |
51 | const string_view_t underline = "\033[4m" ; |
52 | const string_view_t blink = "\033[5m" ; |
53 | const string_view_t reverse = "\033[7m" ; |
54 | const string_view_t concealed = "\033[8m" ; |
55 | const string_view_t clear_line = "\033[K" ; |
56 | |
57 | // Foreground colors |
58 | const string_view_t black = "\033[30m" ; |
59 | const string_view_t red = "\033[31m" ; |
60 | const string_view_t green = "\033[32m" ; |
61 | const string_view_t yellow = "\033[33m" ; |
62 | const string_view_t blue = "\033[34m" ; |
63 | const string_view_t magenta = "\033[35m" ; |
64 | const string_view_t cyan = "\033[36m" ; |
65 | const string_view_t white = "\033[37m" ; |
66 | |
67 | /// Background colors |
68 | const string_view_t on_black = "\033[40m" ; |
69 | const string_view_t on_red = "\033[41m" ; |
70 | const string_view_t on_green = "\033[42m" ; |
71 | const string_view_t on_yellow = "\033[43m" ; |
72 | const string_view_t on_blue = "\033[44m" ; |
73 | const string_view_t on_magenta = "\033[45m" ; |
74 | const string_view_t on_cyan = "\033[46m" ; |
75 | const string_view_t on_white = "\033[47m" ; |
76 | |
77 | /// Bold colors |
78 | const string_view_t yellow_bold = "\033[33m\033[1m" ; |
79 | const string_view_t red_bold = "\033[31m\033[1m" ; |
80 | const string_view_t bold_on_red = "\033[1m\033[41m" ; |
81 | |
82 | private: |
83 | FILE *target_file_; |
84 | mutex_t &mutex_; |
85 | bool should_do_colors_; |
86 | std::unique_ptr<spdlog::formatter> formatter_; |
87 | std::array<std::string, level::n_levels> colors_; |
88 | void print_ccode_(const string_view_t &color_code); |
89 | void print_range_(const memory_buf_t &formatted, size_t start, size_t end); |
90 | static std::string to_string_(const string_view_t &sv); |
91 | }; |
92 | |
93 | template<typename ConsoleMutex> |
94 | class ansicolor_stdout_sink : public ansicolor_sink<ConsoleMutex> |
95 | { |
96 | public: |
97 | explicit ansicolor_stdout_sink(color_mode mode = color_mode::automatic); |
98 | }; |
99 | |
100 | template<typename ConsoleMutex> |
101 | class ansicolor_stderr_sink : public ansicolor_sink<ConsoleMutex> |
102 | { |
103 | public: |
104 | explicit ansicolor_stderr_sink(color_mode mode = color_mode::automatic); |
105 | }; |
106 | |
107 | using ansicolor_stdout_sink_mt = ansicolor_stdout_sink<details::console_mutex>; |
108 | using ansicolor_stdout_sink_st = ansicolor_stdout_sink<details::console_nullmutex>; |
109 | |
110 | using ansicolor_stderr_sink_mt = ansicolor_stderr_sink<details::console_mutex>; |
111 | using ansicolor_stderr_sink_st = ansicolor_stderr_sink<details::console_nullmutex>; |
112 | |
113 | } // namespace sinks |
114 | } // namespace spdlog |
115 | |
116 | #ifdef SPDLOG_HEADER_ONLY |
117 | # include "ansicolor_sink-inl.h" |
118 | #endif |
119 | |