xref: /aosp_15_r20/external/webrtc/rtc_base/logging.cc (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 #include "rtc_base/logging.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <string.h>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #if RTC_LOG_ENABLED()
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
18*d9f75844SAndroid Build Coastguard Worker #include <windows.h>
19*d9f75844SAndroid Build Coastguard Worker #if _MSC_VER < 1900
20*d9f75844SAndroid Build Coastguard Worker #define snprintf _snprintf
21*d9f75844SAndroid Build Coastguard Worker #endif
22*d9f75844SAndroid Build Coastguard Worker #undef ERROR  // wingdi.h
23*d9f75844SAndroid Build Coastguard Worker #endif
24*d9f75844SAndroid Build Coastguard Worker 
25*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
26*d9f75844SAndroid Build Coastguard Worker #include <CoreServices/CoreServices.h>
27*d9f75844SAndroid Build Coastguard Worker #elif defined(WEBRTC_ANDROID)
28*d9f75844SAndroid Build Coastguard Worker #include <android/log.h>
29*d9f75844SAndroid Build Coastguard Worker 
30*d9f75844SAndroid Build Coastguard Worker // Android has a 1024 limit on log inputs. We use 60 chars as an
31*d9f75844SAndroid Build Coastguard Worker // approx for the header/tag portion.
32*d9f75844SAndroid Build Coastguard Worker // See android/system/logging/liblog/logd_write.c
33*d9f75844SAndroid Build Coastguard Worker static const int kMaxLogLineSize = 1024 - 60;
34*d9f75844SAndroid Build Coastguard Worker #endif  // WEBRTC_MAC && !defined(WEBRTC_IOS) || WEBRTC_ANDROID
35*d9f75844SAndroid Build Coastguard Worker 
36*d9f75844SAndroid Build Coastguard Worker #include <inttypes.h>
37*d9f75844SAndroid Build Coastguard Worker #include <stdio.h>
38*d9f75844SAndroid Build Coastguard Worker #include <time.h>
39*d9f75844SAndroid Build Coastguard Worker 
40*d9f75844SAndroid Build Coastguard Worker #include <algorithm>
41*d9f75844SAndroid Build Coastguard Worker #include <cstdarg>
42*d9f75844SAndroid Build Coastguard Worker #include <vector>
43*d9f75844SAndroid Build Coastguard Worker 
44*d9f75844SAndroid Build Coastguard Worker #include "absl/base/attributes.h"
45*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
46*d9f75844SAndroid Build Coastguard Worker #include "api/units/timestamp.h"
47*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
48*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/platform_thread_types.h"
49*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/string_encode.h"
50*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/string_utils.h"
51*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
52*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h"
53*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h"
54*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h"
55*d9f75844SAndroid Build Coastguard Worker 
56*d9f75844SAndroid Build Coastguard Worker namespace rtc {
57*d9f75844SAndroid Build Coastguard Worker namespace {
58*d9f75844SAndroid Build Coastguard Worker 
59*d9f75844SAndroid Build Coastguard Worker // By default, release builds don't log, debug builds at info level
60*d9f75844SAndroid Build Coastguard Worker #if !defined(NDEBUG)
61*d9f75844SAndroid Build Coastguard Worker constexpr LoggingSeverity kDefaultLoggingSeverity = LS_INFO;
62*d9f75844SAndroid Build Coastguard Worker #else
63*d9f75844SAndroid Build Coastguard Worker constexpr LoggingSeverity kDefaultLoggingSeverity = LS_NONE;
64*d9f75844SAndroid Build Coastguard Worker #endif
65*d9f75844SAndroid Build Coastguard Worker 
66*d9f75844SAndroid Build Coastguard Worker // Note: `g_min_sev` and `g_dbg_sev` can be changed while running.
67*d9f75844SAndroid Build Coastguard Worker LoggingSeverity g_min_sev = kDefaultLoggingSeverity;
68*d9f75844SAndroid Build Coastguard Worker LoggingSeverity g_dbg_sev = kDefaultLoggingSeverity;
69*d9f75844SAndroid Build Coastguard Worker 
70*d9f75844SAndroid Build Coastguard Worker // Return the filename portion of the string (that following the last slash).
FilenameFromPath(const char * file)71*d9f75844SAndroid Build Coastguard Worker const char* FilenameFromPath(const char* file) {
72*d9f75844SAndroid Build Coastguard Worker   const char* end1 = ::strrchr(file, '/');
73*d9f75844SAndroid Build Coastguard Worker   const char* end2 = ::strrchr(file, '\\');
74*d9f75844SAndroid Build Coastguard Worker   if (!end1 && !end2)
75*d9f75844SAndroid Build Coastguard Worker     return file;
76*d9f75844SAndroid Build Coastguard Worker   else
77*d9f75844SAndroid Build Coastguard Worker     return (end1 > end2) ? end1 + 1 : end2 + 1;
78*d9f75844SAndroid Build Coastguard Worker }
79*d9f75844SAndroid Build Coastguard Worker 
80*d9f75844SAndroid Build Coastguard Worker // Global lock for log subsystem, only needed to serialize access to streams_.
GetLoggingLock()81*d9f75844SAndroid Build Coastguard Worker webrtc::Mutex& GetLoggingLock() {
82*d9f75844SAndroid Build Coastguard Worker   static webrtc::Mutex& mutex = *new webrtc::Mutex();
83*d9f75844SAndroid Build Coastguard Worker   return mutex;
84*d9f75844SAndroid Build Coastguard Worker }
85*d9f75844SAndroid Build Coastguard Worker 
86*d9f75844SAndroid Build Coastguard Worker }  // namespace
87*d9f75844SAndroid Build Coastguard Worker 
DefaultLogLine() const88*d9f75844SAndroid Build Coastguard Worker std::string LogLineRef::DefaultLogLine() const {
89*d9f75844SAndroid Build Coastguard Worker   rtc::StringBuilder log_output;
90*d9f75844SAndroid Build Coastguard Worker   if (timestamp_ != webrtc::Timestamp::MinusInfinity()) {
91*d9f75844SAndroid Build Coastguard Worker     // TODO(kwiberg): Switch to absl::StrFormat, if binary size is ok.
92*d9f75844SAndroid Build Coastguard Worker     char timestamp[50];  // Maximum string length of an int64_t is 20.
93*d9f75844SAndroid Build Coastguard Worker     int len =
94*d9f75844SAndroid Build Coastguard Worker         snprintf(timestamp, sizeof(timestamp), "[%03" PRId64 ":%03" PRId64 "]",
95*d9f75844SAndroid Build Coastguard Worker                  timestamp_.ms() / 1000, timestamp_.ms() % 1000);
96*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK_LT(len, sizeof(timestamp));
97*d9f75844SAndroid Build Coastguard Worker     log_output << timestamp;
98*d9f75844SAndroid Build Coastguard Worker   }
99*d9f75844SAndroid Build Coastguard Worker   if (thread_id_.has_value()) {
100*d9f75844SAndroid Build Coastguard Worker     log_output << "[" << *thread_id_ << "] ";
101*d9f75844SAndroid Build Coastguard Worker   }
102*d9f75844SAndroid Build Coastguard Worker   if (!filename_.empty()) {
103*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_ANDROID)
104*d9f75844SAndroid Build Coastguard Worker     log_output << "(line " << line_ << "): ";
105*d9f75844SAndroid Build Coastguard Worker #else
106*d9f75844SAndroid Build Coastguard Worker     log_output << "(" << filename_ << ":" << line_ << "): ";
107*d9f75844SAndroid Build Coastguard Worker #endif
108*d9f75844SAndroid Build Coastguard Worker   }
109*d9f75844SAndroid Build Coastguard Worker   log_output << message_;
110*d9f75844SAndroid Build Coastguard Worker   return log_output.Release();
111*d9f75844SAndroid Build Coastguard Worker }
112*d9f75844SAndroid Build Coastguard Worker 
113*d9f75844SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////
114*d9f75844SAndroid Build Coastguard Worker // LogMessage
115*d9f75844SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////
116*d9f75844SAndroid Build Coastguard Worker 
117*d9f75844SAndroid Build Coastguard Worker bool LogMessage::log_to_stderr_ = true;
118*d9f75844SAndroid Build Coastguard Worker 
119*d9f75844SAndroid Build Coastguard Worker // The list of logging streams currently configured.
120*d9f75844SAndroid Build Coastguard Worker // Note: we explicitly do not clean this up, because of the uncertain ordering
121*d9f75844SAndroid Build Coastguard Worker // of destructors at program exit.  Let the person who sets the stream trigger
122*d9f75844SAndroid Build Coastguard Worker // cleanup by setting to null, or let it leak (safe at program exit).
123*d9f75844SAndroid Build Coastguard Worker ABSL_CONST_INIT LogSink* LogMessage::streams_ RTC_GUARDED_BY(GetLoggingLock()) =
124*d9f75844SAndroid Build Coastguard Worker     nullptr;
125*d9f75844SAndroid Build Coastguard Worker ABSL_CONST_INIT std::atomic<bool> LogMessage::streams_empty_ = {true};
126*d9f75844SAndroid Build Coastguard Worker 
127*d9f75844SAndroid Build Coastguard Worker // Boolean options default to false.
128*d9f75844SAndroid Build Coastguard Worker ABSL_CONST_INIT bool LogMessage::log_thread_ = false;
129*d9f75844SAndroid Build Coastguard Worker ABSL_CONST_INIT bool LogMessage::log_timestamp_ = false;
130*d9f75844SAndroid Build Coastguard Worker 
LogMessage(const char * file,int line,LoggingSeverity sev)131*d9f75844SAndroid Build Coastguard Worker LogMessage::LogMessage(const char* file, int line, LoggingSeverity sev)
132*d9f75844SAndroid Build Coastguard Worker     : LogMessage(file, line, sev, ERRCTX_NONE, 0) {}
133*d9f75844SAndroid Build Coastguard Worker 
LogMessage(const char * file,int line,LoggingSeverity sev,LogErrorContext err_ctx,int err)134*d9f75844SAndroid Build Coastguard Worker LogMessage::LogMessage(const char* file,
135*d9f75844SAndroid Build Coastguard Worker                        int line,
136*d9f75844SAndroid Build Coastguard Worker                        LoggingSeverity sev,
137*d9f75844SAndroid Build Coastguard Worker                        LogErrorContext err_ctx,
138*d9f75844SAndroid Build Coastguard Worker                        int err) {
139*d9f75844SAndroid Build Coastguard Worker   log_line_.set_severity(sev);
140*d9f75844SAndroid Build Coastguard Worker   if (log_timestamp_) {
141*d9f75844SAndroid Build Coastguard Worker     int64_t log_start_time = LogStartTime();
142*d9f75844SAndroid Build Coastguard Worker     // Use SystemTimeMillis so that even if tests use fake clocks, the timestamp
143*d9f75844SAndroid Build Coastguard Worker     // in log messages represents the real system time.
144*d9f75844SAndroid Build Coastguard Worker     int64_t time = TimeDiff(SystemTimeMillis(), log_start_time);
145*d9f75844SAndroid Build Coastguard Worker     // Also ensure WallClockStartTime is initialized, so that it matches
146*d9f75844SAndroid Build Coastguard Worker     // LogStartTime.
147*d9f75844SAndroid Build Coastguard Worker     WallClockStartTime();
148*d9f75844SAndroid Build Coastguard Worker     log_line_.set_timestamp(webrtc::Timestamp::Millis(time));
149*d9f75844SAndroid Build Coastguard Worker   }
150*d9f75844SAndroid Build Coastguard Worker 
151*d9f75844SAndroid Build Coastguard Worker   if (log_thread_) {
152*d9f75844SAndroid Build Coastguard Worker     log_line_.set_thread_id(CurrentThreadId());
153*d9f75844SAndroid Build Coastguard Worker   }
154*d9f75844SAndroid Build Coastguard Worker 
155*d9f75844SAndroid Build Coastguard Worker   if (file != nullptr) {
156*d9f75844SAndroid Build Coastguard Worker     log_line_.set_filename(FilenameFromPath(file));
157*d9f75844SAndroid Build Coastguard Worker     log_line_.set_line(line);
158*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_ANDROID)
159*d9f75844SAndroid Build Coastguard Worker     log_line_.set_tag(log_line_.filename());
160*d9f75844SAndroid Build Coastguard Worker #endif
161*d9f75844SAndroid Build Coastguard Worker   }
162*d9f75844SAndroid Build Coastguard Worker 
163*d9f75844SAndroid Build Coastguard Worker   if (err_ctx != ERRCTX_NONE) {
164*d9f75844SAndroid Build Coastguard Worker     char tmp_buf[1024];
165*d9f75844SAndroid Build Coastguard Worker     SimpleStringBuilder tmp(tmp_buf);
166*d9f75844SAndroid Build Coastguard Worker     tmp.AppendFormat("[0x%08X]", err);
167*d9f75844SAndroid Build Coastguard Worker     switch (err_ctx) {
168*d9f75844SAndroid Build Coastguard Worker       case ERRCTX_ERRNO:
169*d9f75844SAndroid Build Coastguard Worker         tmp << " " << strerror(err);
170*d9f75844SAndroid Build Coastguard Worker         break;
171*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_WIN
172*d9f75844SAndroid Build Coastguard Worker       case ERRCTX_HRESULT: {
173*d9f75844SAndroid Build Coastguard Worker         char msgbuf[256];
174*d9f75844SAndroid Build Coastguard Worker         DWORD flags =
175*d9f75844SAndroid Build Coastguard Worker             FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
176*d9f75844SAndroid Build Coastguard Worker         if (DWORD len = FormatMessageA(
177*d9f75844SAndroid Build Coastguard Worker                 flags, nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
178*d9f75844SAndroid Build Coastguard Worker                 msgbuf, sizeof(msgbuf) / sizeof(msgbuf[0]), nullptr)) {
179*d9f75844SAndroid Build Coastguard Worker           while ((len > 0) &&
180*d9f75844SAndroid Build Coastguard Worker                  isspace(static_cast<unsigned char>(msgbuf[len - 1]))) {
181*d9f75844SAndroid Build Coastguard Worker             msgbuf[--len] = 0;
182*d9f75844SAndroid Build Coastguard Worker           }
183*d9f75844SAndroid Build Coastguard Worker           tmp << " " << msgbuf;
184*d9f75844SAndroid Build Coastguard Worker         }
185*d9f75844SAndroid Build Coastguard Worker         break;
186*d9f75844SAndroid Build Coastguard Worker       }
187*d9f75844SAndroid Build Coastguard Worker #endif  // WEBRTC_WIN
188*d9f75844SAndroid Build Coastguard Worker       default:
189*d9f75844SAndroid Build Coastguard Worker         break;
190*d9f75844SAndroid Build Coastguard Worker     }
191*d9f75844SAndroid Build Coastguard Worker     extra_ = tmp.str();
192*d9f75844SAndroid Build Coastguard Worker   }
193*d9f75844SAndroid Build Coastguard Worker }
194*d9f75844SAndroid Build Coastguard Worker 
195*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_ANDROID)
LogMessage(const char * file,int line,LoggingSeverity sev,const char * tag)196*d9f75844SAndroid Build Coastguard Worker LogMessage::LogMessage(const char* file,
197*d9f75844SAndroid Build Coastguard Worker                        int line,
198*d9f75844SAndroid Build Coastguard Worker                        LoggingSeverity sev,
199*d9f75844SAndroid Build Coastguard Worker                        const char* tag)
200*d9f75844SAndroid Build Coastguard Worker     : LogMessage(file, line, sev, ERRCTX_NONE, /*err=*/0) {
201*d9f75844SAndroid Build Coastguard Worker   log_line_.set_tag(tag);
202*d9f75844SAndroid Build Coastguard Worker   print_stream_ << tag << ": ";
203*d9f75844SAndroid Build Coastguard Worker }
204*d9f75844SAndroid Build Coastguard Worker #endif
205*d9f75844SAndroid Build Coastguard Worker 
~LogMessage()206*d9f75844SAndroid Build Coastguard Worker LogMessage::~LogMessage() {
207*d9f75844SAndroid Build Coastguard Worker   FinishPrintStream();
208*d9f75844SAndroid Build Coastguard Worker 
209*d9f75844SAndroid Build Coastguard Worker   log_line_.set_message(print_stream_.Release());
210*d9f75844SAndroid Build Coastguard Worker 
211*d9f75844SAndroid Build Coastguard Worker   if (log_line_.severity() >= g_dbg_sev) {
212*d9f75844SAndroid Build Coastguard Worker     OutputToDebug(log_line_);
213*d9f75844SAndroid Build Coastguard Worker   }
214*d9f75844SAndroid Build Coastguard Worker 
215*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock lock(&GetLoggingLock());
216*d9f75844SAndroid Build Coastguard Worker   for (LogSink* entry = streams_; entry != nullptr; entry = entry->next_) {
217*d9f75844SAndroid Build Coastguard Worker     if (log_line_.severity() >= entry->min_severity_) {
218*d9f75844SAndroid Build Coastguard Worker       entry->OnLogMessage(log_line_);
219*d9f75844SAndroid Build Coastguard Worker     }
220*d9f75844SAndroid Build Coastguard Worker   }
221*d9f75844SAndroid Build Coastguard Worker }
222*d9f75844SAndroid Build Coastguard Worker 
AddTag(const char * tag)223*d9f75844SAndroid Build Coastguard Worker void LogMessage::AddTag(const char* tag) {
224*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
225*d9f75844SAndroid Build Coastguard Worker   log_line_.set_tag(tag);
226*d9f75844SAndroid Build Coastguard Worker #endif
227*d9f75844SAndroid Build Coastguard Worker }
228*d9f75844SAndroid Build Coastguard Worker 
stream()229*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder& LogMessage::stream() {
230*d9f75844SAndroid Build Coastguard Worker   return print_stream_;
231*d9f75844SAndroid Build Coastguard Worker }
232*d9f75844SAndroid Build Coastguard Worker 
GetMinLogSeverity()233*d9f75844SAndroid Build Coastguard Worker int LogMessage::GetMinLogSeverity() {
234*d9f75844SAndroid Build Coastguard Worker   return g_min_sev;
235*d9f75844SAndroid Build Coastguard Worker }
236*d9f75844SAndroid Build Coastguard Worker 
GetLogToDebug()237*d9f75844SAndroid Build Coastguard Worker LoggingSeverity LogMessage::GetLogToDebug() {
238*d9f75844SAndroid Build Coastguard Worker   return g_dbg_sev;
239*d9f75844SAndroid Build Coastguard Worker }
LogStartTime()240*d9f75844SAndroid Build Coastguard Worker int64_t LogMessage::LogStartTime() {
241*d9f75844SAndroid Build Coastguard Worker   static const int64_t g_start = SystemTimeMillis();
242*d9f75844SAndroid Build Coastguard Worker   return g_start;
243*d9f75844SAndroid Build Coastguard Worker }
244*d9f75844SAndroid Build Coastguard Worker 
WallClockStartTime()245*d9f75844SAndroid Build Coastguard Worker uint32_t LogMessage::WallClockStartTime() {
246*d9f75844SAndroid Build Coastguard Worker   static const uint32_t g_start_wallclock = time(nullptr);
247*d9f75844SAndroid Build Coastguard Worker   return g_start_wallclock;
248*d9f75844SAndroid Build Coastguard Worker }
249*d9f75844SAndroid Build Coastguard Worker 
LogThreads(bool on)250*d9f75844SAndroid Build Coastguard Worker void LogMessage::LogThreads(bool on) {
251*d9f75844SAndroid Build Coastguard Worker   log_thread_ = on;
252*d9f75844SAndroid Build Coastguard Worker }
253*d9f75844SAndroid Build Coastguard Worker 
LogTimestamps(bool on)254*d9f75844SAndroid Build Coastguard Worker void LogMessage::LogTimestamps(bool on) {
255*d9f75844SAndroid Build Coastguard Worker   log_timestamp_ = on;
256*d9f75844SAndroid Build Coastguard Worker }
257*d9f75844SAndroid Build Coastguard Worker 
LogToDebug(LoggingSeverity min_sev)258*d9f75844SAndroid Build Coastguard Worker void LogMessage::LogToDebug(LoggingSeverity min_sev) {
259*d9f75844SAndroid Build Coastguard Worker   g_dbg_sev = min_sev;
260*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock lock(&GetLoggingLock());
261*d9f75844SAndroid Build Coastguard Worker   UpdateMinLogSeverity();
262*d9f75844SAndroid Build Coastguard Worker }
263*d9f75844SAndroid Build Coastguard Worker 
SetLogToStderr(bool log_to_stderr)264*d9f75844SAndroid Build Coastguard Worker void LogMessage::SetLogToStderr(bool log_to_stderr) {
265*d9f75844SAndroid Build Coastguard Worker   log_to_stderr_ = log_to_stderr;
266*d9f75844SAndroid Build Coastguard Worker }
267*d9f75844SAndroid Build Coastguard Worker 
GetLogToStream(LogSink * stream)268*d9f75844SAndroid Build Coastguard Worker int LogMessage::GetLogToStream(LogSink* stream) {
269*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock lock(&GetLoggingLock());
270*d9f75844SAndroid Build Coastguard Worker   LoggingSeverity sev = LS_NONE;
271*d9f75844SAndroid Build Coastguard Worker   for (LogSink* entry = streams_; entry != nullptr; entry = entry->next_) {
272*d9f75844SAndroid Build Coastguard Worker     if (stream == nullptr || stream == entry) {
273*d9f75844SAndroid Build Coastguard Worker       sev = std::min(sev, entry->min_severity_);
274*d9f75844SAndroid Build Coastguard Worker     }
275*d9f75844SAndroid Build Coastguard Worker   }
276*d9f75844SAndroid Build Coastguard Worker   return sev;
277*d9f75844SAndroid Build Coastguard Worker }
278*d9f75844SAndroid Build Coastguard Worker 
AddLogToStream(LogSink * stream,LoggingSeverity min_sev)279*d9f75844SAndroid Build Coastguard Worker void LogMessage::AddLogToStream(LogSink* stream, LoggingSeverity min_sev) {
280*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock lock(&GetLoggingLock());
281*d9f75844SAndroid Build Coastguard Worker   stream->min_severity_ = min_sev;
282*d9f75844SAndroid Build Coastguard Worker   stream->next_ = streams_;
283*d9f75844SAndroid Build Coastguard Worker   streams_ = stream;
284*d9f75844SAndroid Build Coastguard Worker   streams_empty_.store(false, std::memory_order_relaxed);
285*d9f75844SAndroid Build Coastguard Worker   UpdateMinLogSeverity();
286*d9f75844SAndroid Build Coastguard Worker }
287*d9f75844SAndroid Build Coastguard Worker 
RemoveLogToStream(LogSink * stream)288*d9f75844SAndroid Build Coastguard Worker void LogMessage::RemoveLogToStream(LogSink* stream) {
289*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock lock(&GetLoggingLock());
290*d9f75844SAndroid Build Coastguard Worker   for (LogSink** entry = &streams_; *entry != nullptr;
291*d9f75844SAndroid Build Coastguard Worker        entry = &(*entry)->next_) {
292*d9f75844SAndroid Build Coastguard Worker     if (*entry == stream) {
293*d9f75844SAndroid Build Coastguard Worker       *entry = (*entry)->next_;
294*d9f75844SAndroid Build Coastguard Worker       break;
295*d9f75844SAndroid Build Coastguard Worker     }
296*d9f75844SAndroid Build Coastguard Worker   }
297*d9f75844SAndroid Build Coastguard Worker   streams_empty_.store(streams_ == nullptr, std::memory_order_relaxed);
298*d9f75844SAndroid Build Coastguard Worker   UpdateMinLogSeverity();
299*d9f75844SAndroid Build Coastguard Worker }
300*d9f75844SAndroid Build Coastguard Worker 
ConfigureLogging(absl::string_view params)301*d9f75844SAndroid Build Coastguard Worker void LogMessage::ConfigureLogging(absl::string_view params) {
302*d9f75844SAndroid Build Coastguard Worker   LoggingSeverity current_level = LS_VERBOSE;
303*d9f75844SAndroid Build Coastguard Worker   LoggingSeverity debug_level = GetLogToDebug();
304*d9f75844SAndroid Build Coastguard Worker 
305*d9f75844SAndroid Build Coastguard Worker   std::vector<std::string> tokens;
306*d9f75844SAndroid Build Coastguard Worker   tokenize(params, ' ', &tokens);
307*d9f75844SAndroid Build Coastguard Worker 
308*d9f75844SAndroid Build Coastguard Worker   for (const std::string& token : tokens) {
309*d9f75844SAndroid Build Coastguard Worker     if (token.empty())
310*d9f75844SAndroid Build Coastguard Worker       continue;
311*d9f75844SAndroid Build Coastguard Worker 
312*d9f75844SAndroid Build Coastguard Worker     // Logging features
313*d9f75844SAndroid Build Coastguard Worker     if (token == "tstamp") {
314*d9f75844SAndroid Build Coastguard Worker       LogTimestamps();
315*d9f75844SAndroid Build Coastguard Worker     } else if (token == "thread") {
316*d9f75844SAndroid Build Coastguard Worker       LogThreads();
317*d9f75844SAndroid Build Coastguard Worker 
318*d9f75844SAndroid Build Coastguard Worker       // Logging levels
319*d9f75844SAndroid Build Coastguard Worker     } else if (token == "verbose") {
320*d9f75844SAndroid Build Coastguard Worker       current_level = LS_VERBOSE;
321*d9f75844SAndroid Build Coastguard Worker     } else if (token == "info") {
322*d9f75844SAndroid Build Coastguard Worker       current_level = LS_INFO;
323*d9f75844SAndroid Build Coastguard Worker     } else if (token == "warning") {
324*d9f75844SAndroid Build Coastguard Worker       current_level = LS_WARNING;
325*d9f75844SAndroid Build Coastguard Worker     } else if (token == "error") {
326*d9f75844SAndroid Build Coastguard Worker       current_level = LS_ERROR;
327*d9f75844SAndroid Build Coastguard Worker     } else if (token == "none") {
328*d9f75844SAndroid Build Coastguard Worker       current_level = LS_NONE;
329*d9f75844SAndroid Build Coastguard Worker 
330*d9f75844SAndroid Build Coastguard Worker       // Logging targets
331*d9f75844SAndroid Build Coastguard Worker     } else if (token == "debug") {
332*d9f75844SAndroid Build Coastguard Worker       debug_level = current_level;
333*d9f75844SAndroid Build Coastguard Worker     }
334*d9f75844SAndroid Build Coastguard Worker   }
335*d9f75844SAndroid Build Coastguard Worker 
336*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN) && !defined(WINUWP)
337*d9f75844SAndroid Build Coastguard Worker   if ((LS_NONE != debug_level) && !::IsDebuggerPresent()) {
338*d9f75844SAndroid Build Coastguard Worker     // First, attempt to attach to our parent's console... so if you invoke
339*d9f75844SAndroid Build Coastguard Worker     // from the command line, we'll see the output there.  Otherwise, create
340*d9f75844SAndroid Build Coastguard Worker     // our own console window.
341*d9f75844SAndroid Build Coastguard Worker     // Note: These methods fail if a console already exists, which is fine.
342*d9f75844SAndroid Build Coastguard Worker     if (!AttachConsole(ATTACH_PARENT_PROCESS))
343*d9f75844SAndroid Build Coastguard Worker       ::AllocConsole();
344*d9f75844SAndroid Build Coastguard Worker   }
345*d9f75844SAndroid Build Coastguard Worker #endif  // defined(WEBRTC_WIN) && !defined(WINUWP)
346*d9f75844SAndroid Build Coastguard Worker 
347*d9f75844SAndroid Build Coastguard Worker   LogToDebug(debug_level);
348*d9f75844SAndroid Build Coastguard Worker }
349*d9f75844SAndroid Build Coastguard Worker 
UpdateMinLogSeverity()350*d9f75844SAndroid Build Coastguard Worker void LogMessage::UpdateMinLogSeverity()
351*d9f75844SAndroid Build Coastguard Worker     RTC_EXCLUSIVE_LOCKS_REQUIRED(GetLoggingLock()) {
352*d9f75844SAndroid Build Coastguard Worker   LoggingSeverity min_sev = g_dbg_sev;
353*d9f75844SAndroid Build Coastguard Worker   for (LogSink* entry = streams_; entry != nullptr; entry = entry->next_) {
354*d9f75844SAndroid Build Coastguard Worker     min_sev = std::min(min_sev, entry->min_severity_);
355*d9f75844SAndroid Build Coastguard Worker   }
356*d9f75844SAndroid Build Coastguard Worker   g_min_sev = min_sev;
357*d9f75844SAndroid Build Coastguard Worker }
358*d9f75844SAndroid Build Coastguard Worker 
OutputToDebug(const LogLineRef & log_line)359*d9f75844SAndroid Build Coastguard Worker void LogMessage::OutputToDebug(const LogLineRef& log_line) {
360*d9f75844SAndroid Build Coastguard Worker   std::string msg_str = log_line.DefaultLogLine();
361*d9f75844SAndroid Build Coastguard Worker   bool log_to_stderr = log_to_stderr_;
362*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && defined(NDEBUG)
363*d9f75844SAndroid Build Coastguard Worker   // On the Mac, all stderr output goes to the Console log and causes clutter.
364*d9f75844SAndroid Build Coastguard Worker   // So in opt builds, don't log to stderr unless the user specifically sets
365*d9f75844SAndroid Build Coastguard Worker   // a preference to do so.
366*d9f75844SAndroid Build Coastguard Worker   CFStringRef key = CFStringCreateWithCString(
367*d9f75844SAndroid Build Coastguard Worker       kCFAllocatorDefault, "logToStdErr", kCFStringEncodingUTF8);
368*d9f75844SAndroid Build Coastguard Worker   CFStringRef domain = CFBundleGetIdentifier(CFBundleGetMainBundle());
369*d9f75844SAndroid Build Coastguard Worker   if (key != nullptr && domain != nullptr) {
370*d9f75844SAndroid Build Coastguard Worker     Boolean exists_and_is_valid;
371*d9f75844SAndroid Build Coastguard Worker     Boolean should_log =
372*d9f75844SAndroid Build Coastguard Worker         CFPreferencesGetAppBooleanValue(key, domain, &exists_and_is_valid);
373*d9f75844SAndroid Build Coastguard Worker     // If the key doesn't exist or is invalid or is false, we will not log to
374*d9f75844SAndroid Build Coastguard Worker     // stderr.
375*d9f75844SAndroid Build Coastguard Worker     log_to_stderr = exists_and_is_valid && should_log;
376*d9f75844SAndroid Build Coastguard Worker   }
377*d9f75844SAndroid Build Coastguard Worker   if (key != nullptr) {
378*d9f75844SAndroid Build Coastguard Worker     CFRelease(key);
379*d9f75844SAndroid Build Coastguard Worker   }
380*d9f75844SAndroid Build Coastguard Worker #endif  // defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && defined(NDEBUG)
381*d9f75844SAndroid Build Coastguard Worker 
382*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
383*d9f75844SAndroid Build Coastguard Worker   // Always log to the debugger.
384*d9f75844SAndroid Build Coastguard Worker   // Perhaps stderr should be controlled by a preference, as on Mac?
385*d9f75844SAndroid Build Coastguard Worker   OutputDebugStringA(msg_str.c_str());
386*d9f75844SAndroid Build Coastguard Worker   if (log_to_stderr) {
387*d9f75844SAndroid Build Coastguard Worker     // This handles dynamically allocated consoles, too.
388*d9f75844SAndroid Build Coastguard Worker     if (HANDLE error_handle = ::GetStdHandle(STD_ERROR_HANDLE)) {
389*d9f75844SAndroid Build Coastguard Worker       log_to_stderr = false;
390*d9f75844SAndroid Build Coastguard Worker       DWORD written = 0;
391*d9f75844SAndroid Build Coastguard Worker       ::WriteFile(error_handle, msg_str.c_str(),
392*d9f75844SAndroid Build Coastguard Worker                   static_cast<DWORD>(msg_str.size()), &written, 0);
393*d9f75844SAndroid Build Coastguard Worker     }
394*d9f75844SAndroid Build Coastguard Worker   }
395*d9f75844SAndroid Build Coastguard Worker #endif  // WEBRTC_WIN
396*d9f75844SAndroid Build Coastguard Worker 
397*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_ANDROID)
398*d9f75844SAndroid Build Coastguard Worker   // Android's logging facility uses severity to log messages but we
399*d9f75844SAndroid Build Coastguard Worker   // need to map libjingle's severity levels to Android ones first.
400*d9f75844SAndroid Build Coastguard Worker   // Also write to stderr which maybe available to executable started
401*d9f75844SAndroid Build Coastguard Worker   // from the shell.
402*d9f75844SAndroid Build Coastguard Worker   int prio;
403*d9f75844SAndroid Build Coastguard Worker   switch (log_line.severity()) {
404*d9f75844SAndroid Build Coastguard Worker     case LS_VERBOSE:
405*d9f75844SAndroid Build Coastguard Worker       prio = ANDROID_LOG_VERBOSE;
406*d9f75844SAndroid Build Coastguard Worker       break;
407*d9f75844SAndroid Build Coastguard Worker     case LS_INFO:
408*d9f75844SAndroid Build Coastguard Worker       prio = ANDROID_LOG_INFO;
409*d9f75844SAndroid Build Coastguard Worker       break;
410*d9f75844SAndroid Build Coastguard Worker     case LS_WARNING:
411*d9f75844SAndroid Build Coastguard Worker       prio = ANDROID_LOG_WARN;
412*d9f75844SAndroid Build Coastguard Worker       break;
413*d9f75844SAndroid Build Coastguard Worker     case LS_ERROR:
414*d9f75844SAndroid Build Coastguard Worker       prio = ANDROID_LOG_ERROR;
415*d9f75844SAndroid Build Coastguard Worker       break;
416*d9f75844SAndroid Build Coastguard Worker     default:
417*d9f75844SAndroid Build Coastguard Worker       prio = ANDROID_LOG_UNKNOWN;
418*d9f75844SAndroid Build Coastguard Worker   }
419*d9f75844SAndroid Build Coastguard Worker 
420*d9f75844SAndroid Build Coastguard Worker   int size = msg_str.size();
421*d9f75844SAndroid Build Coastguard Worker   int current_line = 0;
422*d9f75844SAndroid Build Coastguard Worker   int idx = 0;
423*d9f75844SAndroid Build Coastguard Worker   const int max_lines = size / kMaxLogLineSize + 1;
424*d9f75844SAndroid Build Coastguard Worker   if (max_lines == 1) {
425*d9f75844SAndroid Build Coastguard Worker     __android_log_print(prio, log_line.tag().data(), "%.*s", size,
426*d9f75844SAndroid Build Coastguard Worker                         msg_str.c_str());
427*d9f75844SAndroid Build Coastguard Worker   } else {
428*d9f75844SAndroid Build Coastguard Worker     while (size > 0) {
429*d9f75844SAndroid Build Coastguard Worker       const int len = std::min(size, kMaxLogLineSize);
430*d9f75844SAndroid Build Coastguard Worker       // Use the size of the string in the format (msg may have \0 in the
431*d9f75844SAndroid Build Coastguard Worker       // middle).
432*d9f75844SAndroid Build Coastguard Worker       __android_log_print(prio, log_line.tag().data(), "[%d/%d] %.*s",
433*d9f75844SAndroid Build Coastguard Worker                           current_line + 1, max_lines, len,
434*d9f75844SAndroid Build Coastguard Worker                           msg_str.c_str() + idx);
435*d9f75844SAndroid Build Coastguard Worker       idx += len;
436*d9f75844SAndroid Build Coastguard Worker       size -= len;
437*d9f75844SAndroid Build Coastguard Worker       ++current_line;
438*d9f75844SAndroid Build Coastguard Worker     }
439*d9f75844SAndroid Build Coastguard Worker   }
440*d9f75844SAndroid Build Coastguard Worker #endif  // WEBRTC_ANDROID
441*d9f75844SAndroid Build Coastguard Worker   if (log_to_stderr) {
442*d9f75844SAndroid Build Coastguard Worker     fprintf(stderr, "%s", msg_str.c_str());
443*d9f75844SAndroid Build Coastguard Worker     fflush(stderr);
444*d9f75844SAndroid Build Coastguard Worker   }
445*d9f75844SAndroid Build Coastguard Worker }
446*d9f75844SAndroid Build Coastguard Worker 
447*d9f75844SAndroid Build Coastguard Worker // static
IsNoop(LoggingSeverity severity)448*d9f75844SAndroid Build Coastguard Worker bool LogMessage::IsNoop(LoggingSeverity severity) {
449*d9f75844SAndroid Build Coastguard Worker   if (severity >= g_dbg_sev || severity >= g_min_sev)
450*d9f75844SAndroid Build Coastguard Worker     return false;
451*d9f75844SAndroid Build Coastguard Worker   return streams_empty_.load(std::memory_order_relaxed);
452*d9f75844SAndroid Build Coastguard Worker }
453*d9f75844SAndroid Build Coastguard Worker 
FinishPrintStream()454*d9f75844SAndroid Build Coastguard Worker void LogMessage::FinishPrintStream() {
455*d9f75844SAndroid Build Coastguard Worker   if (!extra_.empty())
456*d9f75844SAndroid Build Coastguard Worker     print_stream_ << " : " << extra_;
457*d9f75844SAndroid Build Coastguard Worker   print_stream_ << "\n";
458*d9f75844SAndroid Build Coastguard Worker }
459*d9f75844SAndroid Build Coastguard Worker 
460*d9f75844SAndroid Build Coastguard Worker namespace webrtc_logging_impl {
461*d9f75844SAndroid Build Coastguard Worker 
Log(const LogArgType * fmt,...)462*d9f75844SAndroid Build Coastguard Worker void Log(const LogArgType* fmt, ...) {
463*d9f75844SAndroid Build Coastguard Worker   va_list args;
464*d9f75844SAndroid Build Coastguard Worker   va_start(args, fmt);
465*d9f75844SAndroid Build Coastguard Worker 
466*d9f75844SAndroid Build Coastguard Worker   LogMetadataErr meta;
467*d9f75844SAndroid Build Coastguard Worker   const char* tag = nullptr;
468*d9f75844SAndroid Build Coastguard Worker   switch (*fmt) {
469*d9f75844SAndroid Build Coastguard Worker     case LogArgType::kLogMetadata: {
470*d9f75844SAndroid Build Coastguard Worker       meta = {va_arg(args, LogMetadata), ERRCTX_NONE, 0};
471*d9f75844SAndroid Build Coastguard Worker       break;
472*d9f75844SAndroid Build Coastguard Worker     }
473*d9f75844SAndroid Build Coastguard Worker     case LogArgType::kLogMetadataErr: {
474*d9f75844SAndroid Build Coastguard Worker       meta = va_arg(args, LogMetadataErr);
475*d9f75844SAndroid Build Coastguard Worker       break;
476*d9f75844SAndroid Build Coastguard Worker     }
477*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
478*d9f75844SAndroid Build Coastguard Worker     case LogArgType::kLogMetadataTag: {
479*d9f75844SAndroid Build Coastguard Worker       const LogMetadataTag tag_meta = va_arg(args, LogMetadataTag);
480*d9f75844SAndroid Build Coastguard Worker       meta = {{nullptr, 0, tag_meta.severity}, ERRCTX_NONE, 0};
481*d9f75844SAndroid Build Coastguard Worker       tag = tag_meta.tag;
482*d9f75844SAndroid Build Coastguard Worker       break;
483*d9f75844SAndroid Build Coastguard Worker     }
484*d9f75844SAndroid Build Coastguard Worker #endif
485*d9f75844SAndroid Build Coastguard Worker     default: {
486*d9f75844SAndroid Build Coastguard Worker       RTC_DCHECK_NOTREACHED();
487*d9f75844SAndroid Build Coastguard Worker       va_end(args);
488*d9f75844SAndroid Build Coastguard Worker       return;
489*d9f75844SAndroid Build Coastguard Worker     }
490*d9f75844SAndroid Build Coastguard Worker   }
491*d9f75844SAndroid Build Coastguard Worker 
492*d9f75844SAndroid Build Coastguard Worker   LogMessage log_message(meta.meta.File(), meta.meta.Line(),
493*d9f75844SAndroid Build Coastguard Worker                          meta.meta.Severity(), meta.err_ctx, meta.err);
494*d9f75844SAndroid Build Coastguard Worker   if (tag) {
495*d9f75844SAndroid Build Coastguard Worker     log_message.AddTag(tag);
496*d9f75844SAndroid Build Coastguard Worker   }
497*d9f75844SAndroid Build Coastguard Worker 
498*d9f75844SAndroid Build Coastguard Worker   for (++fmt; *fmt != LogArgType::kEnd; ++fmt) {
499*d9f75844SAndroid Build Coastguard Worker     switch (*fmt) {
500*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kInt:
501*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << va_arg(args, int);
502*d9f75844SAndroid Build Coastguard Worker         break;
503*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kLong:
504*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << va_arg(args, long);
505*d9f75844SAndroid Build Coastguard Worker         break;
506*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kLongLong:
507*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << va_arg(args, long long);
508*d9f75844SAndroid Build Coastguard Worker         break;
509*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kUInt:
510*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << va_arg(args, unsigned);
511*d9f75844SAndroid Build Coastguard Worker         break;
512*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kULong:
513*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << va_arg(args, unsigned long);
514*d9f75844SAndroid Build Coastguard Worker         break;
515*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kULongLong:
516*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << va_arg(args, unsigned long long);
517*d9f75844SAndroid Build Coastguard Worker         break;
518*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kDouble:
519*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << va_arg(args, double);
520*d9f75844SAndroid Build Coastguard Worker         break;
521*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kLongDouble:
522*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << va_arg(args, long double);
523*d9f75844SAndroid Build Coastguard Worker         break;
524*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kCharP: {
525*d9f75844SAndroid Build Coastguard Worker         const char* s = va_arg(args, const char*);
526*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << (s ? s : "(null)");
527*d9f75844SAndroid Build Coastguard Worker         break;
528*d9f75844SAndroid Build Coastguard Worker       }
529*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kStdString:
530*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << *va_arg(args, const std::string*);
531*d9f75844SAndroid Build Coastguard Worker         break;
532*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kStringView:
533*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << *va_arg(args, const absl::string_view*);
534*d9f75844SAndroid Build Coastguard Worker         break;
535*d9f75844SAndroid Build Coastguard Worker       case LogArgType::kVoidP:
536*d9f75844SAndroid Build Coastguard Worker         log_message.stream() << rtc::ToHex(
537*d9f75844SAndroid Build Coastguard Worker             reinterpret_cast<uintptr_t>(va_arg(args, const void*)));
538*d9f75844SAndroid Build Coastguard Worker         break;
539*d9f75844SAndroid Build Coastguard Worker       default:
540*d9f75844SAndroid Build Coastguard Worker         RTC_DCHECK_NOTREACHED();
541*d9f75844SAndroid Build Coastguard Worker         va_end(args);
542*d9f75844SAndroid Build Coastguard Worker         return;
543*d9f75844SAndroid Build Coastguard Worker     }
544*d9f75844SAndroid Build Coastguard Worker   }
545*d9f75844SAndroid Build Coastguard Worker 
546*d9f75844SAndroid Build Coastguard Worker   va_end(args);
547*d9f75844SAndroid Build Coastguard Worker }
548*d9f75844SAndroid Build Coastguard Worker 
549*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc_logging_impl
550*d9f75844SAndroid Build Coastguard Worker }  // namespace rtc
551*d9f75844SAndroid Build Coastguard Worker #endif
552*d9f75844SAndroid Build Coastguard Worker 
553*d9f75844SAndroid Build Coastguard Worker namespace rtc {
554*d9f75844SAndroid Build Coastguard Worker // Default implementation, override is recomended.
OnLogMessage(const LogLineRef & log_line)555*d9f75844SAndroid Build Coastguard Worker void LogSink::OnLogMessage(const LogLineRef& log_line) {
556*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_ANDROID)
557*d9f75844SAndroid Build Coastguard Worker   OnLogMessage(log_line.DefaultLogLine(), log_line.severity(),
558*d9f75844SAndroid Build Coastguard Worker                log_line.tag().data());
559*d9f75844SAndroid Build Coastguard Worker #else
560*d9f75844SAndroid Build Coastguard Worker   OnLogMessage(log_line.DefaultLogLine(), log_line.severity());
561*d9f75844SAndroid Build Coastguard Worker #endif
562*d9f75844SAndroid Build Coastguard Worker }
563*d9f75844SAndroid Build Coastguard Worker 
564*d9f75844SAndroid Build Coastguard Worker // Inefficient default implementation, override is recommended.
OnLogMessage(const std::string & msg,LoggingSeverity severity,const char * tag)565*d9f75844SAndroid Build Coastguard Worker void LogSink::OnLogMessage(const std::string& msg,
566*d9f75844SAndroid Build Coastguard Worker                            LoggingSeverity severity,
567*d9f75844SAndroid Build Coastguard Worker                            const char* tag) {
568*d9f75844SAndroid Build Coastguard Worker   OnLogMessage(tag + (": " + msg), severity);
569*d9f75844SAndroid Build Coastguard Worker }
570*d9f75844SAndroid Build Coastguard Worker 
OnLogMessage(const std::string & msg,LoggingSeverity)571*d9f75844SAndroid Build Coastguard Worker void LogSink::OnLogMessage(const std::string& msg,
572*d9f75844SAndroid Build Coastguard Worker                            LoggingSeverity /* severity */) {
573*d9f75844SAndroid Build Coastguard Worker   OnLogMessage(msg);
574*d9f75844SAndroid Build Coastguard Worker }
575*d9f75844SAndroid Build Coastguard Worker 
576*d9f75844SAndroid Build Coastguard Worker // Inefficient default implementation, override is recommended.
OnLogMessage(absl::string_view msg,LoggingSeverity severity,const char * tag)577*d9f75844SAndroid Build Coastguard Worker void LogSink::OnLogMessage(absl::string_view msg,
578*d9f75844SAndroid Build Coastguard Worker                            LoggingSeverity severity,
579*d9f75844SAndroid Build Coastguard Worker                            const char* tag) {
580*d9f75844SAndroid Build Coastguard Worker   OnLogMessage(tag + (": " + std::string(msg)), severity);
581*d9f75844SAndroid Build Coastguard Worker }
582*d9f75844SAndroid Build Coastguard Worker 
OnLogMessage(absl::string_view msg,LoggingSeverity)583*d9f75844SAndroid Build Coastguard Worker void LogSink::OnLogMessage(absl::string_view msg,
584*d9f75844SAndroid Build Coastguard Worker                            LoggingSeverity /* severity */) {
585*d9f75844SAndroid Build Coastguard Worker   OnLogMessage(msg);
586*d9f75844SAndroid Build Coastguard Worker }
587*d9f75844SAndroid Build Coastguard Worker 
OnLogMessage(absl::string_view msg)588*d9f75844SAndroid Build Coastguard Worker void LogSink::OnLogMessage(absl::string_view msg) {
589*d9f75844SAndroid Build Coastguard Worker   OnLogMessage(std::string(msg));
590*d9f75844SAndroid Build Coastguard Worker }
591*d9f75844SAndroid Build Coastguard Worker }  // namespace rtc
592