Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 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 file overrides the logging macros in libjingle (webrtc/base/logging.h).
     12 // Instead of using libjingle's logging implementation, the libjingle macros are
     13 // mapped to the corresponding base/logging.h macro (chromium's VLOG).
     14 // If this file is included outside of libjingle (e.g. in wrapper code) it
     15 // should be included after base/logging.h (if any) or compiler error or
     16 // unexpected behavior may occur (macros that have the same name in libjingle as
     17 // in chromium will use the libjingle definition if this file is included
     18 // first).
     19 
     20 // Setting the LoggingSeverity (and lower) that should be written to file should
     21 // be done via command line by specifying the flags:
     22 // --vmodule or --v please see base/logging.h for details on how to use them.
     23 // Specifying what file to write to is done using InitLogging also in
     24 // base/logging.h.
     25 
     26 // The macros and classes declared in here are not described as they are
     27 // NOT TO BE USED outside of libjingle.
     28 
     29 #ifndef THIRD_PARTY_LIBJINGLE_OVERRIDES_WEBRTC_BASE_LOGGING_H_
     30 #define THIRD_PARTY_LIBJINGLE_OVERRIDES_WEBRTC_BASE_LOGGING_H_
     31 
     32 #include <sstream>
     33 #include <string>
     34 
     35 #include "base/logging.h"
     36 #include "third_party/webrtc/base/scoped_ref_ptr.h"
     37 
     38 namespace rtc {
     39 
     40 ///////////////////////////////////////////////////////////////////////////////
     41 // ConstantLabel can be used to easily generate string names from constant
     42 // values.  This can be useful for logging descriptive names of error messages.
     43 // Usage:
     44 //   const ConstantLabel LIBRARY_ERRORS[] = {
     45 //     KLABEL(SOME_ERROR),
     46 //     KLABEL(SOME_OTHER_ERROR),
     47 //     ...
     48 //     LASTLABEL
     49 //   }
     50 //
     51 //   int err = LibraryFunc();
     52 //   LOG(LS_ERROR) << "LibraryFunc returned: "
     53 //                 << ErrorName(err, LIBRARY_ERRORS);
     54 
     55 struct ConstantLabel {
     56   int value;
     57   const char* label;
     58 };
     59 #define KLABEL(x) { x, #x }
     60 #define LASTLABEL { 0, 0 }
     61 
     62 const char* FindLabel(int value, const ConstantLabel entries[]);
     63 std::string ErrorName(int err, const ConstantLabel* err_table);
     64 
     65 //////////////////////////////////////////////////////////////////////
     66 // Note that the non-standard LoggingSeverity aliases exist because they are
     67 // still in broad use.  The meanings of the levels are:
     68 //  LS_SENSITIVE: Information which should only be logged with the consent
     69 //   of the user, due to privacy concerns.
     70 //  LS_VERBOSE: This level is for data which we do not want to appear in the
     71 //   normal debug log, but should appear in diagnostic logs.
     72 //  LS_INFO: Chatty level used in debugging for all sorts of things, the default
     73 //   in debug builds.
     74 //  LS_WARNING: Something that may warrant investigation.
     75 //  LS_ERROR: Something that should not have occurred.
     76 // Note that LoggingSeverity is mapped over to chromiums verbosity levels where
     77 // anything lower than or equal to the current verbosity level is written to
     78 // file which is the opposite of logging severity in libjingle where higher
     79 // severity numbers than or equal to the current severity level are written to
     80 // file. Also, note that the values are explicitly defined here for convenience
     81 // since the command line flag must be set using numerical values.
     82 enum LoggingSeverity { LS_ERROR = 1,
     83                        LS_WARNING = 2,
     84                        LS_INFO = 3,
     85                        LS_VERBOSE = 4,
     86                        LS_SENSITIVE = 5,
     87                        INFO = LS_INFO,
     88                        WARNING = LS_WARNING,
     89                        LERROR = LS_ERROR };
     90 
     91 // LogErrorContext assists in interpreting the meaning of an error value.
     92 enum LogErrorContext {
     93   ERRCTX_NONE,
     94   ERRCTX_ERRNO,     // System-local errno
     95   ERRCTX_HRESULT,   // Windows HRESULT
     96   ERRCTX_OSSTATUS,  // MacOS OSStatus
     97 
     98   // Abbreviations for LOG_E macro
     99   ERRCTX_EN = ERRCTX_ERRNO,     // LOG_E(sev, EN, x)
    100   ERRCTX_HR = ERRCTX_HRESULT,   // LOG_E(sev, HR, x)
    101   ERRCTX_OS = ERRCTX_OSSTATUS,  // LOG_E(sev, OS, x)
    102 };
    103 
    104 // Class that writes a log message to the logging delegate ("WebRTC logging
    105 // stream" in Chrome) and to Chrome's logging stream.
    106 class DiagnosticLogMessage {
    107  public:
    108   DiagnosticLogMessage(const char* file, int line, LoggingSeverity severity,
    109                        bool log_to_chrome, LogErrorContext err_ctx, int err);
    110   DiagnosticLogMessage(const char* file, int line, LoggingSeverity severity,
    111                        bool log_to_chrome, LogErrorContext err_ctx, int err,
    112                        const char* module);
    113   ~DiagnosticLogMessage();
    114 
    115   void CreateTimestamp();
    116 
    117   std::ostream& stream() { return print_stream_; }
    118 
    119  private:
    120   const char* file_name_;
    121   const int line_;
    122   const LoggingSeverity severity_;
    123   const bool log_to_chrome_;
    124 
    125   std::string extra_;
    126 
    127   std::ostringstream print_stream_;
    128 };
    129 
    130 // This class is used to explicitly ignore values in the conditional
    131 // logging macros.  This avoids compiler warnings like "value computed
    132 // is not used" and "statement has no effect".
    133 class LogMessageVoidify {
    134  public:
    135   LogMessageVoidify() { }
    136   // This has to be an operator with a precedence lower than << but
    137   // higher than ?:
    138   void operator&(std::ostream&) { }
    139 };
    140 
    141 //////////////////////////////////////////////////////////////////////
    142 // Logging Helpers
    143 //////////////////////////////////////////////////////////////////////
    144 
    145 class LogMultilineState {
    146  public:
    147   size_t unprintable_count_[2];
    148   LogMultilineState() {
    149     unprintable_count_[0] = unprintable_count_[1] = 0;
    150   }
    151 };
    152 
    153 class LogMessage {
    154  public:
    155   static void LogToDebug(int min_sev);
    156 };
    157 
    158 // When possible, pass optional state variable to track various data across
    159 // multiple calls to LogMultiline.  Otherwise, pass NULL.
    160 void LogMultiline(LoggingSeverity level, const char* label, bool input,
    161                   const void* data, size_t len, bool hex_mode,
    162                   LogMultilineState* state);
    163 
    164 // TODO(grunell): Change name to InitDiagnosticLoggingDelegate or
    165 // InitDiagnosticLogging. Change also in init_webrtc.h/cc.
    166 // TODO(grunell): typedef the delegate function.
    167 void InitDiagnosticLoggingDelegateFunction(
    168     void (*delegate)(const std::string&));
    169 
    170 void SetExtraLoggingInit(
    171     void (*function)(void (*delegate)(const std::string&)));
    172 }  // namespace rtc
    173 
    174 //////////////////////////////////////////////////////////////////////
    175 // Libjingle macros which are mapped over to their VLOG equivalent in
    176 // base/logging.h
    177 //////////////////////////////////////////////////////////////////////
    178 
    179 #if defined(LOGGING_INSIDE_WEBRTC)
    180 
    181 #define DIAGNOSTIC_LOG(sev, ctx, err, ...) \
    182   rtc::DiagnosticLogMessage( \
    183       __FILE__, __LINE__, sev, VLOG_IS_ON(sev), \
    184       rtc::ERRCTX_ ## ctx, err, ##__VA_ARGS__).stream()
    185 
    186 #define LOG_CHECK_LEVEL(sev) VLOG_IS_ON(rtc::sev)
    187 #define LOG_CHECK_LEVEL_V(sev) VLOG_IS_ON(sev)
    188 
    189 #define LOG_V(sev) DIAGNOSTIC_LOG(sev, NONE, 0)
    190 #undef LOG
    191 #define LOG(sev) DIAGNOSTIC_LOG(rtc::sev, NONE, 0)
    192 
    193 // The _F version prefixes the message with the current function name.
    194 #if defined(__GNUC__) && defined(_DEBUG)
    195 #define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": "
    196 #else
    197 #define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": "
    198 #endif
    199 
    200 #define LOG_E(sev, ctx, err, ...) \
    201   DIAGNOSTIC_LOG(rtc::sev, ctx, err, ##__VA_ARGS__)
    202 
    203 #undef LOG_ERRNO_EX
    204 #define LOG_ERRNO_EX(sev, err) LOG_E(sev, ERRNO, err)
    205 #undef LOG_ERRNO
    206 #define LOG_ERRNO(sev) LOG_ERRNO_EX(sev, errno)
    207 
    208 #if defined(WEBRTC_WIN)
    209 #define LOG_GLE_EX(sev, err) LOG_E(sev, HRESULT, err)
    210 #define LOG_GLE(sev) LOG_GLE_EX(sev, GetLastError())
    211 #define LOG_GLEM(sev, mod) LOG_E(sev, HRESULT, GetLastError(), mod)
    212 #define LOG_ERR_EX(sev, err) LOG_GLE_EX(sev, err)
    213 #define LOG_ERR(sev) LOG_GLE(sev)
    214 #define LAST_SYSTEM_ERROR (::GetLastError())
    215 #else
    216 #define LOG_ERR_EX(sev, err) LOG_ERRNO_EX(sev, err)
    217 #define LOG_ERR(sev) LOG_ERRNO(sev)
    218 #define LAST_SYSTEM_ERROR (errno)
    219 #endif  // OS_WIN
    220 
    221 #undef PLOG
    222 #define PLOG(sev, err) LOG_ERR_EX(sev, err)
    223 
    224 #endif  // LOGGING_INSIDE_WEBRTC
    225 
    226 #endif  // THIRD_PARTY_LIBJINGLE_OVERRIDES_WEBRTC_BASE_LOGGING_H_
    227