• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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