logging_chrome.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Need to include this before most other files because it defines 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC_MESSAGE_LOG_ENABLED. We need to use it to define 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC_MESSAGE_MACROS_LOG_ENABLED so render_messages.h will generate the 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ViewMsgLog et al. functions. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On Windows, the about:ipc dialog shows IPCs; on POSIX, we hook up a 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// logger in this file. (We implement about:ipc on Mac but implement 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the loggers here anyway). We need to do this real early to be sure 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC_MESSAGE_MACROS_LOG_ENABLED doesn't get undefined. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && defined(IPC_MESSAGE_LOG_ENABLED) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_MESSAGE_MACROS_LOG_ENABLED 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_ipc_logging.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \ 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RegisterIPCLogger(msg_id, logger) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/all_messages.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fstream> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/logging_chrome.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/debugger.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stringprintf.h" 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/time.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/dump_without_crashing.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/env_vars.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_logging.h" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <initguid.h> 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging_win.h" 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When true, this means that error dialogs should not be shown. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool dialogs_are_suppressed_ = false; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This should be true for exactly the period between the end of 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InitChromeLogging() and the beginning of CleanupChromeLogging(). 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool chrome_logging_initialized_ = false; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Set if we called InitChromeLogging() but failed to initialize. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool chrome_logging_failed_ = false; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This should be true for exactly the period between the end of 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InitChromeLogging() and the beginning of CleanupChromeLogging(). 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool chrome_logging_redirected_ = false; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {7FE69228-633E-4f06-80C1-527FEA23E3A7} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GUID kChromeTraceProviderName = { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x7fe69228, 0x633e, 0x4f06, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } }; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertion handler for logging errors that occur when dialogs are 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// silenced. To record a new error, pass the log string associated 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with that error in the str parameter. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MSVC_DISABLE_OPTIMIZE(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SilentRuntimeAssertHandler(const std::string& str) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::BreakDebugger(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SilentRuntimeReportHandler(const std::string& str) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handler to silently dump the current process when there is an assert in 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// chrome. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DumpProcessAssertHandler(const std::string& str) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) logging::DumpWithoutCrashing(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_WIN 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MSVC_ENABLE_OPTIMIZE(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Suppresses error/assertion dialogs and enables the logging of 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// those errors into silenced_errors_. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SuppressDialogs() { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dialogs_are_suppressed_) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetLogAssertHandler(SilentRuntimeAssertHandler); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetLogReportHandler(SilentRuntimeReportHandler); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UINT new_flags = SEM_FAILCRITICALERRORS | 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SEM_NOGPFAULTERRORBOX | 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SEM_NOOPENFILEERRORBOX; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Preserve existing error mode, as discussed at http://t/dmea 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UINT existing_flags = SetErrorMode(new_flags); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetErrorMode(existing_flags | new_flags); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialogs_are_suppressed_ = true; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace logging { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoggingDestination DetermineLogMode(const CommandLine& command_line) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only use OutputDebugString in debug mode 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NDEBUG 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enable_logging = false; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *kInvertLoggingSwitch = switches::kEnableLogging; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const logging::LoggingDestination kDefaultLoggingMode = 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::LOG_ONLY_TO_FILE; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enable_logging = true; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *kInvertLoggingSwitch = switches::kDisableLogging; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const logging::LoggingDestination kDefaultLoggingMode = 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(kInvertLoggingSwitch)) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enable_logging = !enable_logging; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::LoggingDestination log_mode; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enable_logging) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let --enable-logging=stderr force only stderr, particularly useful for 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // non-debug builds where otherwise you can't get logs to stderr at all. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.GetSwitchValueASCII(switches::kEnableLogging) == "stderr") 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_mode = logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_mode = kDefaultLoggingMode; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_mode = logging::LOG_NONE; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return log_mode; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath SetUpSymlinkIfNeeded(const base::FilePath& symlink_path, 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool new_log) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!symlink_path.empty()); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If not starting a new log, then just log through the existing 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // symlink, but if the symlink doesn't exist, create it. If 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // starting a new log, then delete the old symlink and make a new 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // one to a fresh log file. 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath target_path; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool symlink_exists = file_util::PathExists(symlink_path); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_log || !symlink_exists) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_path = GenerateTimestampedName(symlink_path, base::Time::Now()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't care if the unlink fails; we're going to continue anyway. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::unlink(symlink_path.value().c_str()) == -1) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symlink_exists) // only warn if we might expect it to succeed. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(WARNING) << "Unable to unlink " << symlink_path.value(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_util::CreateSymbolicLink(target_path, symlink_path)) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(ERROR) << "Unable to create symlink " << symlink_path.value() 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " pointing at " << target_path.value(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_util::ReadSymbolicLink(symlink_path, &target_path)) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(ERROR) << "Unable to read symlink " << symlink_path.value(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return target_path; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RemoveSymlinkAndLog(const base::FilePath& link_path, 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& target_path) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::unlink(link_path.value().c_str()) == -1) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(WARNING) << "Unable to unlink symlink " << link_path.value(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::unlink(target_path.value().c_str()) == -1) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(WARNING) << "Unable to unlink log file " << target_path.value(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetSessionLogFile(const CommandLine& command_line) { 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath log_dir; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string log_dir_str; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Environment> env(base::Environment::Create()); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (env->GetVar(env_vars::kSessionLogDir, &log_dir_str) && 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !log_dir_str.empty()) { 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) log_dir = base::FilePath(log_dir_str); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathService::Get(chrome::DIR_USER_DATA, &log_dir); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath login_profile = 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.GetSwitchValuePath(switches::kLoginProfile); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_dir = log_dir.Append(login_profile); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return log_dir.Append(GetLogFileName().BaseName()); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RedirectChromeLogging(const CommandLine& command_line) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!chrome_logging_redirected_) << 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Attempted to redirect logging when it was already initialized."; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Redirect logs to the session log directory, if set. Otherwise 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // defaults to the profile dir. 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath log_path = GetSessionLogFile(command_line); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creating symlink causes us to do blocking IO on UI thread. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Temporarily allow it until we fix http://crbug.com/61143 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always force a new symlink when redirecting. 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath target_path = SetUpSymlinkIfNeeded(log_path, true); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::DcheckState dcheck_state = 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(switches::kEnableDCHECK) ? 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS : 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ChromeOS always logs through the symlink, so it shouldn't be 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deleted if it already exists. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!InitLogging(log_path.value().c_str(), 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetermineLogMode(command_line), 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::LOCK_LOG_FILE, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::APPEND_TO_OLD_LOG_FILE, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dcheck_state)) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Unable to initialize logging to " << log_path.value(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveSymlinkAndLog(log_path, target_path); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_redirected_ = true; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_CHROMEOS 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitChromeLogging(const CommandLine& command_line, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OldFileDeletionState delete_old_log_file) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!chrome_logging_initialized_) << 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Attempted to initialize logging when it was already initialized."; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoggingDestination logging_dest = DetermineLogMode(command_line); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogLockingState log_locking_state = LOCK_LOG_FILE; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath log_path; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath target_path; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't resolve the log path unless we need to. Otherwise we leave an open 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ALPC handle after sandbox lockdown on Windows. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (logging_dest == LOG_ONLY_TO_FILE || 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging_dest == LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_path = GetLogFileName(); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For BWSI (Incognito) logins, we want to put the logs in the user 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // profile directory that is created for the temporary session instead 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of in the system log directory, for privacy reasons. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kGuestSession)) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_path = GetSessionLogFile(command_line); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On ChromeOS we log to the symlink. We force creation of a new 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // symlink if we've been asked to delete the old log, since that 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // indicates the start of a new session. 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_path = SetUpSymlinkIfNeeded( 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_path, delete_old_log_file == logging::DELETE_OLD_LOG_FILE); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because ChromeOS manages the move to a new session by redirecting 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the link, it shouldn't remove the old file in the logging code, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since that will remove the newly created link instead. 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete_old_log_file = logging::APPEND_TO_OLD_LOG_FILE; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_locking_state = DONT_LOCK_LOG_FILE; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::DcheckState dcheck_state = 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(switches::kEnableDCHECK) ? 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS : 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = InitLogging(log_path.value().c_str(), 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging_dest, 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_locking_state, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete_old_log_file, 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dcheck_state); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(ERROR) << "Unable to initialize logging to " << log_path.value() 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " (which should be a link to " << target_path.value() << ")"; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveSymlinkAndLog(log_path, target_path); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_failed_ = true; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(ERROR) << "Unable to initialize logging to " << log_path.value(); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_failed_ = true; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Default to showing error dialogs. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoErrorDialogs)) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetShowErrorDialogs(true); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we want process and thread IDs because we have a lot of things running 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetLogItems(true, // enable_process_id 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // enable_thread_id 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // enable_timestamp 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false); // enable_tickcount 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We call running in unattended mode "headless", and allow 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // headless mode to be configured either by the Environment 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Variable or by the Command Line Switch. This is for 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // automated test purposes. 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Environment> env(base::Environment::Create()); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (env->HasVar(env_vars::kHeadless) || 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(switches::kNoErrorDialogs)) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SuppressDialogs(); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use a minimum log level if the command line asks for one, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // otherwise leave it at the default level (INFO). 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kLoggingLevel)) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string log_level = command_line.GetSwitchValueASCII( 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kLoggingLevel); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level = 0; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::StringToInt(log_level, &level) && 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level >= 0 && level < LOG_NUM_SEVERITIES) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetMinLogLevel(level); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "Bad log level: " << log_level; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enable trace control and transport through event tracing for Windows. 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::LogEventProvider::Initialize(kChromeTraceProviderName); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NDEBUG 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kSilentDumpOnDCHECK) && 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(switches::kEnableDCHECK)) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetLogReportHandler(DumpProcessAssertHandler); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NDEBUG 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_initialized_ = true; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a no-op, but we'll keep it around in case 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we need to do more cleanup in the future. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CleanupChromeLogging() { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (chrome_logging_failed_) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // We failed to initiailize logging, no cleanup. 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(chrome_logging_initialized_) << 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Attempted to clean up logging when it wasn't initialized."; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseLogFile(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_initialized_ = false; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_redirected_ = false; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetLogFileName() { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string filename; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Environment> env(base::Environment::Create()); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (env->GetVar(env_vars::kLogFileName, &filename) && !filename.empty()) { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath(UTF8ToWide(filename)); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath(filename); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath log_filename(FILE_PATH_LITERAL("chrome_debug.log")); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath log_path; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PathService::Get(chrome::DIR_LOGS, &log_path)) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_path = log_path.Append(log_filename); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return log_path; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // error with path service, just use some default file somewhere 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return log_filename; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DialogsAreSuppressed() { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dialogs_are_suppressed_; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t GetFatalAssertions(AssertionList* assertions) { 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In this function, we don't assume that assertions is non-null, so 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that if you just want an assertion count, you can pass in NULL. 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (assertions) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertions->clear(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t assertion_count = 0; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::ifstream log_file; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_file.open(GetLogFileName().value().c_str()); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!log_file.is_open()) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string utf8_line; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring wide_line; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!log_file.eof()) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getline(log_file, utf8_line); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (utf8_line.find(":FATAL:") != std::string::npos) { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wide_line = UTF8ToWide(utf8_line); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (assertions) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertions->push_back(wide_line); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++assertion_count; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_file.close(); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return assertion_count; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GenerateTimestampedName(const base::FilePath& base_path, 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time timestamp) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Exploded time_deets; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timestamp.LocalExplode(&time_deets); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string suffix = base::StringPrintf("_%02d%02d%02d-%02d%02d%02d", 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.year, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.month, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.day_of_month, 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.hour, 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.minute, 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.second); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_path.InsertBeforeExtensionASCII(suffix); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace logging 451