| 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 |