1d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org/*
2d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org *
4d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org */
10d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
11d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// This is a highly stripped-down version of libjingle's talk/base/logging.h.
12d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// It is a thin wrapper around WEBRTC_TRACE, maintaining the libjingle log
13d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// semantics to ease a transition to that format.
14d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
15bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org// NOTE: LS_INFO maps to a new trace level which should be reserved for
16bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org// infrequent, non-verbose logs. The other levels below kTraceWarning have been
17bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org// rendered essentially useless due to their verbosity. Carefully consider the
18bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org// impact of adding a new LS_INFO log. If it will be logged at anything
19bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org// approaching a frame or packet frequency, use LS_VERBOSE if necessary, or
20bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org// preferably, do not log at all.
21bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org
22d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   LOG(...) an ostream target that can be used to send formatted
23d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// output to a variety of logging targets, such as debugger console, stderr,
24d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// file, or any StreamInterface.
25d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   The severity level passed as the first argument to the LOGging
26d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// functions is used as a filter, to limit the verbosity of the logging.
27d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   Static members of LogMessage documented below are used to control the
28d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// verbosity and target of the output.
29d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   There are several variations on the LOG macro which facilitate logging
30d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// of common error conditions, detailed below.
31d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
32d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// LOG(sev) logs the given stream at severity "sev", which must be a
33d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//     compile-time constant of the LoggingSeverity type, without the namespace
34d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//     prefix.
35d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// LOG_V(sev) Like LOG(), but sev is a run-time variable of the LoggingSeverity
36d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//     type (basically, it just doesn't prepend the namespace).
37d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// LOG_F(sev) Like LOG(), but includes the name of the current function.
38d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
39d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// Additional helper macros added by WebRTC:
40d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// LOG_API is a shortcut for API call logging. Pass in the input parameters of
41d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// the method. For example:
42d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   Foo(int bar, int baz) {
43d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//     LOG_API2(bar, baz);
44d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   }
45d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//
46d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// LOG_FERR is a shortcut for logging a failed function call. For example:
47d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   if (!Foo(bar)) {
48bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org//     LOG_FERR1(LS_WARNING, Foo, bar);
49d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   }
50d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
51d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_
52d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_
53d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
54d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#include <sstream>
55d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
56d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.orgnamespace webrtc {
57d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
58d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//////////////////////////////////////////////////////////////////////
59d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
60d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// Note that the non-standard LoggingSeverity aliases exist because they are
61d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// still in broad use.  The meanings of the levels are:
62d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//  LS_SENSITIVE: Information which should only be logged with the consent
63d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   of the user, due to privacy concerns.
64d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//  LS_VERBOSE: This level is for data which we do not want to appear in the
65d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   normal debug log, but should appear in diagnostic logs.
66d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//  LS_INFO: Chatty level used in debugging for all sorts of things, the default
67d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//   in debug builds.
68d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//  LS_WARNING: Something that may warrant investigation.
69d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//  LS_ERROR: Something that should not have occurred.
70bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.orgenum LoggingSeverity {
71bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org  LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR
72bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org};
73d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
74d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.orgclass LogMessage {
75d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org public:
76d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  LogMessage(const char* file, int line, LoggingSeverity sev);
77d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  ~LogMessage();
78d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
7906eaa5465d57f416c14bb3a587ba4146290d6a58andrew@webrtc.org  static bool Loggable(LoggingSeverity sev);
80d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  std::ostream& stream() { return print_stream_; }
81d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
82d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org private:
83d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  // The ostream that buffers the formatted message before output
84d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  std::ostringstream print_stream_;
85d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
86d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  // The severity level of this message
87d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  LoggingSeverity severity_;
88d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org};
89d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
90d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//////////////////////////////////////////////////////////////////////
91804d5527f49d09d2b4d2f462532abd78c905bff7andrew@webrtc.org// Macros which automatically disable logging when WEBRTC_LOGGING == 0
92d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org//////////////////////////////////////////////////////////////////////
93d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
94d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#ifndef LOG
95d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// The following non-obvious technique for implementation of a
96d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// conditional log stream was stolen from google3/base/logging.h.
97d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
98d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// This class is used to explicitly ignore values in the conditional
99d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// logging macros.  This avoids compiler warnings like "value computed
100d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// is not used" and "statement has no effect".
101d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
102d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.orgclass LogMessageVoidify {
103d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org public:
104d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  LogMessageVoidify() { }
105d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  // This has to be an operator with a precedence lower than << but
106d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  // higher than ?:
107d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org  void operator&(std::ostream&) { }
108d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org};
109d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
1109705beb71497537569f82b7b0e3a0175c4214ed2andrew@webrtc.org#if defined(WEBRTC_RESTRICT_LOGGING)
1119705beb71497537569f82b7b0e3a0175c4214ed2andrew@webrtc.org// This should compile away logs matching the following condition.
1129705beb71497537569f82b7b0e3a0175c4214ed2andrew@webrtc.org#define RESTRICT_LOGGING_PRECONDITION(sev)  \
113b89fa697afa12adf1f3501eab484125e28713125henrikg@webrtc.org  sev < webrtc::LS_INFO ? (void) 0 :
1149705beb71497537569f82b7b0e3a0175c4214ed2andrew@webrtc.org#else
1159705beb71497537569f82b7b0e3a0175c4214ed2andrew@webrtc.org#define RESTRICT_LOGGING_PRECONDITION(sev)
1169705beb71497537569f82b7b0e3a0175c4214ed2andrew@webrtc.org#endif
1179705beb71497537569f82b7b0e3a0175c4214ed2andrew@webrtc.org
11806eaa5465d57f416c14bb3a587ba4146290d6a58andrew@webrtc.org#define LOG_SEVERITY_PRECONDITION(sev) \
1199705beb71497537569f82b7b0e3a0175c4214ed2andrew@webrtc.org  RESTRICT_LOGGING_PRECONDITION(sev) !(webrtc::LogMessage::Loggable(sev)) \
12006eaa5465d57f416c14bb3a587ba4146290d6a58andrew@webrtc.org    ? (void) 0 \
12106eaa5465d57f416c14bb3a587ba4146290d6a58andrew@webrtc.org    : webrtc::LogMessageVoidify() &
12206eaa5465d57f416c14bb3a587ba4146290d6a58andrew@webrtc.org
123d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG(sev) \
12406eaa5465d57f416c14bb3a587ba4146290d6a58andrew@webrtc.org  LOG_SEVERITY_PRECONDITION(webrtc::sev) \
125d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org    webrtc::LogMessage(__FILE__, __LINE__, webrtc::sev).stream()
126d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
127d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// The _V version is for when a variable is passed in.  It doesn't do the
128d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// namespace concatination.
129d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG_V(sev) \
13006eaa5465d57f416c14bb3a587ba4146290d6a58andrew@webrtc.org  LOG_SEVERITY_PRECONDITION(sev) \
131d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org    webrtc::LogMessage(__FILE__, __LINE__, sev).stream()
132d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
133d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org// The _F version prefixes the message with the current function name.
134d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#if (defined(__GNUC__) && defined(_DEBUG)) || defined(WANT_PRETTY_LOG_F)
135d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": "
136d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#else
137d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": "
138d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#endif
139d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
140bc687c51d87cbcc52ff13b29ea96062c593bb90bandrew@webrtc.org#define LOG_API0() LOG_F(LS_VERBOSE)
141d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG_API1(v1) LOG_API0() << #v1 << "=" << v1
142d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG_API2(v1, v2) LOG_API1(v1) \
143d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org    << ", " << #v2 << "=" << v2
144d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG_API3(v1, v2, v3) LOG_API2(v1, v2) \
145d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org    << ", " << #v3 << "=" << v3
146d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
147d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG_FERR0(sev, func) LOG(sev) << #func << " failed"
148d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG_FERR1(sev, func, v1) LOG_FERR0(sev, func) \
149d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org    << ": " << #v1 << "=" << v1
150d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG_FERR2(sev, func, v1, v2) LOG_FERR1(sev, func, v1) \
151d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org    << ", " << #v2 << "=" << v2
152d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#define LOG_FERR3(sev, func, v1, v2, v3) LOG_FERR2(sev, func, v1, v2) \
153d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org    << ", " << #v3 << "=" << v3
15492bfbbd61bc6be8506644a52e13a3bef00e0d292andrew@webrtc.org#define LOG_FERR4(sev, func, v1, v2, v3, v4) LOG_FERR3(sev, func, v1, v2, v3) \
15592bfbbd61bc6be8506644a52e13a3bef00e0d292andrew@webrtc.org    << ", " << #v4 << "=" << v4
156d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
157d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#endif  // LOG
158d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
159d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org}  // namespace webrtc
160d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org
161d898c019c4e09c73bc7354da9f1b54004f3e4b7eandrew@webrtc.org#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_
162