1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 // This is a highly stripped-down version of libjingle's talk/base/logging.h. 12 // It is a thin wrapper around WEBRTC_TRACE, maintaining the libjingle log 13 // semantics to ease a transition to that format. 14 15 // NOTE: LS_INFO maps to a new trace level which should be reserved for 16 // infrequent, non-verbose logs. The other levels below kTraceWarning have been 17 // rendered essentially useless due to their verbosity. Carefully consider the 18 // impact of adding a new LS_INFO log. If it will be logged at anything 19 // approaching a frame or packet frequency, use LS_VERBOSE if necessary, or 20 // preferably, do not log at all. 21 22 // LOG(...) an ostream target that can be used to send formatted 23 // output to a variety of logging targets, such as debugger console, stderr, 24 // file, or any StreamInterface. 25 // The severity level passed as the first argument to the LOGging 26 // functions is used as a filter, to limit the verbosity of the logging. 27 // Static members of LogMessage documented below are used to control the 28 // verbosity and target of the output. 29 // There are several variations on the LOG macro which facilitate logging 30 // of common error conditions, detailed below. 31 32 // LOG(sev) logs the given stream at severity "sev", which must be a 33 // compile-time constant of the LoggingSeverity type, without the namespace 34 // prefix. 35 // LOG_V(sev) Like LOG(), but sev is a run-time variable of the LoggingSeverity 36 // type (basically, it just doesn't prepend the namespace). 37 // LOG_F(sev) Like LOG(), but includes the name of the current function. 38 39 // Additional helper macros added by WebRTC: 40 // LOG_API is a shortcut for API call logging. Pass in the input parameters of 41 // the method. For example: 42 // Foo(int bar, int baz) { 43 // LOG_API2(bar, baz); 44 // } 45 // 46 // LOG_FERR is a shortcut for logging a failed function call. For example: 47 // if (!Foo(bar)) { 48 // LOG_FERR1(LS_WARNING, Foo, bar); 49 // } 50 51 #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_ 52 #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_ 53 54 #include <sstream> 55 56 namespace webrtc { 57 58 ////////////////////////////////////////////////////////////////////// 59 60 // Note that the non-standard LoggingSeverity aliases exist because they are 61 // still in broad use. The meanings of the levels are: 62 // LS_SENSITIVE: Information which should only be logged with the consent 63 // of the user, due to privacy concerns. 64 // LS_VERBOSE: This level is for data which we do not want to appear in the 65 // normal debug log, but should appear in diagnostic logs. 66 // LS_INFO: Chatty level used in debugging for all sorts of things, the default 67 // in debug builds. 68 // LS_WARNING: Something that may warrant investigation. 69 // LS_ERROR: Something that should not have occurred. 70 enum LoggingSeverity { 71 LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR 72 }; 73 74 class LogMessage { 75 public: 76 LogMessage(const char* file, int line, LoggingSeverity sev); 77 ~LogMessage(); 78 79 static bool Loggable(LoggingSeverity sev); stream()80 std::ostream& stream() { return print_stream_; } 81 82 private: 83 // The ostream that buffers the formatted message before output 84 std::ostringstream print_stream_; 85 86 // The severity level of this message 87 LoggingSeverity severity_; 88 }; 89 90 ////////////////////////////////////////////////////////////////////// 91 // Macros which automatically disable logging when WEBRTC_LOGGING == 0 92 ////////////////////////////////////////////////////////////////////// 93 94 #ifndef LOG 95 // The following non-obvious technique for implementation of a 96 // conditional log stream was stolen from google3/base/logging.h. 97 98 // This class is used to explicitly ignore values in the conditional 99 // logging macros. This avoids compiler warnings like "value computed 100 // is not used" and "statement has no effect". 101 102 class LogMessageVoidify { 103 public: LogMessageVoidify()104 LogMessageVoidify() { } 105 // This has to be an operator with a precedence lower than << but 106 // higher than ?: 107 void operator&(std::ostream&) { } 108 }; 109 110 #if defined(WEBRTC_RESTRICT_LOGGING) 111 // This should compile away logs matching the following condition. 112 #define RESTRICT_LOGGING_PRECONDITION(sev) \ 113 sev < webrtc::LS_INFO ? (void) 0 : 114 #else 115 #define RESTRICT_LOGGING_PRECONDITION(sev) 116 #endif 117 118 #define LOG_SEVERITY_PRECONDITION(sev) \ 119 RESTRICT_LOGGING_PRECONDITION(sev) !(webrtc::LogMessage::Loggable(sev)) \ 120 ? (void) 0 \ 121 : webrtc::LogMessageVoidify() & 122 123 #define LOG(sev) \ 124 LOG_SEVERITY_PRECONDITION(webrtc::sev) \ 125 webrtc::LogMessage(__FILE__, __LINE__, webrtc::sev).stream() 126 127 // The _V version is for when a variable is passed in. It doesn't do the 128 // namespace concatination. 129 #define LOG_V(sev) \ 130 LOG_SEVERITY_PRECONDITION(sev) \ 131 webrtc::LogMessage(__FILE__, __LINE__, sev).stream() 132 133 // The _F version prefixes the message with the current function name. 134 #if (defined(__GNUC__) && defined(_DEBUG)) || defined(WANT_PRETTY_LOG_F) 135 #define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": " 136 #else 137 #define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": " 138 #endif 139 140 #define LOG_API0() LOG_F(LS_VERBOSE) 141 #define LOG_API1(v1) LOG_API0() << #v1 << "=" << v1 142 #define LOG_API2(v1, v2) LOG_API1(v1) \ 143 << ", " << #v2 << "=" << v2 144 #define LOG_API3(v1, v2, v3) LOG_API2(v1, v2) \ 145 << ", " << #v3 << "=" << v3 146 147 #define LOG_FERR0(sev, func) LOG(sev) << #func << " failed" 148 #define LOG_FERR1(sev, func, v1) LOG_FERR0(sev, func) \ 149 << ": " << #v1 << "=" << v1 150 #define LOG_FERR2(sev, func, v1, v2) LOG_FERR1(sev, func, v1) \ 151 << ", " << #v2 << "=" << v2 152 #define LOG_FERR3(sev, func, v1, v2, v3) LOG_FERR2(sev, func, v1, v2) \ 153 << ", " << #v3 << "=" << v3 154 #define LOG_FERR4(sev, func, v1, v2, v3, v4) LOG_FERR3(sev, func, v1, v2, v3) \ 155 << ", " << #v4 << "=" << v4 156 157 #endif // LOG 158 159 } // namespace webrtc 160 161 #endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_ 162