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
38namespace 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
55struct ConstantLabel {
56  int value;
57  const char* label;
58};
59#define KLABEL(x) { x, #x }
60#define LASTLABEL { 0, 0 }
61
62const char* FindLabel(int value, const ConstantLabel entries[]);
63std::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.
82enum 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.
92enum 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.
106class 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".
133class 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
145class LogMultilineState {
146 public:
147  size_t unprintable_count_[2];
148  LogMultilineState() {
149    unprintable_count_[0] = unprintable_count_[1] = 0;
150  }
151};
152
153class 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.
160void 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.
167void InitDiagnosticLoggingDelegateFunction(
168    void (*delegate)(const std::string&));
169
170void 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