OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/logging.h" | 5 #include "base/logging.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <io.h> | 8 #include <io.h> |
9 #include <windows.h> | 9 #include <windows.h> |
10 typedef HANDLE FileHandle; | 10 typedef HANDLE FileHandle; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 namespace { | 78 namespace { |
79 | 79 |
80 VlogInfo* g_vlog_info = NULL; | 80 VlogInfo* g_vlog_info = NULL; |
81 VlogInfo* g_vlog_info_prev = NULL; | 81 VlogInfo* g_vlog_info_prev = NULL; |
82 | 82 |
83 const char* const log_severity_names[LOG_NUM_SEVERITIES] = { | 83 const char* const log_severity_names[LOG_NUM_SEVERITIES] = { |
84 "INFO", "WARNING", "ERROR", "ERROR_REPORT", "FATAL" }; | 84 "INFO", "WARNING", "ERROR", "ERROR_REPORT", "FATAL" }; |
85 | 85 |
86 int min_log_level = 0; | 86 int min_log_level = 0; |
87 | 87 |
88 // The default set here for logging_destination will only be used if | 88 LoggingDestination logging_destination = LOG_DEFAULT; |
89 // InitLogging is not called. On Windows, use a file next to the exe; | |
90 // on POSIX platforms, where it may not even be possible to locate the | |
91 // executable on disk, use stderr. | |
92 #if defined(OS_WIN) | |
93 LoggingDestination logging_destination = LOG_ONLY_TO_FILE; | |
94 #elif defined(OS_POSIX) | |
95 LoggingDestination logging_destination = LOG_ONLY_TO_SYSTEM_DEBUG_LOG; | |
96 #endif | |
97 | 89 |
98 // For LOG_ERROR and above, always print to stderr. | 90 // For LOG_ERROR and above, always print to stderr. |
99 const int kAlwaysPrintErrorLevel = LOG_ERROR; | 91 const int kAlwaysPrintErrorLevel = LOG_ERROR; |
100 | 92 |
101 // Which log file to use? This is initialized by InitLogging or | 93 // Which log file to use? This is initialized by InitLogging or |
102 // will be lazily initialized to the default value when it is | 94 // will be lazily initialized to the default value when it is |
103 // first needed. | 95 // first needed. |
104 #if defined(OS_WIN) | 96 #if defined(OS_WIN) |
105 typedef std::wstring PathString; | 97 typedef std::wstring PathString; |
106 #else | 98 #else |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 bool InitializeLogFileHandle() { | 308 bool InitializeLogFileHandle() { |
317 if (log_file) | 309 if (log_file) |
318 return true; | 310 return true; |
319 | 311 |
320 if (!log_file_name) { | 312 if (!log_file_name) { |
321 // Nobody has called InitLogging to specify a debug log file, so here we | 313 // Nobody has called InitLogging to specify a debug log file, so here we |
322 // initialize the log file name to a default. | 314 // initialize the log file name to a default. |
323 log_file_name = new PathString(GetDefaultLogFile()); | 315 log_file_name = new PathString(GetDefaultLogFile()); |
324 } | 316 } |
325 | 317 |
326 if (logging_destination == LOG_ONLY_TO_FILE || | 318 if ((logging_destination & LOG_TO_FILE) != 0) { |
327 logging_destination == LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) { | |
328 #if defined(OS_WIN) | 319 #if defined(OS_WIN) |
329 log_file = CreateFile(log_file_name->c_str(), GENERIC_WRITE, | 320 log_file = CreateFile(log_file_name->c_str(), GENERIC_WRITE, |
330 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | 321 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, |
331 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | 322 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
332 if (log_file == INVALID_HANDLE_VALUE || log_file == NULL) { | 323 if (log_file == INVALID_HANDLE_VALUE || log_file == NULL) { |
333 // try the current directory | 324 // try the current directory |
334 log_file = CreateFile(L".\\debug.log", GENERIC_WRITE, | 325 log_file = CreateFile(L".\\debug.log", GENERIC_WRITE, |
335 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | 326 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, |
336 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | 327 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
337 if (log_file == INVALID_HANDLE_VALUE || log_file == NULL) { | 328 if (log_file == INVALID_HANDLE_VALUE || log_file == NULL) { |
338 log_file = NULL; | 329 log_file = NULL; |
339 return false; | 330 return false; |
340 } | 331 } |
341 } | 332 } |
342 SetFilePointer(log_file, 0, 0, FILE_END); | 333 SetFilePointer(log_file, 0, 0, FILE_END); |
343 #elif defined(OS_POSIX) | 334 #elif defined(OS_POSIX) |
344 log_file = fopen(log_file_name->c_str(), "a"); | 335 log_file = fopen(log_file_name->c_str(), "a"); |
345 if (log_file == NULL) | 336 if (log_file == NULL) |
346 return false; | 337 return false; |
347 #endif | 338 #endif |
348 } | 339 } |
349 | 340 |
350 return true; | 341 return true; |
351 } | 342 } |
352 | 343 |
353 } // namespace | 344 } // namespace |
354 | 345 |
| 346 LoggingSettings::LoggingSettings() |
| 347 : logging_dest(LOG_DEFAULT), |
| 348 log_file(NULL), |
| 349 lock_log(LOCK_LOG_FILE), |
| 350 delete_old(APPEND_TO_OLD_LOG_FILE), |
| 351 dcheck_state(DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS) {} |
355 | 352 |
356 bool BaseInitLoggingImpl(const PathChar* new_log_file, | 353 bool BaseInitLoggingImpl(const LoggingSettings& settings) { |
357 LoggingDestination logging_dest, | |
358 LogLockingState lock_log, | |
359 OldFileDeletionState delete_old, | |
360 DcheckState dcheck_state) { | |
361 #if defined(OS_NACL) | 354 #if defined(OS_NACL) |
362 CHECK(logging_dest == LOG_NONE || | 355 // Can log only to the system debug log. |
363 logging_dest == LOG_ONLY_TO_SYSTEM_DEBUG_LOG); | 356 CHECK_EQ(settings.logging_dest & ~LOG_TO_SYSTEM_DEBUG_LOG, 0); |
364 #endif | 357 #endif |
365 g_dcheck_state = dcheck_state; | 358 g_dcheck_state = settings.dcheck_state; |
366 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 359 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
367 // Don't bother initializing g_vlog_info unless we use one of the | 360 // Don't bother initializing g_vlog_info unless we use one of the |
368 // vlog switches. | 361 // vlog switches. |
369 if (command_line->HasSwitch(switches::kV) || | 362 if (command_line->HasSwitch(switches::kV) || |
370 command_line->HasSwitch(switches::kVModule)) { | 363 command_line->HasSwitch(switches::kVModule)) { |
371 // NOTE: If g_vlog_info has already been initialized, it might be in use | 364 // NOTE: If g_vlog_info has already been initialized, it might be in use |
372 // by another thread. Don't delete the old VLogInfo, just create a second | 365 // by another thread. Don't delete the old VLogInfo, just create a second |
373 // one. We keep track of both to avoid memory leak warnings. | 366 // one. We keep track of both to avoid memory leak warnings. |
374 CHECK(!g_vlog_info_prev); | 367 CHECK(!g_vlog_info_prev); |
375 g_vlog_info_prev = g_vlog_info; | 368 g_vlog_info_prev = g_vlog_info; |
376 | 369 |
377 g_vlog_info = | 370 g_vlog_info = |
378 new VlogInfo(command_line->GetSwitchValueASCII(switches::kV), | 371 new VlogInfo(command_line->GetSwitchValueASCII(switches::kV), |
379 command_line->GetSwitchValueASCII(switches::kVModule), | 372 command_line->GetSwitchValueASCII(switches::kVModule), |
380 &min_log_level); | 373 &min_log_level); |
381 } | 374 } |
382 | 375 |
383 LoggingLock::Init(lock_log, new_log_file); | 376 LoggingLock::Init(settings.lock_log, settings.log_file); |
384 | 377 |
385 LoggingLock logging_lock; | 378 LoggingLock logging_lock; |
386 | 379 |
387 if (log_file) { | 380 if (log_file) { |
388 // calling InitLogging twice or after some log call has already opened the | 381 // calling InitLogging twice or after some log call has already opened the |
389 // default log file will re-initialize to the new options | 382 // default log file will re-initialize to the new options |
390 CloseFile(log_file); | 383 CloseFile(log_file); |
391 log_file = NULL; | 384 log_file = NULL; |
392 } | 385 } |
393 | 386 |
394 logging_destination = logging_dest; | 387 logging_destination = settings.logging_dest; |
395 | 388 |
396 // ignore file options if logging is disabled or only to system | 389 // ignore file options unless logging to file is set. |
397 if (logging_destination == LOG_NONE || | 390 if ((logging_destination & LOG_TO_FILE) == 0) |
398 logging_destination == LOG_ONLY_TO_SYSTEM_DEBUG_LOG) | |
399 return true; | 391 return true; |
400 | 392 |
401 if (!log_file_name) | 393 if (!log_file_name) |
402 log_file_name = new PathString(); | 394 log_file_name = new PathString(); |
403 *log_file_name = new_log_file; | 395 *log_file_name = settings.log_file; |
404 if (delete_old == DELETE_OLD_LOG_FILE) | 396 if (settings.delete_old == DELETE_OLD_LOG_FILE) |
405 DeleteFilePath(*log_file_name); | 397 DeleteFilePath(*log_file_name); |
406 | 398 |
407 return InitializeLogFileHandle(); | 399 return InitializeLogFileHandle(); |
408 } | 400 } |
409 | 401 |
410 void SetMinLogLevel(int level) { | 402 void SetMinLogLevel(int level) { |
411 min_log_level = std::min(LOG_ERROR_REPORT, level); | 403 min_log_level = std::min(LOG_ERROR_REPORT, level); |
412 } | 404 } |
413 | 405 |
414 int GetMinLogLevel() { | 406 int GetMinLogLevel() { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 // Include a stack trace on a fatal. | 563 // Include a stack trace on a fatal. |
572 base::debug::StackTrace trace; | 564 base::debug::StackTrace trace; |
573 stream_ << std::endl; // Newline to separate from log message. | 565 stream_ << std::endl; // Newline to separate from log message. |
574 trace.OutputToStream(&stream_); | 566 trace.OutputToStream(&stream_); |
575 } | 567 } |
576 #endif | 568 #endif |
577 stream_ << std::endl; | 569 stream_ << std::endl; |
578 std::string str_newline(stream_.str()); | 570 std::string str_newline(stream_.str()); |
579 | 571 |
580 // Give any log message handler first dibs on the message. | 572 // Give any log message handler first dibs on the message. |
581 if (log_message_handler && log_message_handler(severity_, file_, line_, | 573 if (log_message_handler && |
582 message_start_, str_newline)) { | 574 log_message_handler(severity_, file_, line_, |
| 575 message_start_, str_newline)) { |
583 // The handler took care of it, no further processing. | 576 // The handler took care of it, no further processing. |
584 return; | 577 return; |
585 } | 578 } |
586 | 579 |
587 if (logging_destination == LOG_ONLY_TO_SYSTEM_DEBUG_LOG || | 580 if ((logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) { |
588 logging_destination == LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) { | |
589 #if defined(OS_WIN) | 581 #if defined(OS_WIN) |
590 OutputDebugStringA(str_newline.c_str()); | 582 OutputDebugStringA(str_newline.c_str()); |
591 #elif defined(OS_ANDROID) | 583 #elif defined(OS_ANDROID) |
592 android_LogPriority priority = | 584 android_LogPriority priority = |
593 (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN; | 585 (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN; |
594 switch (severity_) { | 586 switch (severity_) { |
595 case LOG_INFO: | 587 case LOG_INFO: |
596 priority = ANDROID_LOG_INFO; | 588 priority = ANDROID_LOG_INFO; |
597 break; | 589 break; |
598 case LOG_WARNING: | 590 case LOG_WARNING: |
(...skipping 21 matching lines...) Expand all Loading... |
620 | 612 |
621 // We can have multiple threads and/or processes, so try to prevent them | 613 // We can have multiple threads and/or processes, so try to prevent them |
622 // from clobbering each other's writes. | 614 // from clobbering each other's writes. |
623 // If the client app did not call InitLogging, and the lock has not | 615 // If the client app did not call InitLogging, and the lock has not |
624 // been created do it now. We do this on demand, but if two threads try | 616 // been created do it now. We do this on demand, but if two threads try |
625 // to do this at the same time, there will be a race condition to create | 617 // to do this at the same time, there will be a race condition to create |
626 // the lock. This is why InitLogging should be called from the main | 618 // the lock. This is why InitLogging should be called from the main |
627 // thread at the beginning of execution. | 619 // thread at the beginning of execution. |
628 LoggingLock::Init(LOCK_LOG_FILE, NULL); | 620 LoggingLock::Init(LOCK_LOG_FILE, NULL); |
629 // write to log file | 621 // write to log file |
630 if (logging_destination != LOG_NONE && | 622 if ((logging_destination & LOG_TO_FILE) != 0) { |
631 logging_destination != LOG_ONLY_TO_SYSTEM_DEBUG_LOG) { | |
632 LoggingLock logging_lock; | 623 LoggingLock logging_lock; |
633 if (InitializeLogFileHandle()) { | 624 if (InitializeLogFileHandle()) { |
634 #if defined(OS_WIN) | 625 #if defined(OS_WIN) |
635 SetFilePointer(log_file, 0, 0, SEEK_END); | 626 SetFilePointer(log_file, 0, 0, SEEK_END); |
636 DWORD num_written; | 627 DWORD num_written; |
637 WriteFile(log_file, | 628 WriteFile(log_file, |
638 static_cast<const void*>(str_newline.c_str()), | 629 static_cast<const void*>(str_newline.c_str()), |
639 static_cast<DWORD>(str_newline.length()), | 630 static_cast<DWORD>(str_newline.length()), |
640 &num_written, | 631 &num_written, |
641 NULL); | 632 NULL); |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 return *log_file_name; | 860 return *log_file_name; |
870 return std::wstring(); | 861 return std::wstring(); |
871 } | 862 } |
872 #endif | 863 #endif |
873 | 864 |
874 } // namespace logging | 865 } // namespace logging |
875 | 866 |
876 std::ostream& operator<<(std::ostream& out, const wchar_t* wstr) { | 867 std::ostream& operator<<(std::ostream& out, const wchar_t* wstr) { |
877 return out << WideToUTF8(std::wstring(wstr)); | 868 return out << WideToUTF8(std::wstring(wstr)); |
878 } | 869 } |
OLD | NEW |