blob: ef6fb8ddb1ff6de56b0206742ae8cf1bae1a3295 [file] [log] [blame]
andrew@webrtc.org50419b02012-11-14 19:07:54 +00001/*
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// LOG(...) an ostream target that can be used to send formatted
16// output to a variety of logging targets, such as debugger console, stderr,
17// file, or any StreamInterface.
18// The severity level passed as the first argument to the LOGging
19// functions is used as a filter, to limit the verbosity of the logging.
20// Static members of LogMessage documented below are used to control the
21// verbosity and target of the output.
22// There are several variations on the LOG macro which facilitate logging
23// of common error conditions, detailed below.
24
25// LOG(sev) logs the given stream at severity "sev", which must be a
26// compile-time constant of the LoggingSeverity type, without the namespace
27// prefix.
28// LOG_V(sev) Like LOG(), but sev is a run-time variable of the LoggingSeverity
29// type (basically, it just doesn't prepend the namespace).
30// LOG_F(sev) Like LOG(), but includes the name of the current function.
31
32// Additional helper macros added by WebRTC:
33// LOG_API is a shortcut for API call logging. Pass in the input parameters of
34// the method. For example:
35// Foo(int bar, int baz) {
36// LOG_API2(bar, baz);
37// }
38//
39// LOG_FERR is a shortcut for logging a failed function call. For example:
40// if (!Foo(bar)) {
41// LOG_FERR1(WARNING, Foo, bar);
42// }
43
44#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_
45#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_
46
47#include <sstream>
48
49namespace webrtc {
50
51//////////////////////////////////////////////////////////////////////
52
53// Note that the non-standard LoggingSeverity aliases exist because they are
54// still in broad use. The meanings of the levels are:
55// LS_SENSITIVE: Information which should only be logged with the consent
56// of the user, due to privacy concerns.
57// LS_VERBOSE: This level is for data which we do not want to appear in the
58// normal debug log, but should appear in diagnostic logs.
59// LS_INFO: Chatty level used in debugging for all sorts of things, the default
60// in debug builds.
61// LS_WARNING: Something that may warrant investigation.
62// LS_ERROR: Something that should not have occurred.
63enum LoggingSeverity { LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR,
64 INFO = LS_INFO,
65 WARNING = LS_WARNING,
66 LERROR = LS_ERROR };
67
68class LogMessage {
69 public:
70 LogMessage(const char* file, int line, LoggingSeverity sev);
71 ~LogMessage();
72
73 std::ostream& stream() { return print_stream_; }
74
75 private:
76 // These assist in formatting some parts of the debug output.
77 static const char* DescribeFile(const char* file);
78
79 // The ostream that buffers the formatted message before output
80 std::ostringstream print_stream_;
81
82 // The severity level of this message
83 LoggingSeverity severity_;
84};
85
86//////////////////////////////////////////////////////////////////////
87// Macros which automatically disable logging when LOGGING == 0
88//////////////////////////////////////////////////////////////////////
89
90// If LOGGING is not explicitly defined, default to enabled in debug mode
91// TODO(andrew): We explictly enable here; handle in gyp instead.
92#define LOGGING 1
93#if !defined(LOGGING)
94#if defined(_DEBUG) && !defined(NDEBUG)
95#define LOGGING 1
96#else
97#define LOGGING 0
98#endif
99#endif // !defined(LOGGING)
100
101#ifndef LOG
102#if LOGGING
103
104// The following non-obvious technique for implementation of a
105// conditional log stream was stolen from google3/base/logging.h.
106
107// This class is used to explicitly ignore values in the conditional
108// logging macros. This avoids compiler warnings like "value computed
109// is not used" and "statement has no effect".
110
111class LogMessageVoidify {
112 public:
113 LogMessageVoidify() { }
114 // This has to be an operator with a precedence lower than << but
115 // higher than ?:
116 void operator&(std::ostream&) { }
117};
118
119#define LOG(sev) \
120 webrtc::LogMessage(__FILE__, __LINE__, webrtc::sev).stream()
121
122// The _V version is for when a variable is passed in. It doesn't do the
123// namespace concatination.
124#define LOG_V(sev) \
125 webrtc::LogMessage(__FILE__, __LINE__, sev).stream()
126
127// The _F version prefixes the message with the current function name.
128#if (defined(__GNUC__) && defined(_DEBUG)) || defined(WANT_PRETTY_LOG_F)
129#define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": "
130#else
131#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": "
132#endif
133
134#else // !LOGGING
135
136// Hopefully, the compiler will optimize away some of this code.
137// Note: syntax of "1 ? (void)0 : LogMessage" was causing errors in g++,
138// converted to "while (false)"
139#define LOG(sev) \
140 while (false)webrtc::LogMessage(NULL, 0, webrtc::sev).stream()
141#define LOG_V(sev) \
142 while (false) webrtc::LogMessage(NULL, 0, sev).stream()
143#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": "
144
145#endif // !LOGGING
146
147#define LOG_API0() LOG_F(LS_INFO)
148#define LOG_API1(v1) LOG_API0() << #v1 << "=" << v1
149#define LOG_API2(v1, v2) LOG_API1(v1) \
150 << ", " << #v2 << "=" << v2
151#define LOG_API3(v1, v2, v3) LOG_API2(v1, v2) \
152 << ", " << #v3 << "=" << v3
153
154#define LOG_FERR0(sev, func) LOG(sev) << #func << " failed"
155#define LOG_FERR1(sev, func, v1) LOG_FERR0(sev, func) \
156 << ": " << #v1 << "=" << v1
157#define LOG_FERR2(sev, func, v1, v2) LOG_FERR1(sev, func, v1) \
158 << ", " << #v2 << "=" << v2
159#define LOG_FERR3(sev, func, v1, v2, v3) LOG_FERR2(sev, func, v1, v2) \
160 << ", " << #v3 << "=" << v3
161
162#endif // LOG
163
164} // namespace webrtc
165
166#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_