| 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 |