OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... |
39 // LOG_E(sev, ctx, err, ...) logs a detailed error interpreted using the | 39 // LOG_E(sev, ctx, err, ...) logs a detailed error interpreted using the |
40 // specified context. | 40 // specified context. |
41 // LOG_CHECK_LEVEL(sev) (and LOG_CHECK_LEVEL_V(sev)) can be used as a test | 41 // LOG_CHECK_LEVEL(sev) (and LOG_CHECK_LEVEL_V(sev)) can be used as a test |
42 // before performing expensive or sensitive operations whose sole purpose is | 42 // before performing expensive or sensitive operations whose sole purpose is |
43 // to output logging data at the desired level. | 43 // to output logging data at the desired level. |
44 // Lastly, PLOG(sev, err) is an alias for LOG_ERR_EX. | 44 // Lastly, PLOG(sev, err) is an alias for LOG_ERR_EX. |
45 | 45 |
46 #ifndef WEBRTC_BASE_LOGGING_H_ | 46 #ifndef WEBRTC_BASE_LOGGING_H_ |
47 #define WEBRTC_BASE_LOGGING_H_ | 47 #define WEBRTC_BASE_LOGGING_H_ |
48 | 48 |
49 #include <errno.h> | |
50 | 49 |
51 #include <list> | 50 // This header is deprecated and is just left here temporarily during |
52 #include <sstream> | 51 // refactoring. See https://bugs.webrtc.org/7634 for more details. |
53 #include <string> | 52 #include "webrtc/rtc_base/logging.h" |
54 #include <utility> | |
55 | |
56 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) | |
57 #include <CoreServices/CoreServices.h> | |
58 #endif | |
59 | |
60 #include "webrtc/base/basictypes.h" | |
61 #include "webrtc/base/constructormagic.h" | |
62 #include "webrtc/base/thread_annotations.h" | |
63 | |
64 namespace rtc { | |
65 | |
66 /////////////////////////////////////////////////////////////////////////////// | |
67 // ConstantLabel can be used to easily generate string names from constant | |
68 // values. This can be useful for logging descriptive names of error messages. | |
69 // Usage: | |
70 // const ConstantLabel LIBRARY_ERRORS[] = { | |
71 // KLABEL(SOME_ERROR), | |
72 // KLABEL(SOME_OTHER_ERROR), | |
73 // ... | |
74 // LASTLABEL | |
75 // } | |
76 // | |
77 // int err = LibraryFunc(); | |
78 // LOG(LS_ERROR) << "LibraryFunc returned: " | |
79 // << ErrorName(err, LIBRARY_ERRORS); | |
80 | |
81 struct ConstantLabel { int value; const char * label; }; | |
82 #define KLABEL(x) { x, #x } | |
83 #define TLABEL(x, y) { x, y } | |
84 #define LASTLABEL { 0, 0 } | |
85 | |
86 const char* FindLabel(int value, const ConstantLabel entries[]); | |
87 std::string ErrorName(int err, const ConstantLabel* err_table); | |
88 | |
89 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) | |
90 // Returns a UTF8 description from an OS X Status error. | |
91 std::string DescriptionFromOSStatus(OSStatus err); | |
92 #endif | |
93 | |
94 ////////////////////////////////////////////////////////////////////// | |
95 | |
96 // Note that the non-standard LoggingSeverity aliases exist because they are | |
97 // still in broad use. The meanings of the levels are: | |
98 // LS_SENSITIVE: Information which should only be logged with the consent | |
99 // of the user, due to privacy concerns. | |
100 // LS_VERBOSE: This level is for data which we do not want to appear in the | |
101 // normal debug log, but should appear in diagnostic logs. | |
102 // LS_INFO: Chatty level used in debugging for all sorts of things, the default | |
103 // in debug builds. | |
104 // LS_WARNING: Something that may warrant investigation. | |
105 // LS_ERROR: Something that should not have occurred. | |
106 // LS_NONE: Don't log. | |
107 enum LoggingSeverity { | |
108 LS_SENSITIVE, | |
109 LS_VERBOSE, | |
110 LS_INFO, | |
111 LS_WARNING, | |
112 LS_ERROR, | |
113 LS_NONE, | |
114 INFO = LS_INFO, | |
115 WARNING = LS_WARNING, | |
116 LERROR = LS_ERROR | |
117 }; | |
118 | |
119 // LogErrorContext assists in interpreting the meaning of an error value. | |
120 enum LogErrorContext { | |
121 ERRCTX_NONE, | |
122 ERRCTX_ERRNO, // System-local errno | |
123 ERRCTX_HRESULT, // Windows HRESULT | |
124 ERRCTX_OSSTATUS, // MacOS OSStatus | |
125 | |
126 // Abbreviations for LOG_E macro | |
127 ERRCTX_EN = ERRCTX_ERRNO, // LOG_E(sev, EN, x) | |
128 ERRCTX_HR = ERRCTX_HRESULT, // LOG_E(sev, HR, x) | |
129 ERRCTX_OS = ERRCTX_OSSTATUS, // LOG_E(sev, OS, x) | |
130 }; | |
131 | |
132 // Virtual sink interface that can receive log messages. | |
133 class LogSink { | |
134 public: | |
135 LogSink() {} | |
136 virtual ~LogSink() {} | |
137 virtual void OnLogMessage(const std::string& message) = 0; | |
138 }; | |
139 | |
140 class LogMessage { | |
141 public: | |
142 LogMessage(const char* file, | |
143 int line, | |
144 LoggingSeverity sev, | |
145 LogErrorContext err_ctx = ERRCTX_NONE, | |
146 int err = 0, | |
147 const char* module = nullptr); | |
148 | |
149 LogMessage(const char* file, | |
150 int line, | |
151 LoggingSeverity sev, | |
152 const std::string& tag); | |
153 | |
154 ~LogMessage(); | |
155 | |
156 static inline bool Loggable(LoggingSeverity sev) { return (sev >= min_sev_); } | |
157 std::ostream& stream() { return print_stream_; } | |
158 | |
159 // Returns the time at which this function was called for the first time. | |
160 // The time will be used as the logging start time. | |
161 // If this is not called externally, the LogMessage ctor also calls it, in | |
162 // which case the logging start time will be the time of the first LogMessage | |
163 // instance is created. | |
164 static int64_t LogStartTime(); | |
165 | |
166 // Returns the wall clock equivalent of |LogStartTime|, in seconds from the | |
167 // epoch. | |
168 static uint32_t WallClockStartTime(); | |
169 | |
170 // LogThreads: Display the thread identifier of the current thread | |
171 static void LogThreads(bool on = true); | |
172 | |
173 // LogTimestamps: Display the elapsed time of the program | |
174 static void LogTimestamps(bool on = true); | |
175 | |
176 // These are the available logging channels | |
177 // Debug: Debug console on Windows, otherwise stderr | |
178 static void LogToDebug(LoggingSeverity min_sev); | |
179 static LoggingSeverity GetLogToDebug() { return dbg_sev_; } | |
180 | |
181 // Sets whether logs will be directed to stderr in debug mode. | |
182 static void SetLogToStderr(bool log_to_stderr); | |
183 | |
184 // Stream: Any non-blocking stream interface. LogMessage takes ownership of | |
185 // the stream. Multiple streams may be specified by using AddLogToStream. | |
186 // LogToStream is retained for backwards compatibility; when invoked, it | |
187 // will discard any previously set streams and install the specified stream. | |
188 // GetLogToStream gets the severity for the specified stream, of if none | |
189 // is specified, the minimum stream severity. | |
190 // RemoveLogToStream removes the specified stream, without destroying it. | |
191 static int GetLogToStream(LogSink* stream = nullptr); | |
192 static void AddLogToStream(LogSink* stream, LoggingSeverity min_sev); | |
193 static void RemoveLogToStream(LogSink* stream); | |
194 | |
195 // Testing against MinLogSeverity allows code to avoid potentially expensive | |
196 // logging operations by pre-checking the logging level. | |
197 static int GetMinLogSeverity() { return min_sev_; } | |
198 | |
199 // Parses the provided parameter stream to configure the options above. | |
200 // Useful for configuring logging from the command line. | |
201 static void ConfigureLogging(const char* params); | |
202 | |
203 private: | |
204 typedef std::pair<LogSink*, LoggingSeverity> StreamAndSeverity; | |
205 typedef std::list<StreamAndSeverity> StreamList; | |
206 | |
207 // Updates min_sev_ appropriately when debug sinks change. | |
208 static void UpdateMinLogSeverity(); | |
209 | |
210 // These write out the actual log messages. | |
211 static void OutputToDebug(const std::string& msg, | |
212 LoggingSeverity severity, | |
213 const std::string& tag); | |
214 | |
215 // The ostream that buffers the formatted message before output | |
216 std::ostringstream print_stream_; | |
217 | |
218 // The severity level of this message | |
219 LoggingSeverity severity_; | |
220 | |
221 // The Android debug output tag. | |
222 std::string tag_; | |
223 | |
224 // String data generated in the constructor, that should be appended to | |
225 // the message before output. | |
226 std::string extra_; | |
227 | |
228 // dbg_sev_ is the thresholds for those output targets | |
229 // min_sev_ is the minimum (most verbose) of those levels, and is used | |
230 // as a short-circuit in the logging macros to identify messages that won't | |
231 // be logged. | |
232 // ctx_sev_ is the minimum level at which file context is displayed | |
233 static LoggingSeverity min_sev_, dbg_sev_, ctx_sev_; | |
234 | |
235 // The output streams and their associated severities | |
236 static StreamList streams_; | |
237 | |
238 // Flags for formatting options | |
239 static bool thread_, timestamp_; | |
240 | |
241 // Determines if logs will be directed to stderr in debug mode. | |
242 static bool log_to_stderr_; | |
243 | |
244 RTC_DISALLOW_COPY_AND_ASSIGN(LogMessage); | |
245 }; | |
246 | |
247 ////////////////////////////////////////////////////////////////////// | |
248 // Logging Helpers | |
249 ////////////////////////////////////////////////////////////////////// | |
250 | |
251 class LogMultilineState { | |
252 public: | |
253 size_t unprintable_count_[2]; | |
254 LogMultilineState() { | |
255 unprintable_count_[0] = unprintable_count_[1] = 0; | |
256 } | |
257 }; | |
258 | |
259 // When possible, pass optional state variable to track various data across | |
260 // multiple calls to LogMultiline. Otherwise, pass null. | |
261 void LogMultiline(LoggingSeverity level, const char* label, bool input, | |
262 const void* data, size_t len, bool hex_mode, | |
263 LogMultilineState* state); | |
264 | |
265 #ifndef LOG | |
266 | |
267 // The following non-obvious technique for implementation of a | |
268 // conditional log stream was stolen from google3/base/logging.h. | |
269 | |
270 // This class is used to explicitly ignore values in the conditional | |
271 // logging macros. This avoids compiler warnings like "value computed | |
272 // is not used" and "statement has no effect". | |
273 | |
274 class LogMessageVoidify { | |
275 public: | |
276 LogMessageVoidify() { } | |
277 // This has to be an operator with a precedence lower than << but | |
278 // higher than ?: | |
279 void operator&(std::ostream&) { } | |
280 }; | |
281 | |
282 #define LOG_SEVERITY_PRECONDITION(sev) \ | |
283 !(rtc::LogMessage::Loggable(sev)) \ | |
284 ? (void) 0 \ | |
285 : rtc::LogMessageVoidify() & | |
286 | |
287 #define LOG(sev) \ | |
288 LOG_SEVERITY_PRECONDITION(rtc::sev) \ | |
289 rtc::LogMessage(__FILE__, __LINE__, rtc::sev).stream() | |
290 | |
291 // The _V version is for when a variable is passed in. It doesn't do the | |
292 // namespace concatination. | |
293 #define LOG_V(sev) \ | |
294 LOG_SEVERITY_PRECONDITION(sev) \ | |
295 rtc::LogMessage(__FILE__, __LINE__, sev).stream() | |
296 | |
297 // The _F version prefixes the message with the current function name. | |
298 #if (defined(__GNUC__) && !defined(NDEBUG)) || defined(WANT_PRETTY_LOG_F) | |
299 #define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": " | |
300 #define LOG_T_F(sev) LOG(sev) << this << ": " << __PRETTY_FUNCTION__ << ": " | |
301 #else | |
302 #define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": " | |
303 #define LOG_T_F(sev) LOG(sev) << this << ": " << __FUNCTION__ << ": " | |
304 #endif | |
305 | |
306 #define LOG_CHECK_LEVEL(sev) \ | |
307 rtc::LogCheckLevel(rtc::sev) | |
308 #define LOG_CHECK_LEVEL_V(sev) \ | |
309 rtc::LogCheckLevel(sev) | |
310 | |
311 inline bool LogCheckLevel(LoggingSeverity sev) { | |
312 return (LogMessage::GetMinLogSeverity() <= sev); | |
313 } | |
314 | |
315 #define LOG_E(sev, ctx, err, ...) \ | |
316 LOG_SEVERITY_PRECONDITION(rtc::sev) \ | |
317 rtc::LogMessage(__FILE__, __LINE__, rtc::sev, \ | |
318 rtc::ERRCTX_ ## ctx, err , ##__VA_ARGS__) \ | |
319 .stream() | |
320 | |
321 #define LOG_T(sev) LOG(sev) << this << ": " | |
322 | |
323 #define LOG_ERRNO_EX(sev, err) \ | |
324 LOG_E(sev, ERRNO, err) | |
325 #define LOG_ERRNO(sev) \ | |
326 LOG_ERRNO_EX(sev, errno) | |
327 | |
328 #if defined(WEBRTC_WIN) | |
329 #define LOG_GLE_EX(sev, err) \ | |
330 LOG_E(sev, HRESULT, err) | |
331 #define LOG_GLE(sev) \ | |
332 LOG_GLE_EX(sev, GetLastError()) | |
333 #define LOG_GLEM(sev, mod) \ | |
334 LOG_E(sev, HRESULT, GetLastError(), mod) | |
335 #define LOG_ERR_EX(sev, err) \ | |
336 LOG_GLE_EX(sev, err) | |
337 #define LOG_ERR(sev) \ | |
338 LOG_GLE(sev) | |
339 #define LAST_SYSTEM_ERROR \ | |
340 (::GetLastError()) | |
341 #elif defined(__native_client__) && __native_client__ | |
342 #define LOG_ERR_EX(sev, err) \ | |
343 LOG(sev) | |
344 #define LOG_ERR(sev) \ | |
345 LOG(sev) | |
346 #define LAST_SYSTEM_ERROR \ | |
347 (0) | |
348 #elif defined(WEBRTC_POSIX) | |
349 #define LOG_ERR_EX(sev, err) \ | |
350 LOG_ERRNO_EX(sev, err) | |
351 #define LOG_ERR(sev) \ | |
352 LOG_ERRNO(sev) | |
353 #define LAST_SYSTEM_ERROR \ | |
354 (errno) | |
355 #endif // WEBRTC_WIN | |
356 | |
357 #define LOG_TAG(sev, tag) \ | |
358 LOG_SEVERITY_PRECONDITION(sev) \ | |
359 rtc::LogMessage(nullptr, 0, sev, tag).stream() | |
360 | |
361 #define PLOG(sev, err) \ | |
362 LOG_ERR_EX(sev, err) | |
363 | |
364 // TODO(?): Add an "assert" wrapper that logs in the same manner. | |
365 | |
366 #endif // LOG | |
367 | |
368 } // namespace rtc | |
369 | 53 |
370 #endif // WEBRTC_BASE_LOGGING_H_ | 54 #endif // WEBRTC_BASE_LOGGING_H_ |
OLD | NEW |