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