Home | History | Annotate | Download | only in interface
      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);
     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:
    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