/proc/self/cwd/pw_log_basic/log_basic.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2020 The Pigweed Authors |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
4 | | // use this file except in compliance with the License. You may obtain a copy of |
5 | | // the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
11 | | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
12 | | // License for the specific language governing permissions and limitations under |
13 | | // the License. |
14 | | |
15 | | // This is a very basic direct output log implementation with no buffering. |
16 | | |
17 | | #include "pw_log_basic/log_basic.h" |
18 | | |
19 | | #include <cstring> |
20 | | |
21 | | #include "pw_log/levels.h" |
22 | | #include "pw_log_basic_private/config.h" |
23 | | #include "pw_string/string_builder.h" |
24 | | #include "pw_sys_io/sys_io.h" |
25 | | |
26 | | // ANSI color constants to control the terminal. Not Windows compatible. |
27 | | // clang-format off |
28 | 455k | #define MAGENTA "\033[35m" |
29 | 876k | #define YELLOW "\033[33m" |
30 | 389k | #define RED "\033[31m" |
31 | 0 | #define GREEN "\033[32m" |
32 | 19.1M | #define BLUE "\033[96m" |
33 | 0 | #define BLACK "\033[30m" |
34 | | #define YELLOW_BG "\033[43m" |
35 | | #define WHITE_BG "\033[47m" |
36 | | #define RED_BG "\033[41m" |
37 | | #define BOLD "\033[1m" |
38 | 20.8M | #define RESET "\033[0m" |
39 | | // clang-format on |
40 | | |
41 | | namespace pw::log_basic { |
42 | | namespace { |
43 | | |
44 | 20.8M | const char* LogLevelToLogLevelName(int level) { |
45 | 20.8M | switch (level) { |
46 | | // clang-format off |
47 | | #if PW_EMOJI |
48 | | case PW_LOG_LEVEL_DEBUG : return "đž" RESET; |
49 | | case PW_LOG_LEVEL_INFO : return "âšī¸ " RESET; |
50 | | case PW_LOG_LEVEL_WARN : return "â ī¸ " RESET; |
51 | | case PW_LOG_LEVEL_ERROR : return "â" RESET; |
52 | | case PW_LOG_LEVEL_CRITICAL : return "â ī¸ " RESET; |
53 | | default: return "â" RESET; |
54 | | #else |
55 | 19.1M | case PW_LOG_LEVEL_DEBUG : return BLUE BOLD "DBG" RESET; |
56 | 455k | case PW_LOG_LEVEL_INFO : return MAGENTA BOLD "INF" RESET; |
57 | 876k | case PW_LOG_LEVEL_WARN : return YELLOW BOLD "WRN" RESET; |
58 | 389k | case PW_LOG_LEVEL_ERROR : return RED BOLD "ERR" RESET; |
59 | 0 | case PW_LOG_LEVEL_CRITICAL : return BLACK BOLD RED_BG "FTL" RESET; |
60 | 0 | default : return GREEN BOLD "UNK" RESET; |
61 | 20.8M | #endif |
62 | | // clang-format on |
63 | 20.8M | } |
64 | 20.8M | } |
65 | | |
66 | | #if PW_LOG_SHOW_FILENAME |
67 | | const char* GetFileBasename(const char* filename) { |
68 | | int length = std::strlen(filename); |
69 | | if (length == 0) { |
70 | | return filename; |
71 | | } |
72 | | |
73 | | // Start on the last character. |
74 | | // TODO(pwbug/38): This part of the function doesn't work for Windows paths. |
75 | | const char* basename = filename + std::strlen(filename) - 1; |
76 | | while (basename != filename && *basename != '/') { |
77 | | basename--; |
78 | | } |
79 | | if (*basename == '/') { |
80 | | basename++; |
81 | | } |
82 | | return basename; |
83 | | } |
84 | | #endif // PW_LOG_SHOW_FILENAME |
85 | | |
86 | 20.8M | void (*write_log)(std::string_view) = [](std::string_view log) { |
87 | 20.8M | sys_io::WriteLine(log) |
88 | 20.8M | .IgnoreError(); // TODO: b/242598609 - Handle Status properly |
89 | 20.8M | }; |
90 | | |
91 | | } // namespace |
92 | | |
93 | | // This is a fully loaded, inefficient-at-the-callsite, log implementation. |
94 | | extern "C" void pw_Log(int level, |
95 | | unsigned int flags, |
96 | | const char* module_name, |
97 | | const char* file_name, |
98 | | int line_number, |
99 | | const char* function_name, |
100 | | const char* message, |
101 | 20.8M | ...) { |
102 | 20.8M | va_list args; |
103 | 20.8M | va_start(args, message); |
104 | 20.8M | pw_Log_HandleMessageVaList(level, |
105 | 20.8M | flags, |
106 | 20.8M | module_name, |
107 | 20.8M | file_name, |
108 | 20.8M | line_number, |
109 | 20.8M | function_name, |
110 | 20.8M | message, |
111 | 20.8M | args); |
112 | 20.8M | va_end(args); |
113 | 20.8M | } |
114 | | |
115 | | extern "C" void pw_Log_HandleMessageVaList(int level, |
116 | | unsigned int flags, |
117 | | const char* module_name, |
118 | | const char* file_name, |
119 | | int line_number, |
120 | | const char* function_name, |
121 | | const char* message, |
122 | 20.8M | va_list args) { |
123 | | // Accumulate the log message in this buffer, then output it. |
124 | 20.8M | pw::StringBuffer<PW_LOG_BASIC_ENTRY_SIZE> buffer; |
125 | | |
126 | | // Column: Timestamp |
127 | | // Note that this macro method defaults to a no-op. |
128 | 20.8M | PW_LOG_APPEND_TIMESTAMP(buffer); |
129 | | |
130 | | // Column: Filename |
131 | | #if PW_LOG_SHOW_FILENAME |
132 | | buffer.Format(" %-30s:%4d |", GetFileBasename(file_name), line_number); |
133 | | #else |
134 | 20.8M | static_cast<void>(file_name); |
135 | 20.8M | static_cast<void>(line_number); |
136 | 20.8M | #endif |
137 | | |
138 | | // Column: Function |
139 | | #if PW_LOG_SHOW_FUNCTION |
140 | | buffer.Format(" %-30s |", function_name); |
141 | | #else |
142 | 20.8M | static_cast<void>(function_name); |
143 | 20.8M | #endif |
144 | | |
145 | | // Column: Module |
146 | | #if PW_LOG_SHOW_MODULE |
147 | | buffer << " " BOLD; |
148 | | buffer.Format("%3s", module_name); |
149 | | buffer << RESET " "; |
150 | | #else |
151 | 20.8M | static_cast<void>(module_name); |
152 | 20.8M | #endif // PW_LOG_SHOW_MODULE |
153 | | |
154 | | // Column: Flag |
155 | | #if PW_LOG_SHOW_FLAG |
156 | | #if PW_EMOJI |
157 | | buffer << (flags ? "đŠ" : " "); |
158 | | #else |
159 | | buffer << (flags ? "*" : "|"); |
160 | | #endif // PW_EMOJI |
161 | | buffer << " "; |
162 | | #else |
163 | 20.8M | static_cast<void>(flags); |
164 | 20.8M | #endif // PW_LOG_SHOW_FLAG |
165 | | |
166 | | // Column: Level |
167 | 20.8M | buffer << LogLevelToLogLevelName(level) << " "; |
168 | | |
169 | | // Column: Message |
170 | 20.8M | buffer.FormatVaList(message, args); |
171 | | |
172 | | // All done; flush the log. |
173 | 20.8M | write_log(buffer); |
174 | 20.8M | } |
175 | | |
176 | 0 | void SetOutput(void (*log_output)(std::string_view log)) { |
177 | 0 | write_log = log_output; |
178 | 0 | } |
179 | | |
180 | | } // namespace pw::log_basic |