summaryrefslogtreecommitdiffstats
path: root/chrome/common/logging_chrome.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/common/logging_chrome.cc')
-rw-r--r--chrome/common/logging_chrome.cc179
1 files changed, 136 insertions, 43 deletions
diff --git a/chrome/common/logging_chrome.cc b/chrome/common/logging_chrome.cc
index beab5b8..196c581 100644
--- a/chrome/common/logging_chrome.cc
+++ b/chrome/common/logging_chrome.cc
@@ -32,7 +32,7 @@
#include "base/command_line.h"
#include "base/compiler_specific.h"
-#include "base/debug_util.h"
+#include "base/debug/debugger.h"
#include "base/environment.h"
#include "base/file_path.h"
#include "base/file_util.h"
@@ -64,8 +64,9 @@ static bool chrome_logging_redirected_ = false;
#if defined(OS_WIN)
// {7FE69228-633E-4f06-80C1-527FEA23E3A7}
-DEFINE_GUID(kChromeTraceProviderName,
- 0x7fe69228, 0x633e, 0x4f06, 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7);
+static const GUID kChromeTraceProviderName = {
+ 0x7fe69228, 0x633e, 0x4f06,
+ { 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } };
#endif
// Assertion handler for logging errors that occur when dialogs are
@@ -73,7 +74,7 @@ DEFINE_GUID(kChromeTraceProviderName,
// with that error in the str parameter.
MSVC_DISABLE_OPTIMIZE();
static void SilentRuntimeAssertHandler(const std::string& str) {
- DebugUtil::BreakDebugger();
+ base::debug::BreakDebugger();
}
static void SilentRuntimeReportHandler(const std::string& str) {
}
@@ -135,47 +136,106 @@ LoggingDestination DetermineLogMode(const CommandLine& command_line) {
}
#if defined(OS_CHROMEOS)
-void SetUpSymlink(const FilePath& symlink_path, const FilePath& new_log_path) {
- // We don't care if the unlink fails; we're going to continue anyway.
- if (unlink(symlink_path.value().c_str()) == -1)
- PLOG(WARNING) << "Unable to unlink " << symlink_path.value();
- if (symlink(new_log_path.value().c_str(),
- symlink_path.value().c_str()) == -1) {
- PLOG(ERROR) << "Unable to create symlink " << symlink_path.value()
- << " pointing at " << new_log_path.value();
+namespace {
+FilePath GenerateTimestampedName(const FilePath& base_path,
+ base::Time timestamp) {
+ base::Time::Exploded time_deets;
+ timestamp.LocalExplode(&time_deets);
+ std::string suffix = base::StringPrintf("_%02d%02d%02d-%02d%02d%02d",
+ time_deets.year,
+ time_deets.month,
+ time_deets.day_of_month,
+ time_deets.hour,
+ time_deets.minute,
+ time_deets.second);
+ return base_path.InsertBeforeExtension(suffix);
+}
+
+FilePath SetUpSymlinkIfNeeded(const FilePath& symlink_path, bool new_log) {
+ DCHECK(!symlink_path.empty());
+
+ // If not starting a new log, then just log through the existing
+ // symlink, but if the symlink doesn't exist, create it. If
+ // starting a new log, then delete the old symlink and make a new
+ // one to a fresh log file.
+ FilePath target_path;
+ bool symlink_exists = file_util::PathExists(symlink_path);
+ if (new_log || !symlink_exists) {
+ target_path = GenerateTimestampedName(symlink_path, base::Time::Now());
+
+ // We don't care if the unlink fails; we're going to continue anyway.
+ if (unlink(symlink_path.value().c_str()) == -1) {
+ if (symlink_exists) // only warn if we might expect it to succeed.
+ PLOG(WARNING) << "Unable to unlink " << symlink_path.value();
+ }
+ if (symlink(target_path.value().c_str(),
+ symlink_path.value().c_str()) == -1) {
+ PLOG(ERROR) << "Unable to create symlink " << symlink_path.value()
+ << " pointing at " << target_path.value();
+ }
+ } else {
+ char buf[PATH_MAX];
+ ssize_t count = readlink(symlink_path.value().c_str(), buf, arraysize(buf));
+ if (count > 0) {
+ target_path = FilePath(FilePath::StringType(buf, count));
+ } else {
+ PLOG(ERROR) << "Unable to read symlink " << symlink_path.value();
+ }
}
+ return target_path;
}
-FilePath TimestampLog(const FilePath& new_log_file, base::Time timestamp) {
- base::Time::Exploded time_deets;
- timestamp.LocalExplode(&time_deets);
- std::string suffix = StringPrintf("_%02d%02d%02d-%02d%02d%02d",
- time_deets.year,
- time_deets.month,
- time_deets.day_of_month,
- time_deets.hour,
- time_deets.minute,
- time_deets.second);
- FilePath new_log_path = new_log_file.InsertBeforeExtension(suffix);
- SetUpSymlink(new_log_file, new_log_path);
-
- return new_log_path;
+void RemoveSymlinkAndLog(const FilePath& link_path,
+ const FilePath& target_path) {
+ if (::unlink(link_path.value().c_str()) == -1)
+ PLOG(WARNING) << "Unable to unlink symlink " << link_path.value();
+ if (::unlink(target_path.value().c_str()) == -1)
+ PLOG(WARNING) << "Unable to unlink log file " << target_path.value();
}
-void RedirectChromeLogging(const FilePath& new_log_dir,
- const CommandLine& command_line,
- OldFileDeletionState delete_old_log_file) {
+} // anonymous namespace
+
+FilePath GetSessionLogFile(const CommandLine& command_line) {
+ FilePath log_dir;
+ std::string log_dir_str;
+ scoped_ptr<base::Environment> env(base::Environment::Create());
+ if (env->GetVar(env_vars::kSessionLogDir, &log_dir_str) &&
+ !log_dir_str.empty()) {
+ log_dir = FilePath(log_dir_str);
+ } else {
+ PathService::Get(chrome::DIR_USER_DATA, &log_dir);
+ FilePath login_profile =
+ command_line.GetSwitchValuePath(switches::kLoginProfile);
+ log_dir = log_dir.Append(login_profile);
+ }
+ return log_dir.Append(GetLogFileName().BaseName());
+}
+
+void RedirectChromeLogging(const CommandLine& command_line) {
DCHECK(!chrome_logging_redirected_) <<
"Attempted to redirect logging when it was already initialized.";
- FilePath log_file_name = GetLogFileName().BaseName();
- FilePath new_log_path =
- TimestampLog(new_log_dir.Append(log_file_name), base::Time::Now());
- InitLogging(new_log_path.value().c_str(),
- DetermineLogMode(command_line),
- logging::LOCK_LOG_FILE,
- delete_old_log_file);
- chrome_logging_redirected_ = true;
+
+ // Redirect logs to the session log directory, if set. Otherwise
+ // defaults to the profile dir.
+ FilePath log_path = GetSessionLogFile(command_line);
+
+ // Always force a new symlink when redirecting.
+ FilePath target_path = SetUpSymlinkIfNeeded(log_path, true);
+
+ // ChromeOS always logs through the symlink, so it shouldn't be
+ // deleted if it already exists.
+ if (!InitLogging(log_path.value().c_str(),
+ DetermineLogMode(command_line),
+ logging::LOCK_LOG_FILE,
+ logging::APPEND_TO_OLD_LOG_FILE)) {
+ LOG(ERROR) << "Unable to initialize logging to " << log_path.value();
+ RemoveSymlinkAndLog(log_path, target_path);
+ } else {
+ chrome_logging_redirected_ = true;
+ }
}
+
+
#endif
void InitChromeLogging(const CommandLine& command_line,
@@ -188,21 +248,54 @@ void InitChromeLogging(const CommandLine& command_line,
#endif
FilePath log_path = GetLogFileName();
+
#if defined(OS_CHROMEOS)
- log_path = TimestampLog(log_path, base::Time::Now());
+ // For BWSI (Incognito) logins, we want to put the logs in the user
+ // profile directory that is created for the temporary session instead
+ // of in the system log directory, for privacy reasons.
+ if (command_line.HasSwitch(switches::kGuestSession))
+ log_path = GetSessionLogFile(command_line);
+
+ // On ChromeOS we log to the symlink. We force creation of a new
+ // symlink if we've been asked to delete the old log, since that
+ // indicates the start of a new session.
+ FilePath target_path = SetUpSymlinkIfNeeded(
+ log_path, delete_old_log_file == logging::DELETE_OLD_LOG_FILE);
+
+ // Because ChromeOS manages the move to a new session by redirecting
+ // the link, it shouldn't remove the old file in the logging code,
+ // since that will remove the newly created link instead.
+ delete_old_log_file = logging::APPEND_TO_OLD_LOG_FILE;
#endif
- logging::InitLogging(log_path.value().c_str(),
- DetermineLogMode(command_line),
- logging::LOCK_LOG_FILE,
- delete_old_log_file);
+ bool success = InitLogging(log_path.value().c_str(),
+ DetermineLogMode(command_line),
+ logging::LOCK_LOG_FILE,
+ delete_old_log_file);
+
+#if defined(OS_CHROMEOS)
+ if (!success) {
+ PLOG(ERROR) << "Unable to initialize logging to " << log_path.value()
+ << " (which should be a link to " << target_path.value() << ")";
+ RemoveSymlinkAndLog(log_path, target_path);
+ return;
+ }
+#else
+ if (!success) {
+ PLOG(ERROR) << "Unable to initialize logging to " << log_path.value();
+ return;
+ }
+#endif
// Default to showing error dialogs.
if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoErrorDialogs))
logging::SetShowErrorDialogs(true);
// we want process and thread IDs because we have a lot of things running
- logging::SetLogItems(true, true, false, true);
+ logging::SetLogItems(true, // enable_process_id
+ true, // enable_thread_id
+ false, // enable_timestamp
+ true); // enable_tickcount
// We call running in unattended mode "headless", and allow
// headless mode to be configured either by the Environment