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 |