xref: /aosp_15_r20/external/webrtc/rtc_base/logging.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker // RTC_LOG(...) an ostream target that can be used to send formatted
12*d9f75844SAndroid Build Coastguard Worker // output to a variety of logging targets, such as debugger console, stderr,
13*d9f75844SAndroid Build Coastguard Worker // or any LogSink.
14*d9f75844SAndroid Build Coastguard Worker // The severity level passed as the first argument to the logging
15*d9f75844SAndroid Build Coastguard Worker // functions is used as a filter, to limit the verbosity of the logging.
16*d9f75844SAndroid Build Coastguard Worker // Static members of LogMessage documented below are used to control the
17*d9f75844SAndroid Build Coastguard Worker // verbosity and target of the output.
18*d9f75844SAndroid Build Coastguard Worker // There are several variations on the RTC_LOG macro which facilitate logging
19*d9f75844SAndroid Build Coastguard Worker // of common error conditions, detailed below.
20*d9f75844SAndroid Build Coastguard Worker 
21*d9f75844SAndroid Build Coastguard Worker // RTC_LOG(sev) logs the given stream at severity "sev", which must be a
22*d9f75844SAndroid Build Coastguard Worker //     compile-time constant of the LoggingSeverity type, without the namespace
23*d9f75844SAndroid Build Coastguard Worker //     prefix.
24*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_IF(sev, condition) logs the given stream at severitye "sev" if
25*d9f75844SAndroid Build Coastguard Worker //     "condition" is true.
26*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_V(sev) Like RTC_LOG(), but sev is a run-time variable of the
27*d9f75844SAndroid Build Coastguard Worker //     LoggingSeverity type (basically, it just doesn't prepend the namespace).
28*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_F(sev) Like RTC_LOG(), but includes the name of the current function.
29*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_IF_F(sev, condition), Like RTC_LOG_IF(), but includes the name of
30*d9f75844SAndroid Build Coastguard Worker //     the current function.
31*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_T(sev) Like RTC_LOG(), but includes the this pointer.
32*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_T_F(sev) Like RTC_LOG_F(), but includes the this pointer.
33*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_GLE(sev [, mod]) attempt to add a string description of the
34*d9f75844SAndroid Build Coastguard Worker //     HRESULT returned by GetLastError.
35*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_ERRNO(sev) attempts to add a string description of an errno-derived
36*d9f75844SAndroid Build Coastguard Worker //     error. errno and associated facilities exist on both Windows and POSIX,
37*d9f75844SAndroid Build Coastguard Worker //     but on Windows they only apply to the C/C++ runtime.
38*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_ERR(sev) is an alias for the platform's normal error system, i.e.
39*d9f75844SAndroid Build Coastguard Worker //     _GLE on Windows and _ERRNO on POSIX.
40*d9f75844SAndroid Build Coastguard Worker // (The above three also all have _EX versions that let you specify the error
41*d9f75844SAndroid Build Coastguard Worker // code, rather than using the last one.)
42*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_E(sev, ctx, err, ...) logs a detailed error interpreted using the
43*d9f75844SAndroid Build Coastguard Worker //     specified context.
44*d9f75844SAndroid Build Coastguard Worker // RTC_LOG_CHECK_LEVEL(sev) (and RTC_LOG_CHECK_LEVEL_V(sev)) can be used as a
45*d9f75844SAndroid Build Coastguard Worker //     test before performing expensive or sensitive operations whose sole
46*d9f75844SAndroid Build Coastguard Worker //     purpose is to output logging data at the desired level.
47*d9f75844SAndroid Build Coastguard Worker 
48*d9f75844SAndroid Build Coastguard Worker #ifndef RTC_BASE_LOGGING_H_
49*d9f75844SAndroid Build Coastguard Worker #define RTC_BASE_LOGGING_H_
50*d9f75844SAndroid Build Coastguard Worker 
51*d9f75844SAndroid Build Coastguard Worker #include <errno.h>
52*d9f75844SAndroid Build Coastguard Worker 
53*d9f75844SAndroid Build Coastguard Worker #include <atomic>
54*d9f75844SAndroid Build Coastguard Worker #include <sstream>  // no-presubmit-check TODO(webrtc:8982)
55*d9f75844SAndroid Build Coastguard Worker #include <string>
56*d9f75844SAndroid Build Coastguard Worker #include <type_traits>
57*d9f75844SAndroid Build Coastguard Worker #include <utility>
58*d9f75844SAndroid Build Coastguard Worker 
59*d9f75844SAndroid Build Coastguard Worker #include "absl/base/attributes.h"
60*d9f75844SAndroid Build Coastguard Worker #include "absl/meta/type_traits.h"
61*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
62*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
63*d9f75844SAndroid Build Coastguard Worker #include "api/units/timestamp.h"
64*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/platform_thread_types.h"
65*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
66*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/inline.h"
67*d9f75844SAndroid Build Coastguard Worker 
68*d9f75844SAndroid Build Coastguard Worker #if !defined(NDEBUG) || defined(DLOG_ALWAYS_ON)
69*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_IS_ON 1
70*d9f75844SAndroid Build Coastguard Worker #else
71*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_IS_ON 0
72*d9f75844SAndroid Build Coastguard Worker #endif
73*d9f75844SAndroid Build Coastguard Worker 
74*d9f75844SAndroid Build Coastguard Worker #if defined(RTC_DISABLE_LOGGING)
75*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_ENABLED() 0
76*d9f75844SAndroid Build Coastguard Worker #else
77*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_ENABLED() 1
78*d9f75844SAndroid Build Coastguard Worker #endif
79*d9f75844SAndroid Build Coastguard Worker 
80*d9f75844SAndroid Build Coastguard Worker namespace rtc {
81*d9f75844SAndroid Build Coastguard Worker 
82*d9f75844SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////
83*d9f75844SAndroid Build Coastguard Worker // The meanings of the levels are:
84*d9f75844SAndroid Build Coastguard Worker //  LS_VERBOSE: This level is for data which we do not want to appear in the
85*d9f75844SAndroid Build Coastguard Worker //   normal debug log, but should appear in diagnostic logs.
86*d9f75844SAndroid Build Coastguard Worker //  LS_INFO: Chatty level used in debugging for all sorts of things, the default
87*d9f75844SAndroid Build Coastguard Worker //   in debug builds.
88*d9f75844SAndroid Build Coastguard Worker //  LS_WARNING: Something that may warrant investigation.
89*d9f75844SAndroid Build Coastguard Worker //  LS_ERROR: Something that should not have occurred.
90*d9f75844SAndroid Build Coastguard Worker //  LS_NONE: Don't log.
91*d9f75844SAndroid Build Coastguard Worker enum LoggingSeverity {
92*d9f75844SAndroid Build Coastguard Worker   LS_VERBOSE,
93*d9f75844SAndroid Build Coastguard Worker   LS_INFO,
94*d9f75844SAndroid Build Coastguard Worker   LS_WARNING,
95*d9f75844SAndroid Build Coastguard Worker   LS_ERROR,
96*d9f75844SAndroid Build Coastguard Worker   LS_NONE,
97*d9f75844SAndroid Build Coastguard Worker };
98*d9f75844SAndroid Build Coastguard Worker 
99*d9f75844SAndroid Build Coastguard Worker // LogErrorContext assists in interpreting the meaning of an error value.
100*d9f75844SAndroid Build Coastguard Worker enum LogErrorContext {
101*d9f75844SAndroid Build Coastguard Worker   ERRCTX_NONE,
102*d9f75844SAndroid Build Coastguard Worker   ERRCTX_ERRNO,    // System-local errno
103*d9f75844SAndroid Build Coastguard Worker   ERRCTX_HRESULT,  // Windows HRESULT
104*d9f75844SAndroid Build Coastguard Worker 
105*d9f75844SAndroid Build Coastguard Worker   // Abbreviations for LOG_E macro
106*d9f75844SAndroid Build Coastguard Worker   ERRCTX_EN = ERRCTX_ERRNO,    // LOG_E(sev, EN, x)
107*d9f75844SAndroid Build Coastguard Worker   ERRCTX_HR = ERRCTX_HRESULT,  // LOG_E(sev, HR, x)
108*d9f75844SAndroid Build Coastguard Worker };
109*d9f75844SAndroid Build Coastguard Worker 
110*d9f75844SAndroid Build Coastguard Worker class LogMessage;
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker // LogLineRef encapsulates all the information required to generate a log line.
113*d9f75844SAndroid Build Coastguard Worker // It is used both internally to LogMessage but also as a parameter to
114*d9f75844SAndroid Build Coastguard Worker // LogSink::OnLogMessage, allowing custom LogSinks to format the log in
115*d9f75844SAndroid Build Coastguard Worker // the most flexible way.
116*d9f75844SAndroid Build Coastguard Worker class LogLineRef {
117*d9f75844SAndroid Build Coastguard Worker  public:
message()118*d9f75844SAndroid Build Coastguard Worker   absl::string_view message() const { return message_; }
filename()119*d9f75844SAndroid Build Coastguard Worker   absl::string_view filename() const { return filename_; }
line()120*d9f75844SAndroid Build Coastguard Worker   int line() const { return line_; }
thread_id()121*d9f75844SAndroid Build Coastguard Worker   absl::optional<PlatformThreadId> thread_id() const { return thread_id_; }
timestamp()122*d9f75844SAndroid Build Coastguard Worker   webrtc::Timestamp timestamp() const { return timestamp_; }
tag()123*d9f75844SAndroid Build Coastguard Worker   absl::string_view tag() const { return tag_; }
severity()124*d9f75844SAndroid Build Coastguard Worker   LoggingSeverity severity() const { return severity_; }
125*d9f75844SAndroid Build Coastguard Worker 
126*d9f75844SAndroid Build Coastguard Worker #if RTC_LOG_ENABLED()
127*d9f75844SAndroid Build Coastguard Worker   std::string DefaultLogLine() const;
128*d9f75844SAndroid Build Coastguard Worker #else
DefaultLogLine()129*d9f75844SAndroid Build Coastguard Worker   std::string DefaultLogLine() const { return ""; }
130*d9f75844SAndroid Build Coastguard Worker #endif
131*d9f75844SAndroid Build Coastguard Worker 
132*d9f75844SAndroid Build Coastguard Worker  private:
133*d9f75844SAndroid Build Coastguard Worker   friend class LogMessage;
set_message(std::string message)134*d9f75844SAndroid Build Coastguard Worker   void set_message(std::string message) { message_ = std::move(message); }
set_filename(absl::string_view filename)135*d9f75844SAndroid Build Coastguard Worker   void set_filename(absl::string_view filename) { filename_ = filename; }
set_line(int line)136*d9f75844SAndroid Build Coastguard Worker   void set_line(int line) { line_ = line; }
set_thread_id(absl::optional<PlatformThreadId> thread_id)137*d9f75844SAndroid Build Coastguard Worker   void set_thread_id(absl::optional<PlatformThreadId> thread_id) {
138*d9f75844SAndroid Build Coastguard Worker     thread_id_ = thread_id;
139*d9f75844SAndroid Build Coastguard Worker   }
set_timestamp(webrtc::Timestamp timestamp)140*d9f75844SAndroid Build Coastguard Worker   void set_timestamp(webrtc::Timestamp timestamp) { timestamp_ = timestamp; }
set_tag(absl::string_view tag)141*d9f75844SAndroid Build Coastguard Worker   void set_tag(absl::string_view tag) { tag_ = tag; }
set_severity(LoggingSeverity severity)142*d9f75844SAndroid Build Coastguard Worker   void set_severity(LoggingSeverity severity) { severity_ = severity; }
143*d9f75844SAndroid Build Coastguard Worker 
144*d9f75844SAndroid Build Coastguard Worker   std::string message_;
145*d9f75844SAndroid Build Coastguard Worker   absl::string_view filename_;
146*d9f75844SAndroid Build Coastguard Worker   int line_ = 0;
147*d9f75844SAndroid Build Coastguard Worker   absl::optional<PlatformThreadId> thread_id_;
148*d9f75844SAndroid Build Coastguard Worker   webrtc::Timestamp timestamp_ = webrtc::Timestamp::MinusInfinity();
149*d9f75844SAndroid Build Coastguard Worker   // The default Android debug output tag.
150*d9f75844SAndroid Build Coastguard Worker   absl::string_view tag_ = "libjingle";
151*d9f75844SAndroid Build Coastguard Worker   // The severity level of this message
152*d9f75844SAndroid Build Coastguard Worker   LoggingSeverity severity_;
153*d9f75844SAndroid Build Coastguard Worker };
154*d9f75844SAndroid Build Coastguard Worker 
155*d9f75844SAndroid Build Coastguard Worker // Virtual sink interface that can receive log messages.
156*d9f75844SAndroid Build Coastguard Worker class LogSink {
157*d9f75844SAndroid Build Coastguard Worker  public:
LogSink()158*d9f75844SAndroid Build Coastguard Worker   LogSink() {}
~LogSink()159*d9f75844SAndroid Build Coastguard Worker   virtual ~LogSink() {}
160*d9f75844SAndroid Build Coastguard Worker   virtual void OnLogMessage(const std::string& msg,
161*d9f75844SAndroid Build Coastguard Worker                             LoggingSeverity severity,
162*d9f75844SAndroid Build Coastguard Worker                             const char* tag);
163*d9f75844SAndroid Build Coastguard Worker   virtual void OnLogMessage(const std::string& message,
164*d9f75844SAndroid Build Coastguard Worker                             LoggingSeverity severity);
165*d9f75844SAndroid Build Coastguard Worker   virtual void OnLogMessage(const std::string& message) = 0;
166*d9f75844SAndroid Build Coastguard Worker 
167*d9f75844SAndroid Build Coastguard Worker   virtual void OnLogMessage(absl::string_view msg,
168*d9f75844SAndroid Build Coastguard Worker                             LoggingSeverity severity,
169*d9f75844SAndroid Build Coastguard Worker                             const char* tag);
170*d9f75844SAndroid Build Coastguard Worker   virtual void OnLogMessage(absl::string_view message,
171*d9f75844SAndroid Build Coastguard Worker                             LoggingSeverity severity);
172*d9f75844SAndroid Build Coastguard Worker   virtual void OnLogMessage(absl::string_view message);
173*d9f75844SAndroid Build Coastguard Worker   virtual void OnLogMessage(const LogLineRef& line);
174*d9f75844SAndroid Build Coastguard Worker 
175*d9f75844SAndroid Build Coastguard Worker  private:
176*d9f75844SAndroid Build Coastguard Worker   friend class ::rtc::LogMessage;
177*d9f75844SAndroid Build Coastguard Worker #if RTC_LOG_ENABLED()
178*d9f75844SAndroid Build Coastguard Worker   // Members for LogMessage class to keep linked list of the registered sinks.
179*d9f75844SAndroid Build Coastguard Worker   LogSink* next_ = nullptr;
180*d9f75844SAndroid Build Coastguard Worker   LoggingSeverity min_severity_;
181*d9f75844SAndroid Build Coastguard Worker #endif
182*d9f75844SAndroid Build Coastguard Worker };
183*d9f75844SAndroid Build Coastguard Worker 
184*d9f75844SAndroid Build Coastguard Worker namespace webrtc_logging_impl {
185*d9f75844SAndroid Build Coastguard Worker 
186*d9f75844SAndroid Build Coastguard Worker class LogMetadata {
187*d9f75844SAndroid Build Coastguard Worker  public:
LogMetadata(const char * file,int line,LoggingSeverity severity)188*d9f75844SAndroid Build Coastguard Worker   LogMetadata(const char* file, int line, LoggingSeverity severity)
189*d9f75844SAndroid Build Coastguard Worker       : file_(file),
190*d9f75844SAndroid Build Coastguard Worker         line_and_sev_(static_cast<uint32_t>(line) << 3 | severity) {}
191*d9f75844SAndroid Build Coastguard Worker   LogMetadata() = default;
192*d9f75844SAndroid Build Coastguard Worker 
File()193*d9f75844SAndroid Build Coastguard Worker   const char* File() const { return file_; }
Line()194*d9f75844SAndroid Build Coastguard Worker   int Line() const { return line_and_sev_ >> 3; }
Severity()195*d9f75844SAndroid Build Coastguard Worker   LoggingSeverity Severity() const {
196*d9f75844SAndroid Build Coastguard Worker     return static_cast<LoggingSeverity>(line_and_sev_ & 0x7);
197*d9f75844SAndroid Build Coastguard Worker   }
198*d9f75844SAndroid Build Coastguard Worker 
199*d9f75844SAndroid Build Coastguard Worker  private:
200*d9f75844SAndroid Build Coastguard Worker   const char* file_;
201*d9f75844SAndroid Build Coastguard Worker 
202*d9f75844SAndroid Build Coastguard Worker   // Line number and severity, the former in the most significant 29 bits, the
203*d9f75844SAndroid Build Coastguard Worker   // latter in the least significant 3 bits. (This is an optimization; since
204*d9f75844SAndroid Build Coastguard Worker   // both numbers are usually compile-time constants, this way we can load them
205*d9f75844SAndroid Build Coastguard Worker   // both with a single instruction.)
206*d9f75844SAndroid Build Coastguard Worker   uint32_t line_and_sev_;
207*d9f75844SAndroid Build Coastguard Worker };
208*d9f75844SAndroid Build Coastguard Worker static_assert(std::is_trivial<LogMetadata>::value, "");
209*d9f75844SAndroid Build Coastguard Worker 
210*d9f75844SAndroid Build Coastguard Worker struct LogMetadataErr {
211*d9f75844SAndroid Build Coastguard Worker   LogMetadata meta;
212*d9f75844SAndroid Build Coastguard Worker   LogErrorContext err_ctx;
213*d9f75844SAndroid Build Coastguard Worker   int err;
214*d9f75844SAndroid Build Coastguard Worker };
215*d9f75844SAndroid Build Coastguard Worker 
216*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
217*d9f75844SAndroid Build Coastguard Worker struct LogMetadataTag {
218*d9f75844SAndroid Build Coastguard Worker   LoggingSeverity severity;
219*d9f75844SAndroid Build Coastguard Worker   const char* tag;
220*d9f75844SAndroid Build Coastguard Worker };
221*d9f75844SAndroid Build Coastguard Worker #endif
222*d9f75844SAndroid Build Coastguard Worker 
223*d9f75844SAndroid Build Coastguard Worker enum class LogArgType : int8_t {
224*d9f75844SAndroid Build Coastguard Worker   kEnd = 0,
225*d9f75844SAndroid Build Coastguard Worker   kInt,
226*d9f75844SAndroid Build Coastguard Worker   kLong,
227*d9f75844SAndroid Build Coastguard Worker   kLongLong,
228*d9f75844SAndroid Build Coastguard Worker   kUInt,
229*d9f75844SAndroid Build Coastguard Worker   kULong,
230*d9f75844SAndroid Build Coastguard Worker   kULongLong,
231*d9f75844SAndroid Build Coastguard Worker   kDouble,
232*d9f75844SAndroid Build Coastguard Worker   kLongDouble,
233*d9f75844SAndroid Build Coastguard Worker   kCharP,
234*d9f75844SAndroid Build Coastguard Worker   kStdString,
235*d9f75844SAndroid Build Coastguard Worker   kStringView,
236*d9f75844SAndroid Build Coastguard Worker   kVoidP,
237*d9f75844SAndroid Build Coastguard Worker   kLogMetadata,
238*d9f75844SAndroid Build Coastguard Worker   kLogMetadataErr,
239*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
240*d9f75844SAndroid Build Coastguard Worker   kLogMetadataTag,
241*d9f75844SAndroid Build Coastguard Worker #endif
242*d9f75844SAndroid Build Coastguard Worker };
243*d9f75844SAndroid Build Coastguard Worker 
244*d9f75844SAndroid Build Coastguard Worker // Wrapper for log arguments. Only ever make values of this type with the
245*d9f75844SAndroid Build Coastguard Worker // MakeVal() functions.
246*d9f75844SAndroid Build Coastguard Worker template <LogArgType N, typename T>
247*d9f75844SAndroid Build Coastguard Worker struct Val {
TypeVal248*d9f75844SAndroid Build Coastguard Worker   static constexpr LogArgType Type() { return N; }
GetValVal249*d9f75844SAndroid Build Coastguard Worker   T GetVal() const { return val; }
250*d9f75844SAndroid Build Coastguard Worker   T val;
251*d9f75844SAndroid Build Coastguard Worker };
252*d9f75844SAndroid Build Coastguard Worker 
253*d9f75844SAndroid Build Coastguard Worker // Case for when we need to construct a temp string and then print that.
254*d9f75844SAndroid Build Coastguard Worker // (We can't use Val<CheckArgType::kStdString, const std::string*>
255*d9f75844SAndroid Build Coastguard Worker // because we need somewhere to store the temp string.)
256*d9f75844SAndroid Build Coastguard Worker struct ToStringVal {
TypeToStringVal257*d9f75844SAndroid Build Coastguard Worker   static constexpr LogArgType Type() { return LogArgType::kStdString; }
GetValToStringVal258*d9f75844SAndroid Build Coastguard Worker   const std::string* GetVal() const { return &val; }
259*d9f75844SAndroid Build Coastguard Worker   std::string val;
260*d9f75844SAndroid Build Coastguard Worker };
261*d9f75844SAndroid Build Coastguard Worker 
MakeVal(int x)262*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kInt, int> MakeVal(int x) {
263*d9f75844SAndroid Build Coastguard Worker   return {x};
264*d9f75844SAndroid Build Coastguard Worker }
MakeVal(long x)265*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kLong, long> MakeVal(long x) {
266*d9f75844SAndroid Build Coastguard Worker   return {x};
267*d9f75844SAndroid Build Coastguard Worker }
MakeVal(long long x)268*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kLongLong, long long> MakeVal(long long x) {
269*d9f75844SAndroid Build Coastguard Worker   return {x};
270*d9f75844SAndroid Build Coastguard Worker }
MakeVal(unsigned int x)271*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kUInt, unsigned int> MakeVal(unsigned int x) {
272*d9f75844SAndroid Build Coastguard Worker   return {x};
273*d9f75844SAndroid Build Coastguard Worker }
MakeVal(unsigned long x)274*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kULong, unsigned long> MakeVal(unsigned long x) {
275*d9f75844SAndroid Build Coastguard Worker   return {x};
276*d9f75844SAndroid Build Coastguard Worker }
MakeVal(unsigned long long x)277*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kULongLong, unsigned long long> MakeVal(
278*d9f75844SAndroid Build Coastguard Worker     unsigned long long x) {
279*d9f75844SAndroid Build Coastguard Worker   return {x};
280*d9f75844SAndroid Build Coastguard Worker }
281*d9f75844SAndroid Build Coastguard Worker 
MakeVal(double x)282*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kDouble, double> MakeVal(double x) {
283*d9f75844SAndroid Build Coastguard Worker   return {x};
284*d9f75844SAndroid Build Coastguard Worker }
MakeVal(long double x)285*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kLongDouble, long double> MakeVal(long double x) {
286*d9f75844SAndroid Build Coastguard Worker   return {x};
287*d9f75844SAndroid Build Coastguard Worker }
288*d9f75844SAndroid Build Coastguard Worker 
MakeVal(const char * x)289*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kCharP, const char*> MakeVal(const char* x) {
290*d9f75844SAndroid Build Coastguard Worker   return {x};
291*d9f75844SAndroid Build Coastguard Worker }
MakeVal(const std::string & x)292*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kStdString, const std::string*> MakeVal(
293*d9f75844SAndroid Build Coastguard Worker     const std::string& x) {
294*d9f75844SAndroid Build Coastguard Worker   return {&x};
295*d9f75844SAndroid Build Coastguard Worker }
MakeVal(const absl::string_view & x)296*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kStringView, const absl::string_view*> MakeVal(
297*d9f75844SAndroid Build Coastguard Worker     const absl::string_view& x) {
298*d9f75844SAndroid Build Coastguard Worker   return {&x};
299*d9f75844SAndroid Build Coastguard Worker }
300*d9f75844SAndroid Build Coastguard Worker 
MakeVal(const void * x)301*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kVoidP, const void*> MakeVal(const void* x) {
302*d9f75844SAndroid Build Coastguard Worker   return {x};
303*d9f75844SAndroid Build Coastguard Worker }
304*d9f75844SAndroid Build Coastguard Worker 
MakeVal(const LogMetadata & x)305*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kLogMetadata, LogMetadata> MakeVal(
306*d9f75844SAndroid Build Coastguard Worker     const LogMetadata& x) {
307*d9f75844SAndroid Build Coastguard Worker   return {x};
308*d9f75844SAndroid Build Coastguard Worker }
MakeVal(const LogMetadataErr & x)309*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kLogMetadataErr, LogMetadataErr> MakeVal(
310*d9f75844SAndroid Build Coastguard Worker     const LogMetadataErr& x) {
311*d9f75844SAndroid Build Coastguard Worker   return {x};
312*d9f75844SAndroid Build Coastguard Worker }
313*d9f75844SAndroid Build Coastguard Worker 
314*d9f75844SAndroid Build Coastguard Worker // The enum class types are not implicitly convertible to arithmetic types.
315*d9f75844SAndroid Build Coastguard Worker template <typename T,
316*d9f75844SAndroid Build Coastguard Worker           absl::enable_if_t<std::is_enum<T>::value &&
317*d9f75844SAndroid Build Coastguard Worker                             !std::is_arithmetic<T>::value>* = nullptr>
decltype(MakeVal (std::declval<absl::underlying_type_t<T>> ()))318*d9f75844SAndroid Build Coastguard Worker inline decltype(MakeVal(std::declval<absl::underlying_type_t<T>>())) MakeVal(
319*d9f75844SAndroid Build Coastguard Worker     T x) {
320*d9f75844SAndroid Build Coastguard Worker   return {static_cast<absl::underlying_type_t<T>>(x)};
321*d9f75844SAndroid Build Coastguard Worker }
322*d9f75844SAndroid Build Coastguard Worker 
323*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
MakeVal(const LogMetadataTag & x)324*d9f75844SAndroid Build Coastguard Worker inline Val<LogArgType::kLogMetadataTag, LogMetadataTag> MakeVal(
325*d9f75844SAndroid Build Coastguard Worker     const LogMetadataTag& x) {
326*d9f75844SAndroid Build Coastguard Worker   return {x};
327*d9f75844SAndroid Build Coastguard Worker }
328*d9f75844SAndroid Build Coastguard Worker #endif
329*d9f75844SAndroid Build Coastguard Worker 
330*d9f75844SAndroid Build Coastguard Worker template <typename T, class = void>
331*d9f75844SAndroid Build Coastguard Worker struct has_to_log_string : std::false_type {};
332*d9f75844SAndroid Build Coastguard Worker template <typename T>
333*d9f75844SAndroid Build Coastguard Worker struct has_to_log_string<T,
334*d9f75844SAndroid Build Coastguard Worker                          absl::enable_if_t<std::is_convertible<
335*d9f75844SAndroid Build Coastguard Worker                              decltype(ToLogString(std::declval<T>())),
336*d9f75844SAndroid Build Coastguard Worker                              std::string>::value>> : std::true_type {};
337*d9f75844SAndroid Build Coastguard Worker 
338*d9f75844SAndroid Build Coastguard Worker template <typename T, absl::enable_if_t<has_to_log_string<T>::value>* = nullptr>
339*d9f75844SAndroid Build Coastguard Worker ToStringVal MakeVal(const T& x) {
340*d9f75844SAndroid Build Coastguard Worker   return {ToLogString(x)};
341*d9f75844SAndroid Build Coastguard Worker }
342*d9f75844SAndroid Build Coastguard Worker 
343*d9f75844SAndroid Build Coastguard Worker // Handle arbitrary types other than the above by falling back to stringstream.
344*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/9278): Get rid of this overload when callers don't need
345*d9f75844SAndroid Build Coastguard Worker // it anymore. No in-tree caller does, but some external callers still do.
346*d9f75844SAndroid Build Coastguard Worker template <
347*d9f75844SAndroid Build Coastguard Worker     typename T,
348*d9f75844SAndroid Build Coastguard Worker     typename T1 = absl::decay_t<T>,
349*d9f75844SAndroid Build Coastguard Worker     absl::enable_if_t<std::is_class<T1>::value &&
350*d9f75844SAndroid Build Coastguard Worker                       !std::is_same<T1, std::string>::value &&
351*d9f75844SAndroid Build Coastguard Worker                       !std::is_same<T1, LogMetadata>::value &&
352*d9f75844SAndroid Build Coastguard Worker                       !has_to_log_string<T1>::value &&
353*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
354*d9f75844SAndroid Build Coastguard Worker                       !std::is_same<T1, LogMetadataTag>::value &&
355*d9f75844SAndroid Build Coastguard Worker #endif
356*d9f75844SAndroid Build Coastguard Worker                       !std::is_same<T1, LogMetadataErr>::value>* = nullptr>
357*d9f75844SAndroid Build Coastguard Worker ToStringVal MakeVal(const T& x) {
358*d9f75844SAndroid Build Coastguard Worker   std::ostringstream os;  // no-presubmit-check TODO(webrtc:8982)
359*d9f75844SAndroid Build Coastguard Worker   os << x;
360*d9f75844SAndroid Build Coastguard Worker   return {os.str()};
361*d9f75844SAndroid Build Coastguard Worker }
362*d9f75844SAndroid Build Coastguard Worker 
363*d9f75844SAndroid Build Coastguard Worker #if RTC_LOG_ENABLED()
364*d9f75844SAndroid Build Coastguard Worker void Log(const LogArgType* fmt, ...);
365*d9f75844SAndroid Build Coastguard Worker #else
366*d9f75844SAndroid Build Coastguard Worker inline void Log(const LogArgType* fmt, ...) {
367*d9f75844SAndroid Build Coastguard Worker   // Do nothing, shouldn't be invoked
368*d9f75844SAndroid Build Coastguard Worker }
369*d9f75844SAndroid Build Coastguard Worker #endif
370*d9f75844SAndroid Build Coastguard Worker 
371*d9f75844SAndroid Build Coastguard Worker // Ephemeral type that represents the result of the logging << operator.
372*d9f75844SAndroid Build Coastguard Worker template <typename... Ts>
373*d9f75844SAndroid Build Coastguard Worker class LogStreamer;
374*d9f75844SAndroid Build Coastguard Worker 
375*d9f75844SAndroid Build Coastguard Worker // Base case: Before the first << argument.
376*d9f75844SAndroid Build Coastguard Worker template <>
377*d9f75844SAndroid Build Coastguard Worker class LogStreamer<> final {
378*d9f75844SAndroid Build Coastguard Worker  public:
379*d9f75844SAndroid Build Coastguard Worker   template <typename U,
380*d9f75844SAndroid Build Coastguard Worker             typename V = decltype(MakeVal(std::declval<U>())),
381*d9f75844SAndroid Build Coastguard Worker             absl::enable_if_t<std::is_arithmetic<U>::value ||
382*d9f75844SAndroid Build Coastguard Worker                               std::is_enum<U>::value>* = nullptr>
383*d9f75844SAndroid Build Coastguard Worker   RTC_FORCE_INLINE LogStreamer<V> operator<<(U arg) const {
384*d9f75844SAndroid Build Coastguard Worker     return LogStreamer<V>(MakeVal(arg), this);
385*d9f75844SAndroid Build Coastguard Worker   }
386*d9f75844SAndroid Build Coastguard Worker 
387*d9f75844SAndroid Build Coastguard Worker   template <typename U,
388*d9f75844SAndroid Build Coastguard Worker             typename V = decltype(MakeVal(std::declval<U>())),
389*d9f75844SAndroid Build Coastguard Worker             absl::enable_if_t<!std::is_arithmetic<U>::value &&
390*d9f75844SAndroid Build Coastguard Worker                               !std::is_enum<U>::value>* = nullptr>
391*d9f75844SAndroid Build Coastguard Worker   RTC_FORCE_INLINE LogStreamer<V> operator<<(const U& arg) const {
392*d9f75844SAndroid Build Coastguard Worker     return LogStreamer<V>(MakeVal(arg), this);
393*d9f75844SAndroid Build Coastguard Worker   }
394*d9f75844SAndroid Build Coastguard Worker 
395*d9f75844SAndroid Build Coastguard Worker   template <typename... Us>
396*d9f75844SAndroid Build Coastguard Worker   RTC_FORCE_INLINE static void Call(const Us&... args) {
397*d9f75844SAndroid Build Coastguard Worker     static constexpr LogArgType t[] = {Us::Type()..., LogArgType::kEnd};
398*d9f75844SAndroid Build Coastguard Worker     Log(t, args.GetVal()...);
399*d9f75844SAndroid Build Coastguard Worker   }
400*d9f75844SAndroid Build Coastguard Worker };
401*d9f75844SAndroid Build Coastguard Worker 
402*d9f75844SAndroid Build Coastguard Worker // Inductive case: We've already seen at least one << argument. The most recent
403*d9f75844SAndroid Build Coastguard Worker // one had type `T`, and the earlier ones had types `Ts`.
404*d9f75844SAndroid Build Coastguard Worker template <typename T, typename... Ts>
405*d9f75844SAndroid Build Coastguard Worker class LogStreamer<T, Ts...> final {
406*d9f75844SAndroid Build Coastguard Worker  public:
407*d9f75844SAndroid Build Coastguard Worker   RTC_FORCE_INLINE LogStreamer(T arg, const LogStreamer<Ts...>* prior)
408*d9f75844SAndroid Build Coastguard Worker       : arg_(arg), prior_(prior) {}
409*d9f75844SAndroid Build Coastguard Worker 
410*d9f75844SAndroid Build Coastguard Worker   template <typename U,
411*d9f75844SAndroid Build Coastguard Worker             typename V = decltype(MakeVal(std::declval<U>())),
412*d9f75844SAndroid Build Coastguard Worker             absl::enable_if_t<std::is_arithmetic<U>::value ||
413*d9f75844SAndroid Build Coastguard Worker                               std::is_enum<U>::value>* = nullptr>
414*d9f75844SAndroid Build Coastguard Worker   RTC_FORCE_INLINE LogStreamer<V, T, Ts...> operator<<(U arg) const {
415*d9f75844SAndroid Build Coastguard Worker     return LogStreamer<V, T, Ts...>(MakeVal(arg), this);
416*d9f75844SAndroid Build Coastguard Worker   }
417*d9f75844SAndroid Build Coastguard Worker 
418*d9f75844SAndroid Build Coastguard Worker   template <typename U,
419*d9f75844SAndroid Build Coastguard Worker             typename V = decltype(MakeVal(std::declval<U>())),
420*d9f75844SAndroid Build Coastguard Worker             absl::enable_if_t<!std::is_arithmetic<U>::value &&
421*d9f75844SAndroid Build Coastguard Worker                               !std::is_enum<U>::value>* = nullptr>
422*d9f75844SAndroid Build Coastguard Worker   RTC_FORCE_INLINE LogStreamer<V, T, Ts...> operator<<(const U& arg) const {
423*d9f75844SAndroid Build Coastguard Worker     return LogStreamer<V, T, Ts...>(MakeVal(arg), this);
424*d9f75844SAndroid Build Coastguard Worker   }
425*d9f75844SAndroid Build Coastguard Worker 
426*d9f75844SAndroid Build Coastguard Worker   template <typename... Us>
427*d9f75844SAndroid Build Coastguard Worker   RTC_FORCE_INLINE void Call(const Us&... args) const {
428*d9f75844SAndroid Build Coastguard Worker     prior_->Call(arg_, args...);
429*d9f75844SAndroid Build Coastguard Worker   }
430*d9f75844SAndroid Build Coastguard Worker 
431*d9f75844SAndroid Build Coastguard Worker  private:
432*d9f75844SAndroid Build Coastguard Worker   // The most recent argument.
433*d9f75844SAndroid Build Coastguard Worker   T arg_;
434*d9f75844SAndroid Build Coastguard Worker 
435*d9f75844SAndroid Build Coastguard Worker   // Earlier arguments.
436*d9f75844SAndroid Build Coastguard Worker   const LogStreamer<Ts...>* prior_;
437*d9f75844SAndroid Build Coastguard Worker };
438*d9f75844SAndroid Build Coastguard Worker 
439*d9f75844SAndroid Build Coastguard Worker class LogCall final {
440*d9f75844SAndroid Build Coastguard Worker  public:
441*d9f75844SAndroid Build Coastguard Worker   // This can be any binary operator with precedence lower than <<.
442*d9f75844SAndroid Build Coastguard Worker   // We return bool here to be able properly remove logging if
443*d9f75844SAndroid Build Coastguard Worker   // RTC_DISABLE_LOGGING is defined.
444*d9f75844SAndroid Build Coastguard Worker   template <typename... Ts>
445*d9f75844SAndroid Build Coastguard Worker   RTC_FORCE_INLINE bool operator&(const LogStreamer<Ts...>& streamer) {
446*d9f75844SAndroid Build Coastguard Worker     streamer.Call();
447*d9f75844SAndroid Build Coastguard Worker     return true;
448*d9f75844SAndroid Build Coastguard Worker   }
449*d9f75844SAndroid Build Coastguard Worker };
450*d9f75844SAndroid Build Coastguard Worker 
451*d9f75844SAndroid Build Coastguard Worker // This class is used to explicitly ignore values in the conditional
452*d9f75844SAndroid Build Coastguard Worker // logging macros.  This avoids compiler warnings like "value computed
453*d9f75844SAndroid Build Coastguard Worker // is not used" and "statement has no effect".
454*d9f75844SAndroid Build Coastguard Worker class LogMessageVoidify {
455*d9f75844SAndroid Build Coastguard Worker  public:
456*d9f75844SAndroid Build Coastguard Worker   LogMessageVoidify() = default;
457*d9f75844SAndroid Build Coastguard Worker   // This has to be an operator with a precedence lower than << but
458*d9f75844SAndroid Build Coastguard Worker   // higher than ?:
459*d9f75844SAndroid Build Coastguard Worker   template <typename... Ts>
460*d9f75844SAndroid Build Coastguard Worker   void operator&(LogStreamer<Ts...>&& streamer) {}
461*d9f75844SAndroid Build Coastguard Worker };
462*d9f75844SAndroid Build Coastguard Worker 
463*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc_logging_impl
464*d9f75844SAndroid Build Coastguard Worker 
465*d9f75844SAndroid Build Coastguard Worker // Direct use of this class is deprecated; please use the logging macros
466*d9f75844SAndroid Build Coastguard Worker // instead.
467*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/9278): Move this class to an unnamed namespace in the
468*d9f75844SAndroid Build Coastguard Worker // .cc file.
469*d9f75844SAndroid Build Coastguard Worker class LogMessage {
470*d9f75844SAndroid Build Coastguard Worker  public:
471*d9f75844SAndroid Build Coastguard Worker   // Same as the above, but using a compile-time constant for the logging
472*d9f75844SAndroid Build Coastguard Worker   // severity. This saves space at the call site, since passing an empty struct
473*d9f75844SAndroid Build Coastguard Worker   // is generally the same as not passing an argument at all.
474*d9f75844SAndroid Build Coastguard Worker   template <LoggingSeverity S>
475*d9f75844SAndroid Build Coastguard Worker   RTC_NO_INLINE LogMessage(const char* file,
476*d9f75844SAndroid Build Coastguard Worker                            int line,
477*d9f75844SAndroid Build Coastguard Worker                            std::integral_constant<LoggingSeverity, S>)
478*d9f75844SAndroid Build Coastguard Worker       : LogMessage(file, line, S) {}
479*d9f75844SAndroid Build Coastguard Worker 
480*d9f75844SAndroid Build Coastguard Worker #if RTC_LOG_ENABLED()
481*d9f75844SAndroid Build Coastguard Worker   LogMessage(const char* file, int line, LoggingSeverity sev);
482*d9f75844SAndroid Build Coastguard Worker   LogMessage(const char* file,
483*d9f75844SAndroid Build Coastguard Worker              int line,
484*d9f75844SAndroid Build Coastguard Worker              LoggingSeverity sev,
485*d9f75844SAndroid Build Coastguard Worker              LogErrorContext err_ctx,
486*d9f75844SAndroid Build Coastguard Worker              int err);
487*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_ANDROID)
488*d9f75844SAndroid Build Coastguard Worker   LogMessage(const char* file, int line, LoggingSeverity sev, const char* tag);
489*d9f75844SAndroid Build Coastguard Worker #endif
490*d9f75844SAndroid Build Coastguard Worker   ~LogMessage();
491*d9f75844SAndroid Build Coastguard Worker 
492*d9f75844SAndroid Build Coastguard Worker   LogMessage(const LogMessage&) = delete;
493*d9f75844SAndroid Build Coastguard Worker   LogMessage& operator=(const LogMessage&) = delete;
494*d9f75844SAndroid Build Coastguard Worker 
495*d9f75844SAndroid Build Coastguard Worker   void AddTag(const char* tag);
496*d9f75844SAndroid Build Coastguard Worker   rtc::StringBuilder& stream();
497*d9f75844SAndroid Build Coastguard Worker   // Returns the time at which this function was called for the first time.
498*d9f75844SAndroid Build Coastguard Worker   // The time will be used as the logging start time.
499*d9f75844SAndroid Build Coastguard Worker   // If this is not called externally, the LogMessage ctor also calls it, in
500*d9f75844SAndroid Build Coastguard Worker   // which case the logging start time will be the time of the first LogMessage
501*d9f75844SAndroid Build Coastguard Worker   // instance is created.
502*d9f75844SAndroid Build Coastguard Worker   static int64_t LogStartTime();
503*d9f75844SAndroid Build Coastguard Worker   // Returns the wall clock equivalent of `LogStartTime`, in seconds from the
504*d9f75844SAndroid Build Coastguard Worker   // epoch.
505*d9f75844SAndroid Build Coastguard Worker   static uint32_t WallClockStartTime();
506*d9f75844SAndroid Build Coastguard Worker   //  LogThreads: Display the thread identifier of the current thread
507*d9f75844SAndroid Build Coastguard Worker   static void LogThreads(bool on = true);
508*d9f75844SAndroid Build Coastguard Worker   //  LogTimestamps: Display the elapsed time of the program
509*d9f75844SAndroid Build Coastguard Worker   static void LogTimestamps(bool on = true);
510*d9f75844SAndroid Build Coastguard Worker   // These are the available logging channels
511*d9f75844SAndroid Build Coastguard Worker   //  Debug: Debug console on Windows, otherwise stderr
512*d9f75844SAndroid Build Coastguard Worker   static void LogToDebug(LoggingSeverity min_sev);
513*d9f75844SAndroid Build Coastguard Worker   static LoggingSeverity GetLogToDebug();
514*d9f75844SAndroid Build Coastguard Worker   // Sets whether logs will be directed to stderr in debug mode.
515*d9f75844SAndroid Build Coastguard Worker   static void SetLogToStderr(bool log_to_stderr);
516*d9f75844SAndroid Build Coastguard Worker   // Stream: Any non-blocking stream interface.
517*d9f75844SAndroid Build Coastguard Worker   // Installs the `stream` to collect logs with severtiy `min_sev` or higher.
518*d9f75844SAndroid Build Coastguard Worker   // `stream` must live until deinstalled by RemoveLogToStream.
519*d9f75844SAndroid Build Coastguard Worker   // If `stream` is the first stream added to the system, we might miss some
520*d9f75844SAndroid Build Coastguard Worker   // early concurrent log statement happening from another thread happening near
521*d9f75844SAndroid Build Coastguard Worker   // this instant.
522*d9f75844SAndroid Build Coastguard Worker   static void AddLogToStream(LogSink* stream, LoggingSeverity min_sev);
523*d9f75844SAndroid Build Coastguard Worker   // Removes the specified stream, without destroying it. When the method
524*d9f75844SAndroid Build Coastguard Worker   // has completed, it's guaranteed that `stream` will receive no more logging
525*d9f75844SAndroid Build Coastguard Worker   // calls.
526*d9f75844SAndroid Build Coastguard Worker   static void RemoveLogToStream(LogSink* stream);
527*d9f75844SAndroid Build Coastguard Worker   // Returns the severity for the specified stream, of if none is specified,
528*d9f75844SAndroid Build Coastguard Worker   // the minimum stream severity.
529*d9f75844SAndroid Build Coastguard Worker   static int GetLogToStream(LogSink* stream = nullptr);
530*d9f75844SAndroid Build Coastguard Worker   // Testing against MinLogSeverity allows code to avoid potentially expensive
531*d9f75844SAndroid Build Coastguard Worker   // logging operations by pre-checking the logging level.
532*d9f75844SAndroid Build Coastguard Worker   static int GetMinLogSeverity();
533*d9f75844SAndroid Build Coastguard Worker   // Parses the provided parameter stream to configure the options above.
534*d9f75844SAndroid Build Coastguard Worker   // Useful for configuring logging from the command line.
535*d9f75844SAndroid Build Coastguard Worker   static void ConfigureLogging(absl::string_view params);
536*d9f75844SAndroid Build Coastguard Worker   // Checks the current global debug severity and if the `streams_` collection
537*d9f75844SAndroid Build Coastguard Worker   // is empty. If `severity` is smaller than the global severity and if the
538*d9f75844SAndroid Build Coastguard Worker   // `streams_` collection is empty, the LogMessage will be considered a noop
539*d9f75844SAndroid Build Coastguard Worker   // LogMessage.
540*d9f75844SAndroid Build Coastguard Worker   static bool IsNoop(LoggingSeverity severity);
541*d9f75844SAndroid Build Coastguard Worker   // Version of IsNoop that uses fewer instructions at the call site, since the
542*d9f75844SAndroid Build Coastguard Worker   // caller doesn't have to pass an argument.
543*d9f75844SAndroid Build Coastguard Worker   template <LoggingSeverity S>
544*d9f75844SAndroid Build Coastguard Worker   RTC_NO_INLINE static bool IsNoop() {
545*d9f75844SAndroid Build Coastguard Worker     return IsNoop(S);
546*d9f75844SAndroid Build Coastguard Worker   }
547*d9f75844SAndroid Build Coastguard Worker #else
548*d9f75844SAndroid Build Coastguard Worker   // Next methods do nothing; no one will call these functions.
549*d9f75844SAndroid Build Coastguard Worker   LogMessage(const char* file, int line, LoggingSeverity sev) {}
550*d9f75844SAndroid Build Coastguard Worker   LogMessage(const char* file,
551*d9f75844SAndroid Build Coastguard Worker              int line,
552*d9f75844SAndroid Build Coastguard Worker              LoggingSeverity sev,
553*d9f75844SAndroid Build Coastguard Worker              LogErrorContext err_ctx,
554*d9f75844SAndroid Build Coastguard Worker              int err) {}
555*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_ANDROID)
556*d9f75844SAndroid Build Coastguard Worker   LogMessage(const char* file, int line, LoggingSeverity sev, const char* tag) {
557*d9f75844SAndroid Build Coastguard Worker   }
558*d9f75844SAndroid Build Coastguard Worker #endif
559*d9f75844SAndroid Build Coastguard Worker   ~LogMessage() = default;
560*d9f75844SAndroid Build Coastguard Worker 
561*d9f75844SAndroid Build Coastguard Worker   inline void AddTag(const char* tag) {}
562*d9f75844SAndroid Build Coastguard Worker   inline rtc::StringBuilder& stream() { return print_stream_; }
563*d9f75844SAndroid Build Coastguard Worker   inline static int64_t LogStartTime() { return 0; }
564*d9f75844SAndroid Build Coastguard Worker   inline static uint32_t WallClockStartTime() { return 0; }
565*d9f75844SAndroid Build Coastguard Worker   inline static void LogThreads(bool on = true) {}
566*d9f75844SAndroid Build Coastguard Worker   inline static void LogTimestamps(bool on = true) {}
567*d9f75844SAndroid Build Coastguard Worker   inline static void LogToDebug(LoggingSeverity min_sev) {}
568*d9f75844SAndroid Build Coastguard Worker   inline static LoggingSeverity GetLogToDebug() {
569*d9f75844SAndroid Build Coastguard Worker     return LoggingSeverity::LS_INFO;
570*d9f75844SAndroid Build Coastguard Worker   }
571*d9f75844SAndroid Build Coastguard Worker   inline static void SetLogToStderr(bool log_to_stderr) {}
572*d9f75844SAndroid Build Coastguard Worker   inline static void AddLogToStream(LogSink* stream, LoggingSeverity min_sev) {}
573*d9f75844SAndroid Build Coastguard Worker   inline static void RemoveLogToStream(LogSink* stream) {}
574*d9f75844SAndroid Build Coastguard Worker   inline static int GetLogToStream(LogSink* stream = nullptr) { return 0; }
575*d9f75844SAndroid Build Coastguard Worker   inline static int GetMinLogSeverity() { return 0; }
576*d9f75844SAndroid Build Coastguard Worker   inline static void ConfigureLogging(absl::string_view params) {}
577*d9f75844SAndroid Build Coastguard Worker   static constexpr bool IsNoop(LoggingSeverity severity) { return true; }
578*d9f75844SAndroid Build Coastguard Worker   template <LoggingSeverity S>
579*d9f75844SAndroid Build Coastguard Worker   static constexpr bool IsNoop() {
580*d9f75844SAndroid Build Coastguard Worker     return IsNoop(S);
581*d9f75844SAndroid Build Coastguard Worker   }
582*d9f75844SAndroid Build Coastguard Worker #endif  // RTC_LOG_ENABLED()
583*d9f75844SAndroid Build Coastguard Worker 
584*d9f75844SAndroid Build Coastguard Worker  private:
585*d9f75844SAndroid Build Coastguard Worker   friend class LogMessageForTesting;
586*d9f75844SAndroid Build Coastguard Worker 
587*d9f75844SAndroid Build Coastguard Worker #if RTC_LOG_ENABLED()
588*d9f75844SAndroid Build Coastguard Worker   // Updates min_sev_ appropriately when debug sinks change.
589*d9f75844SAndroid Build Coastguard Worker   static void UpdateMinLogSeverity();
590*d9f75844SAndroid Build Coastguard Worker 
591*d9f75844SAndroid Build Coastguard Worker   // This writes out the actual log messages.
592*d9f75844SAndroid Build Coastguard Worker   static void OutputToDebug(const LogLineRef& log_line_ref);
593*d9f75844SAndroid Build Coastguard Worker 
594*d9f75844SAndroid Build Coastguard Worker   // Called from the dtor (or from a test) to append optional extra error
595*d9f75844SAndroid Build Coastguard Worker   // information to the log stream and a newline character.
596*d9f75844SAndroid Build Coastguard Worker   void FinishPrintStream();
597*d9f75844SAndroid Build Coastguard Worker 
598*d9f75844SAndroid Build Coastguard Worker   LogLineRef log_line_;
599*d9f75844SAndroid Build Coastguard Worker 
600*d9f75844SAndroid Build Coastguard Worker   // String data generated in the constructor, that should be appended to
601*d9f75844SAndroid Build Coastguard Worker   // the message before output.
602*d9f75844SAndroid Build Coastguard Worker   std::string extra_;
603*d9f75844SAndroid Build Coastguard Worker 
604*d9f75844SAndroid Build Coastguard Worker   // The output streams and their associated severities
605*d9f75844SAndroid Build Coastguard Worker   static LogSink* streams_;
606*d9f75844SAndroid Build Coastguard Worker 
607*d9f75844SAndroid Build Coastguard Worker   // Holds true with high probability if `streams_` is empty, false with high
608*d9f75844SAndroid Build Coastguard Worker   // probability otherwise. Operated on with std::memory_order_relaxed because
609*d9f75844SAndroid Build Coastguard Worker   // it's ok to lose or log some additional statements near the instant streams
610*d9f75844SAndroid Build Coastguard Worker   // are added/removed.
611*d9f75844SAndroid Build Coastguard Worker   static std::atomic<bool> streams_empty_;
612*d9f75844SAndroid Build Coastguard Worker 
613*d9f75844SAndroid Build Coastguard Worker   // Flags for formatting options and their potential values.
614*d9f75844SAndroid Build Coastguard Worker   static bool log_thread_;
615*d9f75844SAndroid Build Coastguard Worker   static bool log_timestamp_;
616*d9f75844SAndroid Build Coastguard Worker 
617*d9f75844SAndroid Build Coastguard Worker   // Determines if logs will be directed to stderr in debug mode.
618*d9f75844SAndroid Build Coastguard Worker   static bool log_to_stderr_;
619*d9f75844SAndroid Build Coastguard Worker #else  // RTC_LOG_ENABLED()
620*d9f75844SAndroid Build Coastguard Worker   // Next methods do nothing; no one will call these functions.
621*d9f75844SAndroid Build Coastguard Worker   inline static void UpdateMinLogSeverity() {}
622*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_ANDROID)
623*d9f75844SAndroid Build Coastguard Worker   inline static void OutputToDebug(absl::string_view filename,
624*d9f75844SAndroid Build Coastguard Worker                                    int line,
625*d9f75844SAndroid Build Coastguard Worker                                    absl::string_view msg,
626*d9f75844SAndroid Build Coastguard Worker                                    LoggingSeverity severity,
627*d9f75844SAndroid Build Coastguard Worker                                    const char* tag) {}
628*d9f75844SAndroid Build Coastguard Worker #else
629*d9f75844SAndroid Build Coastguard Worker   inline static void OutputToDebug(absl::string_view filename,
630*d9f75844SAndroid Build Coastguard Worker                                    int line,
631*d9f75844SAndroid Build Coastguard Worker                                    absl::string_view msg,
632*d9f75844SAndroid Build Coastguard Worker                                    LoggingSeverity severity) {}
633*d9f75844SAndroid Build Coastguard Worker #endif  // defined(WEBRTC_ANDROID)
634*d9f75844SAndroid Build Coastguard Worker   inline void FinishPrintStream() {}
635*d9f75844SAndroid Build Coastguard Worker #endif  // RTC_LOG_ENABLED()
636*d9f75844SAndroid Build Coastguard Worker 
637*d9f75844SAndroid Build Coastguard Worker   // The stringbuilder that buffers the formatted message before output
638*d9f75844SAndroid Build Coastguard Worker   rtc::StringBuilder print_stream_;
639*d9f75844SAndroid Build Coastguard Worker };
640*d9f75844SAndroid Build Coastguard Worker 
641*d9f75844SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////
642*d9f75844SAndroid Build Coastguard Worker // Logging Helpers
643*d9f75844SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////
644*d9f75844SAndroid Build Coastguard Worker 
645*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_FILE_LINE(sev, file, line)        \
646*d9f75844SAndroid Build Coastguard Worker   ::rtc::webrtc_logging_impl::LogCall() &         \
647*d9f75844SAndroid Build Coastguard Worker       ::rtc::webrtc_logging_impl::LogStreamer<>() \
648*d9f75844SAndroid Build Coastguard Worker           << ::rtc::webrtc_logging_impl::LogMetadata(file, line, sev)
649*d9f75844SAndroid Build Coastguard Worker 
650*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG(sev)                        \
651*d9f75844SAndroid Build Coastguard Worker   !rtc::LogMessage::IsNoop<::rtc::sev>() && \
652*d9f75844SAndroid Build Coastguard Worker       RTC_LOG_FILE_LINE(::rtc::sev, __FILE__, __LINE__)
653*d9f75844SAndroid Build Coastguard Worker 
654*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_IF(sev, condition)                         \
655*d9f75844SAndroid Build Coastguard Worker   !rtc::LogMessage::IsNoop<::rtc::sev>() && (condition) && \
656*d9f75844SAndroid Build Coastguard Worker       RTC_LOG_FILE_LINE(::rtc::sev, __FILE__, __LINE__)
657*d9f75844SAndroid Build Coastguard Worker 
658*d9f75844SAndroid Build Coastguard Worker // The _V version is for when a variable is passed in.
659*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_V(sev) \
660*d9f75844SAndroid Build Coastguard Worker   !rtc::LogMessage::IsNoop(sev) && RTC_LOG_FILE_LINE(sev, __FILE__, __LINE__)
661*d9f75844SAndroid Build Coastguard Worker 
662*d9f75844SAndroid Build Coastguard Worker // The _F version prefixes the message with the current function name.
663*d9f75844SAndroid Build Coastguard Worker #if (defined(__GNUC__) && !defined(NDEBUG)) || defined(WANT_PRETTY_LOG_F)
664*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_F(sev) RTC_LOG(sev) << __PRETTY_FUNCTION__ << ": "
665*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_IF_F(sev, condition) \
666*d9f75844SAndroid Build Coastguard Worker   RTC_LOG_IF(sev, condition) << __PRETTY_FUNCTION__ << ": "
667*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_T_F(sev) \
668*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(sev) << this << ": " << __PRETTY_FUNCTION__ << ": "
669*d9f75844SAndroid Build Coastguard Worker #else
670*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_F(sev) RTC_LOG(sev) << __FUNCTION__ << ": "
671*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_IF_F(sev, condition) \
672*d9f75844SAndroid Build Coastguard Worker   RTC_LOG_IF(sev, condition) << __FUNCTION__ << ": "
673*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_T_F(sev) RTC_LOG(sev) << this << ": " << __FUNCTION__ << ": "
674*d9f75844SAndroid Build Coastguard Worker #endif
675*d9f75844SAndroid Build Coastguard Worker 
676*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_CHECK_LEVEL(sev) ::rtc::LogCheckLevel(::rtc::sev)
677*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_CHECK_LEVEL_V(sev) ::rtc::LogCheckLevel(sev)
678*d9f75844SAndroid Build Coastguard Worker 
679*d9f75844SAndroid Build Coastguard Worker inline bool LogCheckLevel(LoggingSeverity sev) {
680*d9f75844SAndroid Build Coastguard Worker   return (LogMessage::GetMinLogSeverity() <= sev);
681*d9f75844SAndroid Build Coastguard Worker }
682*d9f75844SAndroid Build Coastguard Worker 
683*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_E(sev, ctx, err)                                 \
684*d9f75844SAndroid Build Coastguard Worker   !rtc::LogMessage::IsNoop<::rtc::sev>() &&                      \
685*d9f75844SAndroid Build Coastguard Worker       ::rtc::webrtc_logging_impl::LogCall() &                    \
686*d9f75844SAndroid Build Coastguard Worker           ::rtc::webrtc_logging_impl::LogStreamer<>()            \
687*d9f75844SAndroid Build Coastguard Worker               << ::rtc::webrtc_logging_impl::LogMetadataErr {    \
688*d9f75844SAndroid Build Coastguard Worker     {__FILE__, __LINE__, ::rtc::sev}, ::rtc::ERRCTX_##ctx, (err) \
689*d9f75844SAndroid Build Coastguard Worker   }
690*d9f75844SAndroid Build Coastguard Worker 
691*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_T(sev) RTC_LOG(sev) << this << ": "
692*d9f75844SAndroid Build Coastguard Worker 
693*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_ERRNO_EX(sev, err) RTC_LOG_E(sev, ERRNO, err)
694*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_ERRNO(sev) RTC_LOG_ERRNO_EX(sev, errno)
695*d9f75844SAndroid Build Coastguard Worker 
696*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
697*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_GLE_EX(sev, err) RTC_LOG_E(sev, HRESULT, err)
698*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_GLE(sev) RTC_LOG_GLE_EX(sev, static_cast<int>(GetLastError()))
699*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_ERR_EX(sev, err) RTC_LOG_GLE_EX(sev, err)
700*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_ERR(sev) RTC_LOG_GLE(sev)
701*d9f75844SAndroid Build Coastguard Worker #elif defined(__native_client__) && __native_client__
702*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_ERR_EX(sev, err) RTC_LOG(sev)
703*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_ERR(sev) RTC_LOG(sev)
704*d9f75844SAndroid Build Coastguard Worker #elif defined(WEBRTC_POSIX)
705*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_ERR_EX(sev, err) RTC_LOG_ERRNO_EX(sev, err)
706*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_ERR(sev) RTC_LOG_ERRNO(sev)
707*d9f75844SAndroid Build Coastguard Worker #endif  // WEBRTC_WIN
708*d9f75844SAndroid Build Coastguard Worker 
709*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
710*d9f75844SAndroid Build Coastguard Worker 
711*d9f75844SAndroid Build Coastguard Worker namespace webrtc_logging_impl {
712*d9f75844SAndroid Build Coastguard Worker // TODO(kwiberg): Replace these with absl::string_view.
713*d9f75844SAndroid Build Coastguard Worker inline const char* AdaptString(const char* str) {
714*d9f75844SAndroid Build Coastguard Worker   return str;
715*d9f75844SAndroid Build Coastguard Worker }
716*d9f75844SAndroid Build Coastguard Worker inline const char* AdaptString(const std::string& str) {
717*d9f75844SAndroid Build Coastguard Worker   return str.c_str();
718*d9f75844SAndroid Build Coastguard Worker }
719*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc_logging_impl
720*d9f75844SAndroid Build Coastguard Worker 
721*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_TAG(sev, tag)                                 \
722*d9f75844SAndroid Build Coastguard Worker   !rtc::LogMessage::IsNoop(sev) &&                            \
723*d9f75844SAndroid Build Coastguard Worker       ::rtc::webrtc_logging_impl::LogCall() &                 \
724*d9f75844SAndroid Build Coastguard Worker           ::rtc::webrtc_logging_impl::LogStreamer<>()         \
725*d9f75844SAndroid Build Coastguard Worker               << ::rtc::webrtc_logging_impl::LogMetadataTag { \
726*d9f75844SAndroid Build Coastguard Worker     sev, ::rtc::webrtc_logging_impl::AdaptString(tag)         \
727*d9f75844SAndroid Build Coastguard Worker   }
728*d9f75844SAndroid Build Coastguard Worker 
729*d9f75844SAndroid Build Coastguard Worker #else
730*d9f75844SAndroid Build Coastguard Worker 
731*d9f75844SAndroid Build Coastguard Worker // DEPRECATED. This macro is only intended for Android.
732*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_TAG(sev, tag) RTC_LOG_V(sev)
733*d9f75844SAndroid Build Coastguard Worker 
734*d9f75844SAndroid Build Coastguard Worker #endif
735*d9f75844SAndroid Build Coastguard Worker 
736*d9f75844SAndroid Build Coastguard Worker // The RTC_DLOG macros are equivalent to their RTC_LOG counterparts except that
737*d9f75844SAndroid Build Coastguard Worker // they only generate code in debug builds.
738*d9f75844SAndroid Build Coastguard Worker #if RTC_DLOG_IS_ON
739*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG(sev) RTC_LOG(sev)
740*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_IF(sev, condition) RTC_LOG_IF(sev, condition)
741*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_V(sev) RTC_LOG_V(sev)
742*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_F(sev) RTC_LOG_F(sev)
743*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_IF_F(sev, condition) RTC_LOG_IF_F(sev, condition)
744*d9f75844SAndroid Build Coastguard Worker #else
745*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_EAT_STREAM_PARAMS()                \
746*d9f75844SAndroid Build Coastguard Worker   while (false)                                     \
747*d9f75844SAndroid Build Coastguard Worker   ::rtc::webrtc_logging_impl::LogMessageVoidify() & \
748*d9f75844SAndroid Build Coastguard Worker       (::rtc::webrtc_logging_impl::LogStreamer<>())
749*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG(sev) RTC_DLOG_EAT_STREAM_PARAMS()
750*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_IF(sev, condition) RTC_DLOG_EAT_STREAM_PARAMS()
751*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_V(sev) RTC_DLOG_EAT_STREAM_PARAMS()
752*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_F(sev) RTC_DLOG_EAT_STREAM_PARAMS()
753*d9f75844SAndroid Build Coastguard Worker #define RTC_DLOG_IF_F(sev, condition) RTC_DLOG_EAT_STREAM_PARAMS()
754*d9f75844SAndroid Build Coastguard Worker #endif
755*d9f75844SAndroid Build Coastguard Worker 
756*d9f75844SAndroid Build Coastguard Worker }  // namespace rtc
757*d9f75844SAndroid Build Coastguard Worker 
758*d9f75844SAndroid Build Coastguard Worker #endif  // RTC_BASE_LOGGING_H_
759