OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 static const char kLibjingle[] = "libjingle"; | 30 static const char kLibjingle[] = "libjingle"; |
31 | 31 |
32 #include <time.h> | 32 #include <time.h> |
33 #include <limits.h> | 33 #include <limits.h> |
34 | 34 |
35 #include <algorithm> | 35 #include <algorithm> |
36 #include <iomanip> | 36 #include <iomanip> |
37 #include <ostream> | 37 #include <ostream> |
38 #include <vector> | 38 #include <vector> |
39 | 39 |
| 40 #include "webrtc/base/criticalsection.h" |
40 #include "webrtc/base/logging.h" | 41 #include "webrtc/base/logging.h" |
41 #include "webrtc/base/platform_thread.h" | 42 #include "webrtc/base/platform_thread.h" |
42 #include "webrtc/base/scoped_ptr.h" | 43 #include "webrtc/base/scoped_ptr.h" |
43 #include "webrtc/base/stringencode.h" | 44 #include "webrtc/base/stringencode.h" |
44 #include "webrtc/base/stringutils.h" | 45 #include "webrtc/base/stringutils.h" |
45 #include "webrtc/base/timeutils.h" | 46 #include "webrtc/base/timeutils.h" |
46 | 47 |
47 namespace rtc { | 48 namespace rtc { |
48 namespace { | 49 namespace { |
49 | 50 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 // By default, release builds don't log, debug builds at info level | 94 // By default, release builds don't log, debug builds at info level |
94 #if _DEBUG | 95 #if _DEBUG |
95 LoggingSeverity LogMessage::min_sev_ = LS_INFO; | 96 LoggingSeverity LogMessage::min_sev_ = LS_INFO; |
96 LoggingSeverity LogMessage::dbg_sev_ = LS_INFO; | 97 LoggingSeverity LogMessage::dbg_sev_ = LS_INFO; |
97 #else // !_DEBUG | 98 #else // !_DEBUG |
98 LoggingSeverity LogMessage::min_sev_ = LS_NONE; | 99 LoggingSeverity LogMessage::min_sev_ = LS_NONE; |
99 LoggingSeverity LogMessage::dbg_sev_ = LS_NONE; | 100 LoggingSeverity LogMessage::dbg_sev_ = LS_NONE; |
100 #endif // !_DEBUG | 101 #endif // !_DEBUG |
101 bool LogMessage::log_to_stderr_ = true; | 102 bool LogMessage::log_to_stderr_ = true; |
102 | 103 |
| 104 namespace { |
103 // Global lock for log subsystem, only needed to serialize access to streams_. | 105 // Global lock for log subsystem, only needed to serialize access to streams_. |
104 CriticalSection LogMessage::crit_; | 106 CriticalSection g_log_crit; |
| 107 } // namespace |
105 | 108 |
106 // The list of logging streams currently configured. | 109 // The list of logging streams currently configured. |
107 // Note: we explicitly do not clean this up, because of the uncertain ordering | 110 // Note: we explicitly do not clean this up, because of the uncertain ordering |
108 // of destructors at program exit. Let the person who sets the stream trigger | 111 // of destructors at program exit. Let the person who sets the stream trigger |
109 // cleanup by setting to NULL, or let it leak (safe at program exit). | 112 // cleanup by setting to NULL, or let it leak (safe at program exit). |
110 LogMessage::StreamList LogMessage::streams_ GUARDED_BY(LogMessage::crit_); | 113 LogMessage::StreamList LogMessage::streams_ GUARDED_BY(g_log_crit); |
111 | 114 |
112 // Boolean options default to false (0) | 115 // Boolean options default to false (0) |
113 bool LogMessage::thread_, LogMessage::timestamp_; | 116 bool LogMessage::thread_, LogMessage::timestamp_; |
114 | 117 |
115 LogMessage::LogMessage(const char* file, int line, LoggingSeverity sev, | 118 LogMessage::LogMessage(const char* file, |
116 LogErrorContext err_ctx, int err, const char* module) | 119 int line, |
117 : severity_(sev), | 120 LoggingSeverity sev, |
118 tag_(kLibjingle), | 121 LogErrorContext err_ctx, |
119 warn_slow_logs_delay_(WARN_SLOW_LOGS_DELAY) { | 122 int err, |
| 123 const char* module) |
| 124 : severity_(sev), tag_(kLibjingle) { |
120 if (timestamp_) { | 125 if (timestamp_) { |
121 uint32_t time = TimeSince(LogStartTime()); | 126 uint32_t time = TimeSince(LogStartTime()); |
122 // Also ensure WallClockStartTime is initialized, so that it matches | 127 // Also ensure WallClockStartTime is initialized, so that it matches |
123 // LogStartTime. | 128 // LogStartTime. |
124 WallClockStartTime(); | 129 WallClockStartTime(); |
125 print_stream_ << "[" << std::setfill('0') << std::setw(3) << (time / 1000) | 130 print_stream_ << "[" << std::setfill('0') << std::setw(3) << (time / 1000) |
126 << ":" << std::setw(3) << (time % 1000) << std::setfill(' ') | 131 << ":" << std::setw(3) << (time % 1000) << std::setfill(' ') |
127 << "] "; | 132 << "] "; |
128 } | 133 } |
129 | 134 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 LogMessage::~LogMessage() { | 195 LogMessage::~LogMessage() { |
191 if (!extra_.empty()) | 196 if (!extra_.empty()) |
192 print_stream_ << " : " << extra_; | 197 print_stream_ << " : " << extra_; |
193 print_stream_ << std::endl; | 198 print_stream_ << std::endl; |
194 | 199 |
195 const std::string& str = print_stream_.str(); | 200 const std::string& str = print_stream_.str(); |
196 if (severity_ >= dbg_sev_) { | 201 if (severity_ >= dbg_sev_) { |
197 OutputToDebug(str, severity_, tag_); | 202 OutputToDebug(str, severity_, tag_); |
198 } | 203 } |
199 | 204 |
200 uint32_t before = Time(); | 205 CritScope cs(&g_log_crit); |
201 // Must lock streams_ before accessing | 206 for (auto& kv : streams_) { |
202 CritScope cs(&crit_); | 207 if (severity_ >= kv.second) { |
203 for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) { | 208 kv.first->OnLogMessage(str); |
204 if (severity_ >= it->second) { | |
205 it->first->OnLogMessage(str); | |
206 } | 209 } |
207 } | 210 } |
208 uint32_t delay = TimeSince(before); | |
209 if (delay >= warn_slow_logs_delay_) { | |
210 rtc::LogMessage slow_log_warning(__FILE__, __LINE__, LS_WARNING); | |
211 // If our warning is slow, we don't want to warn about it, because | |
212 // that would lead to inifinite recursion. So, give a really big | |
213 // number for the delay threshold. | |
214 slow_log_warning.warn_slow_logs_delay_ = UINT_MAX; | |
215 slow_log_warning.stream() << "Slow log: took " << delay << "ms to write " | |
216 << str.size() << " bytes."; | |
217 } | |
218 } | 211 } |
219 | 212 |
220 uint32_t LogMessage::LogStartTime() { | 213 uint32_t LogMessage::LogStartTime() { |
221 static const uint32_t g_start = Time(); | 214 static const uint32_t g_start = Time(); |
222 return g_start; | 215 return g_start; |
223 } | 216 } |
224 | 217 |
225 uint32_t LogMessage::WallClockStartTime() { | 218 uint32_t LogMessage::WallClockStartTime() { |
226 static const uint32_t g_start_wallclock = time(NULL); | 219 static const uint32_t g_start_wallclock = time(NULL); |
227 return g_start_wallclock; | 220 return g_start_wallclock; |
228 } | 221 } |
229 | 222 |
230 void LogMessage::LogThreads(bool on) { | 223 void LogMessage::LogThreads(bool on) { |
231 thread_ = on; | 224 thread_ = on; |
232 } | 225 } |
233 | 226 |
234 void LogMessage::LogTimestamps(bool on) { | 227 void LogMessage::LogTimestamps(bool on) { |
235 timestamp_ = on; | 228 timestamp_ = on; |
236 } | 229 } |
237 | 230 |
238 void LogMessage::LogToDebug(LoggingSeverity min_sev) { | 231 void LogMessage::LogToDebug(LoggingSeverity min_sev) { |
239 dbg_sev_ = min_sev; | 232 dbg_sev_ = min_sev; |
240 CritScope cs(&crit_); | 233 CritScope cs(&g_log_crit); |
241 UpdateMinLogSeverity(); | 234 UpdateMinLogSeverity(); |
242 } | 235 } |
243 | 236 |
244 void LogMessage::SetLogToStderr(bool log_to_stderr) { | 237 void LogMessage::SetLogToStderr(bool log_to_stderr) { |
245 log_to_stderr_ = log_to_stderr; | 238 log_to_stderr_ = log_to_stderr; |
246 } | 239 } |
247 | 240 |
248 int LogMessage::GetLogToStream(LogSink* stream) { | 241 int LogMessage::GetLogToStream(LogSink* stream) { |
249 CritScope cs(&crit_); | 242 CritScope cs(&g_log_crit); |
250 LoggingSeverity sev = LS_NONE; | 243 LoggingSeverity sev = LS_NONE; |
251 for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) { | 244 for (auto& kv : streams_) { |
252 if (!stream || stream == it->first) { | 245 if (!stream || stream == kv.first) { |
253 sev = std::min(sev, it->second); | 246 sev = std::min(sev, kv.second); |
254 } | 247 } |
255 } | 248 } |
256 return sev; | 249 return sev; |
257 } | 250 } |
258 | 251 |
259 void LogMessage::AddLogToStream(LogSink* stream, LoggingSeverity min_sev) { | 252 void LogMessage::AddLogToStream(LogSink* stream, LoggingSeverity min_sev) { |
260 CritScope cs(&crit_); | 253 CritScope cs(&g_log_crit); |
261 streams_.push_back(std::make_pair(stream, min_sev)); | 254 streams_.push_back(std::make_pair(stream, min_sev)); |
262 UpdateMinLogSeverity(); | 255 UpdateMinLogSeverity(); |
263 } | 256 } |
264 | 257 |
265 void LogMessage::RemoveLogToStream(LogSink* stream) { | 258 void LogMessage::RemoveLogToStream(LogSink* stream) { |
266 CritScope cs(&crit_); | 259 CritScope cs(&g_log_crit); |
267 for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) { | 260 for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) { |
268 if (stream == it->first) { | 261 if (stream == it->first) { |
269 streams_.erase(it); | 262 streams_.erase(it); |
270 break; | 263 break; |
271 } | 264 } |
272 } | 265 } |
273 UpdateMinLogSeverity(); | 266 UpdateMinLogSeverity(); |
274 } | 267 } |
275 | 268 |
276 void LogMessage::ConfigureLogging(const char* params) { | 269 void LogMessage::ConfigureLogging(const char* params) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 } | 321 } |
329 if (!success) { | 322 if (!success) { |
330 ::AllocConsole(); | 323 ::AllocConsole(); |
331 } | 324 } |
332 } | 325 } |
333 #endif // WEBRTC_WIN | 326 #endif // WEBRTC_WIN |
334 | 327 |
335 LogToDebug(debug_level); | 328 LogToDebug(debug_level); |
336 } | 329 } |
337 | 330 |
338 void LogMessage::UpdateMinLogSeverity() EXCLUSIVE_LOCKS_REQUIRED(crit_) { | 331 void LogMessage::UpdateMinLogSeverity() EXCLUSIVE_LOCKS_REQUIRED(g_log_crit) { |
339 LoggingSeverity min_sev = dbg_sev_; | 332 LoggingSeverity min_sev = dbg_sev_; |
340 for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) { | 333 for (auto& kv : streams_) { |
341 min_sev = std::min(dbg_sev_, it->second); | 334 min_sev = std::min(dbg_sev_, kv.second); |
342 } | 335 } |
343 min_sev_ = min_sev; | 336 min_sev_ = min_sev; |
344 } | 337 } |
345 | 338 |
346 void LogMessage::OutputToDebug(const std::string& str, | 339 void LogMessage::OutputToDebug(const std::string& str, |
347 LoggingSeverity severity, | 340 LoggingSeverity severity, |
348 const std::string& tag) { | 341 const std::string& tag) { |
349 bool log_to_stderr = log_to_stderr_; | 342 bool log_to_stderr = log_to_stderr_; |
350 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && (!defined(_DEBUG) || defined(
NDEBUG)) | 343 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && (!defined(_DEBUG) || defined(
NDEBUG)) |
351 // On the Mac, all stderr output goes to the Console log and causes clutter. | 344 // On the Mac, all stderr output goes to the Console log and causes clutter. |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 } | 547 } |
555 | 548 |
556 if (state) { | 549 if (state) { |
557 state->unprintable_count_[input] = consecutive_unprintable; | 550 state->unprintable_count_[input] = consecutive_unprintable; |
558 } | 551 } |
559 } | 552 } |
560 | 553 |
561 ////////////////////////////////////////////////////////////////////// | 554 ////////////////////////////////////////////////////////////////////// |
562 | 555 |
563 } // namespace rtc | 556 } // namespace rtc |
OLD | NEW |