blob: 1085fefa9caf35cb19ba544c835e208731ef443c [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
andrew@webrtc.org655d8f52012-11-20 07:34:45 +000015// 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
andrew@webrtc.org50419b02012-11-14 19:07:54 +000022// 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)) {
andrew@webrtc.org655d8f52012-11-20 07:34:45 +000048// LOG_FERR1(LS_WARNING, Foo, bar);
andrew@webrtc.org50419b02012-11-14 19:07:54 +000049// }
50
51#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_
52#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_
53
54#include <sstream>
55
56namespace 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.
andrew@webrtc.org655d8f52012-11-20 07:34:45 +000070enum LoggingSeverity {
71 LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR
72};
andrew@webrtc.org50419b02012-11-14 19:07:54 +000073
74class LogMessage {
75 public:
76 LogMessage(const char* file, int line, LoggingSeverity sev);
77 ~LogMessage();
78
79 std::ostream& stream() { return print_stream_; }
80
81 private:
andrew@webrtc.org50419b02012-11-14 19:07:54 +000082 // The ostream that buffers the formatted message before output
83 std::ostringstream print_stream_;
84
85 // The severity level of this message
86 LoggingSeverity severity_;
87};
88
89//////////////////////////////////////////////////////////////////////
andrew@webrtc.orgc3e5d342012-11-23 19:30:59 +000090// Macros which automatically disable logging when WEBRTC_LOGGING == 0
andrew@webrtc.org50419b02012-11-14 19:07:54 +000091//////////////////////////////////////////////////////////////////////
92
andrew@webrtc.org50419b02012-11-14 19:07:54 +000093#ifndef LOG
andrew@webrtc.orgc3e5d342012-11-23 19:30:59 +000094#if defined(WEBRTC_LOGGING)
andrew@webrtc.org50419b02012-11-14 19:07:54 +000095
96// The following non-obvious technique for implementation of a
97// conditional log stream was stolen from google3/base/logging.h.
98
99// This class is used to explicitly ignore values in the conditional
100// logging macros. This avoids compiler warnings like "value computed
101// is not used" and "statement has no effect".
102
103class LogMessageVoidify {
104 public:
105 LogMessageVoidify() { }
106 // This has to be an operator with a precedence lower than << but
107 // higher than ?:
108 void operator&(std::ostream&) { }
109};
110
111#define LOG(sev) \
112 webrtc::LogMessage(__FILE__, __LINE__, webrtc::sev).stream()
113
114// The _V version is for when a variable is passed in. It doesn't do the
115// namespace concatination.
116#define LOG_V(sev) \
117 webrtc::LogMessage(__FILE__, __LINE__, sev).stream()
118
119// The _F version prefixes the message with the current function name.
120#if (defined(__GNUC__) && defined(_DEBUG)) || defined(WANT_PRETTY_LOG_F)
121#define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": "
122#else
123#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": "
124#endif
125
andrew@webrtc.orgc3e5d342012-11-23 19:30:59 +0000126#else // !defined(WEBRTC_LOGGING)
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000127
128// Hopefully, the compiler will optimize away some of this code.
129// Note: syntax of "1 ? (void)0 : LogMessage" was causing errors in g++,
130// converted to "while (false)"
131#define LOG(sev) \
132 while (false)webrtc::LogMessage(NULL, 0, webrtc::sev).stream()
133#define LOG_V(sev) \
134 while (false) webrtc::LogMessage(NULL, 0, sev).stream()
135#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": "
136
andrew@webrtc.orgc3e5d342012-11-23 19:30:59 +0000137#endif // !defined(WEBRTC_LOGGING)
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000138
andrew@webrtc.org655d8f52012-11-20 07:34:45 +0000139#define LOG_API0() LOG_F(LS_VERBOSE)
andrew@webrtc.org50419b02012-11-14 19:07:54 +0000140#define LOG_API1(v1) LOG_API0() << #v1 << "=" << v1
141#define LOG_API2(v1, v2) LOG_API1(v1) \
142 << ", " << #v2 << "=" << v2
143#define LOG_API3(v1, v2, v3) LOG_API2(v1, v2) \
144 << ", " << #v3 << "=" << v3
145
146#define LOG_FERR0(sev, func) LOG(sev) << #func << " failed"
147#define LOG_FERR1(sev, func, v1) LOG_FERR0(sev, func) \
148 << ": " << #v1 << "=" << v1
149#define LOG_FERR2(sev, func, v1, v2) LOG_FERR1(sev, func, v1) \
150 << ", " << #v2 << "=" << v2
151#define LOG_FERR3(sev, func, v1, v2, v3) LOG_FERR2(sev, func, v1, v2) \
152 << ", " << #v3 << "=" << v3
153
154#endif // LOG
155
156} // namespace webrtc
157
158#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_