| 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 bool LogMessage::log_to_stderr_ = true; | 103 bool LogMessage::log_to_stderr_ = true; |
| 104 | 104 |
| 105 namespace { | 105 namespace { |
| 106 // Global lock for log subsystem, only needed to serialize access to streams_. | 106 // Global lock for log subsystem, only needed to serialize access to streams_. |
| 107 CriticalSection g_log_crit; | 107 CriticalSection g_log_crit; |
| 108 } // namespace | 108 } // namespace |
| 109 | 109 |
| 110 // The list of logging streams currently configured. | 110 // The list of logging streams currently configured. |
| 111 // Note: we explicitly do not clean this up, because of the uncertain ordering | 111 // Note: we explicitly do not clean this up, because of the uncertain ordering |
| 112 // of destructors at program exit. Let the person who sets the stream trigger | 112 // of destructors at program exit. Let the person who sets the stream trigger |
| 113 // cleanup by setting to NULL, or let it leak (safe at program exit). | 113 // cleanup by setting to null, or let it leak (safe at program exit). |
| 114 LogMessage::StreamList LogMessage::streams_ GUARDED_BY(g_log_crit); | 114 LogMessage::StreamList LogMessage::streams_ GUARDED_BY(g_log_crit); |
| 115 | 115 |
| 116 // Boolean options default to false (0) | 116 // Boolean options default to false (0) |
| 117 bool LogMessage::thread_, LogMessage::timestamp_; | 117 bool LogMessage::thread_, LogMessage::timestamp_; |
| 118 | 118 |
| 119 LogMessage::LogMessage(const char* file, | 119 LogMessage::LogMessage(const char* file, |
| 120 int line, | 120 int line, |
| 121 LoggingSeverity sev, | 121 LoggingSeverity sev, |
| 122 LogErrorContext err_ctx, | 122 LogErrorContext err_ctx, |
| 123 int err, | 123 int err, |
| 124 const char* module) | 124 const char* module) |
| 125 : severity_(sev), tag_(kLibjingle) { | 125 : severity_(sev), tag_(kLibjingle) { |
| 126 if (timestamp_) { | 126 if (timestamp_) { |
| 127 // Use SystemTimeMillis so that even if tests use fake clocks, the timestamp | 127 // Use SystemTimeMillis so that even if tests use fake clocks, the timestamp |
| 128 // in log messages represents the real system time. | 128 // in log messages represents the real system time. |
| 129 int64_t time = TimeDiff(SystemTimeMillis(), LogStartTime()); | 129 int64_t time = TimeDiff(SystemTimeMillis(), LogStartTime()); |
| 130 // Also ensure WallClockStartTime is initialized, so that it matches | 130 // Also ensure WallClockStartTime is initialized, so that it matches |
| 131 // LogStartTime. | 131 // LogStartTime. |
| 132 WallClockStartTime(); | 132 WallClockStartTime(); |
| 133 print_stream_ << "[" << std::setfill('0') << std::setw(3) << (time / 1000) | 133 print_stream_ << "[" << std::setfill('0') << std::setw(3) << (time / 1000) |
| 134 << ":" << std::setw(3) << (time % 1000) << std::setfill(' ') | 134 << ":" << std::setw(3) << (time % 1000) << std::setfill(' ') |
| 135 << "] "; | 135 << "] "; |
| 136 } | 136 } |
| 137 | 137 |
| 138 if (thread_) { | 138 if (thread_) { |
| 139 PlatformThreadId id = CurrentThreadId(); | 139 PlatformThreadId id = CurrentThreadId(); |
| 140 print_stream_ << "[" << std::dec << id << "] "; | 140 print_stream_ << "[" << std::dec << id << "] "; |
| 141 } | 141 } |
| 142 | 142 |
| 143 if (file != NULL) | 143 if (file != nullptr) |
| 144 print_stream_ << "(" << FilenameFromPath(file) << ":" << line << "): "; | 144 print_stream_ << "(" << FilenameFromPath(file) << ":" << line << "): "; |
| 145 | 145 |
| 146 if (err_ctx != ERRCTX_NONE) { | 146 if (err_ctx != ERRCTX_NONE) { |
| 147 std::ostringstream tmp; | 147 std::ostringstream tmp; |
| 148 tmp << "[0x" << std::setfill('0') << std::hex << std::setw(8) << err << "]"; | 148 tmp << "[0x" << std::setfill('0') << std::hex << std::setw(8) << err << "]"; |
| 149 switch (err_ctx) { | 149 switch (err_ctx) { |
| 150 case ERRCTX_ERRNO: | 150 case ERRCTX_ERRNO: |
| 151 tmp << " " << strerror(err); | 151 tmp << " " << strerror(err); |
| 152 break; | 152 break; |
| 153 #ifdef WEBRTC_WIN | 153 #ifdef WEBRTC_WIN |
| 154 case ERRCTX_HRESULT: { | 154 case ERRCTX_HRESULT: { |
| 155 char msgbuf[256]; | 155 char msgbuf[256]; |
| 156 DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM; | 156 DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM; |
| 157 HMODULE hmod = GetModuleHandleA(module); | 157 HMODULE hmod = GetModuleHandleA(module); |
| 158 if (hmod) | 158 if (hmod) |
| 159 flags |= FORMAT_MESSAGE_FROM_HMODULE; | 159 flags |= FORMAT_MESSAGE_FROM_HMODULE; |
| 160 if (DWORD len = FormatMessageA( | 160 if (DWORD len = FormatMessageA( |
| 161 flags, hmod, err, | 161 flags, hmod, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
| 162 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | 162 msgbuf, sizeof(msgbuf) / sizeof(msgbuf[0]), nullptr)) { |
| 163 msgbuf, sizeof(msgbuf) / sizeof(msgbuf[0]), NULL)) { | |
| 164 while ((len > 0) && | 163 while ((len > 0) && |
| 165 isspace(static_cast<unsigned char>(msgbuf[len-1]))) { | 164 isspace(static_cast<unsigned char>(msgbuf[len-1]))) { |
| 166 msgbuf[--len] = 0; | 165 msgbuf[--len] = 0; |
| 167 } | 166 } |
| 168 tmp << " " << msgbuf; | 167 tmp << " " << msgbuf; |
| 169 } | 168 } |
| 170 break; | 169 break; |
| 171 } | 170 } |
| 172 #endif // WEBRTC_WIN | 171 #endif // WEBRTC_WIN |
| 173 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) | 172 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) |
| 174 case ERRCTX_OSSTATUS: { | 173 case ERRCTX_OSSTATUS: { |
| 175 std::string desc(DescriptionFromOSStatus(err)); | 174 std::string desc(DescriptionFromOSStatus(err)); |
| 176 tmp << " " << (desc.empty() ? "Unknown error" : desc.c_str()); | 175 tmp << " " << (desc.empty() ? "Unknown error" : desc.c_str()); |
| 177 break; | 176 break; |
| 178 } | 177 } |
| 179 #endif // WEBRTC_MAC && !defined(WEBRTC_IOS) | 178 #endif // WEBRTC_MAC && !defined(WEBRTC_IOS) |
| 180 default: | 179 default: |
| 181 break; | 180 break; |
| 182 } | 181 } |
| 183 extra_ = tmp.str(); | 182 extra_ = tmp.str(); |
| 184 } | 183 } |
| 185 } | 184 } |
| 186 | 185 |
| 187 LogMessage::LogMessage(const char* file, | 186 LogMessage::LogMessage(const char* file, |
| 188 int line, | 187 int line, |
| 189 LoggingSeverity sev, | 188 LoggingSeverity sev, |
| 190 const std::string& tag) | 189 const std::string& tag) |
| 191 : LogMessage(file, line, sev, ERRCTX_NONE, 0 /* err */, NULL /* module */) { | 190 : LogMessage(file, |
| 191 line, |
| 192 sev, |
| 193 ERRCTX_NONE, |
| 194 0 /* err */, |
| 195 nullptr /* module */) { |
| 192 tag_ = tag; | 196 tag_ = tag; |
| 193 print_stream_ << tag << ": "; | 197 print_stream_ << tag << ": "; |
| 194 } | 198 } |
| 195 | 199 |
| 196 LogMessage::~LogMessage() { | 200 LogMessage::~LogMessage() { |
| 197 if (!extra_.empty()) | 201 if (!extra_.empty()) |
| 198 print_stream_ << " : " << extra_; | 202 print_stream_ << " : " << extra_; |
| 199 print_stream_ << std::endl; | 203 print_stream_ << std::endl; |
| 200 | 204 |
| 201 const std::string& str = print_stream_.str(); | 205 const std::string& str = print_stream_.str(); |
| 202 if (severity_ >= dbg_sev_) { | 206 if (severity_ >= dbg_sev_) { |
| 203 OutputToDebug(str, severity_, tag_); | 207 OutputToDebug(str, severity_, tag_); |
| 204 } | 208 } |
| 205 | 209 |
| 206 CritScope cs(&g_log_crit); | 210 CritScope cs(&g_log_crit); |
| 207 for (auto& kv : streams_) { | 211 for (auto& kv : streams_) { |
| 208 if (severity_ >= kv.second) { | 212 if (severity_ >= kv.second) { |
| 209 kv.first->OnLogMessage(str); | 213 kv.first->OnLogMessage(str); |
| 210 } | 214 } |
| 211 } | 215 } |
| 212 } | 216 } |
| 213 | 217 |
| 214 int64_t LogMessage::LogStartTime() { | 218 int64_t LogMessage::LogStartTime() { |
| 215 static const int64_t g_start = SystemTimeMillis(); | 219 static const int64_t g_start = SystemTimeMillis(); |
| 216 return g_start; | 220 return g_start; |
| 217 } | 221 } |
| 218 | 222 |
| 219 uint32_t LogMessage::WallClockStartTime() { | 223 uint32_t LogMessage::WallClockStartTime() { |
| 220 static const uint32_t g_start_wallclock = time(NULL); | 224 static const uint32_t g_start_wallclock = time(nullptr); |
| 221 return g_start_wallclock; | 225 return g_start_wallclock; |
| 222 } | 226 } |
| 223 | 227 |
| 224 void LogMessage::LogThreads(bool on) { | 228 void LogMessage::LogThreads(bool on) { |
| 225 thread_ = on; | 229 thread_ = on; |
| 226 } | 230 } |
| 227 | 231 |
| 228 void LogMessage::LogTimestamps(bool on) { | 232 void LogMessage::LogTimestamps(bool on) { |
| 229 timestamp_ = on; | 233 timestamp_ = on; |
| 230 } | 234 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 const std::string& tag) { | 346 const std::string& tag) { |
| 343 bool log_to_stderr = log_to_stderr_; | 347 bool log_to_stderr = log_to_stderr_; |
| 344 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && defined(NDEBUG) | 348 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && defined(NDEBUG) |
| 345 // On the Mac, all stderr output goes to the Console log and causes clutter. | 349 // On the Mac, all stderr output goes to the Console log and causes clutter. |
| 346 // So in opt builds, don't log to stderr unless the user specifically sets | 350 // So in opt builds, don't log to stderr unless the user specifically sets |
| 347 // a preference to do so. | 351 // a preference to do so. |
| 348 CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault, | 352 CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault, |
| 349 "logToStdErr", | 353 "logToStdErr", |
| 350 kCFStringEncodingUTF8); | 354 kCFStringEncodingUTF8); |
| 351 CFStringRef domain = CFBundleGetIdentifier(CFBundleGetMainBundle()); | 355 CFStringRef domain = CFBundleGetIdentifier(CFBundleGetMainBundle()); |
| 352 if (key != NULL && domain != NULL) { | 356 if (key != nullptr && domain != nullptr) { |
| 353 Boolean exists_and_is_valid; | 357 Boolean exists_and_is_valid; |
| 354 Boolean should_log = | 358 Boolean should_log = |
| 355 CFPreferencesGetAppBooleanValue(key, domain, &exists_and_is_valid); | 359 CFPreferencesGetAppBooleanValue(key, domain, &exists_and_is_valid); |
| 356 // If the key doesn't exist or is invalid or is false, we will not log to | 360 // If the key doesn't exist or is invalid or is false, we will not log to |
| 357 // stderr. | 361 // stderr. |
| 358 log_to_stderr = exists_and_is_valid && should_log; | 362 log_to_stderr = exists_and_is_valid && should_log; |
| 359 } | 363 } |
| 360 if (key != NULL) { | 364 if (key != nullptr) { |
| 361 CFRelease(key); | 365 CFRelease(key); |
| 362 } | 366 } |
| 363 #endif | 367 #endif |
| 364 #if defined(WEBRTC_WIN) | 368 #if defined(WEBRTC_WIN) |
| 365 // Always log to the debugger. | 369 // Always log to the debugger. |
| 366 // Perhaps stderr should be controlled by a preference, as on Mac? | 370 // Perhaps stderr should be controlled by a preference, as on Mac? |
| 367 OutputDebugStringA(str.c_str()); | 371 OutputDebugStringA(str.c_str()); |
| 368 if (log_to_stderr) { | 372 if (log_to_stderr) { |
| 369 // This handles dynamically allocated consoles, too. | 373 // This handles dynamically allocated consoles, too. |
| 370 if (HANDLE error_handle = ::GetStdHandle(STD_ERROR_HANDLE)) { | 374 if (HANDLE error_handle = ::GetStdHandle(STD_ERROR_HANDLE)) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 ////////////////////////////////////////////////////////////////////// | 440 ////////////////////////////////////////////////////////////////////// |
| 437 | 441 |
| 438 void LogMultiline(LoggingSeverity level, const char* label, bool input, | 442 void LogMultiline(LoggingSeverity level, const char* label, bool input, |
| 439 const void* data, size_t len, bool hex_mode, | 443 const void* data, size_t len, bool hex_mode, |
| 440 LogMultilineState* state) { | 444 LogMultilineState* state) { |
| 441 if (!LOG_CHECK_LEVEL_V(level)) | 445 if (!LOG_CHECK_LEVEL_V(level)) |
| 442 return; | 446 return; |
| 443 | 447 |
| 444 const char * direction = (input ? " << " : " >> "); | 448 const char * direction = (input ? " << " : " >> "); |
| 445 | 449 |
| 446 // NULL data means to flush our count of unprintable characters. | 450 // null data means to flush our count of unprintable characters. |
| 447 if (!data) { | 451 if (!data) { |
| 448 if (state && state->unprintable_count_[input]) { | 452 if (state && state->unprintable_count_[input]) { |
| 449 LOG_V(level) << label << direction << "## " | 453 LOG_V(level) << label << direction << "## " |
| 450 << state->unprintable_count_[input] | 454 << state->unprintable_count_[input] |
| 451 << " consecutive unprintable ##"; | 455 << " consecutive unprintable ##"; |
| 452 state->unprintable_count_[input] = 0; | 456 state->unprintable_count_[input] = 0; |
| 453 } | 457 } |
| 454 return; | 458 return; |
| 455 } | 459 } |
| 456 | 460 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 } | 552 } |
| 549 | 553 |
| 550 if (state) { | 554 if (state) { |
| 551 state->unprintable_count_[input] = consecutive_unprintable; | 555 state->unprintable_count_[input] = consecutive_unprintable; |
| 552 } | 556 } |
| 553 } | 557 } |
| 554 | 558 |
| 555 ////////////////////////////////////////////////////////////////////// | 559 ////////////////////////////////////////////////////////////////////// |
| 556 | 560 |
| 557 } // namespace rtc | 561 } // namespace rtc |
| OLD | NEW |