logging_installer.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <windows.h> 6 7#include "chrome/installer/util/logging_installer.h" 8 9#include "base/command_line.h" 10#include "base/file_util.h" 11#include "base/files/file_path.h" 12#include "base/logging.h" 13#include "base/logging_win.h" 14#include "base/path_service.h" 15#include "base/platform_file.h" 16#include "base/strings/string_util.h" 17#include "base/strings/utf_string_conversions.h" 18#include "base/win/scoped_handle.h" 19#include "chrome/installer/util/master_preferences.h" 20#include "chrome/installer/util/master_preferences_constants.h" 21#include "chrome/installer/util/util_constants.h" 22 23// {93BCE0BF-3FAF-43b1-9E28-BEB6FAB5ECE7} 24static const GUID kSetupTraceProvider = { 0x93bce0bf, 0x3faf, 0x43b1, 25 { 0x9e, 0x28, 0xbe, 0xb6, 0xfa, 0xb5, 0xec, 0xe7 } }; 26 27namespace installer { 28 29// This should be true for the period between the end of 30// InitInstallerLogging() and the beginning of EndInstallerLogging(). 31bool installer_logging_ = false; 32 33TruncateResult TruncateLogFileIfNeeded(const base::FilePath& log_file) { 34 TruncateResult result = LOGFILE_UNTOUCHED; 35 36 int64 log_size = 0; 37 if (file_util::GetFileSize(log_file, &log_size) && 38 log_size > kMaxInstallerLogFileSize) { 39 // Cause the old log file to be deleted when we are done with it. 40 const int file_flags = base::PLATFORM_FILE_OPEN | 41 base::PLATFORM_FILE_READ | 42 base::PLATFORM_FILE_SHARE_DELETE | 43 base::PLATFORM_FILE_DELETE_ON_CLOSE; 44 base::win::ScopedHandle old_log_file( 45 base::CreatePlatformFile(log_file, file_flags, NULL, NULL)); 46 47 if (old_log_file.IsValid()) { 48 result = LOGFILE_DELETED; 49 base::FilePath tmp_log(log_file.value() + FILE_PATH_LITERAL(".tmp")); 50 // Note that file_util::Move will attempt to replace existing files. 51 if (file_util::Move(log_file, tmp_log)) { 52 int64 offset = log_size - kTruncatedInstallerLogFileSize; 53 std::string old_log_data(kTruncatedInstallerLogFileSize, 0); 54 int bytes_read = base::ReadPlatformFile(old_log_file, 55 offset, 56 &old_log_data[0], 57 kTruncatedInstallerLogFileSize); 58 if (bytes_read > 0 && 59 (bytes_read == file_util::WriteFile(log_file, 60 &old_log_data[0], 61 bytes_read) || 62 file_util::PathExists(log_file))) { 63 result = LOGFILE_TRUNCATED; 64 } 65 } 66 } else if (file_util::Delete(log_file, false)) { 67 // Couldn't get sufficient access to the log file, optimistically try to 68 // delete it. 69 result = LOGFILE_DELETED; 70 } 71 } 72 73 return result; 74} 75 76 77void InitInstallerLogging(const installer::MasterPreferences& prefs) { 78 if (installer_logging_) 79 return; 80 81 installer_logging_ = true; 82 83 bool value = false; 84 if (prefs.GetBool(installer::master_preferences::kDisableLogging, 85 &value) && value) { 86 return; 87 } 88 89 base::FilePath log_file_path(GetLogFilePath(prefs)); 90 TruncateLogFileIfNeeded(log_file_path); 91 92 logging::InitLogging( 93 log_file_path.value().c_str(), 94 logging::LOG_ONLY_TO_FILE, 95 logging::LOCK_LOG_FILE, 96 logging::APPEND_TO_OLD_LOG_FILE, 97 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); 98 99 if (prefs.GetBool(installer::master_preferences::kVerboseLogging, 100 &value) && value) { 101 logging::SetMinLogLevel(logging::LOG_VERBOSE); 102 } else { 103 logging::SetMinLogLevel(logging::LOG_ERROR); 104 } 105 106 // Enable ETW logging. 107 logging::LogEventProvider::Initialize(kSetupTraceProvider); 108} 109 110void EndInstallerLogging() { 111 logging::CloseLogFile(); 112 113 installer_logging_ = false; 114} 115 116base::FilePath GetLogFilePath(const installer::MasterPreferences& prefs) { 117 std::string path; 118 prefs.GetString(installer::master_preferences::kLogFile, &path); 119 if (!path.empty()) { 120 return base::FilePath(UTF8ToWide(path)); 121 } 122 123 std::wstring log_filename = prefs.install_chrome_frame() ? 124 L"chrome_frame_installer.log" : L"chrome_installer.log"; 125 126 base::FilePath log_path; 127 if (PathService::Get(base::DIR_TEMP, &log_path)) { 128 log_path = log_path.Append(log_filename); 129 return log_path; 130 } else { 131 return base::FilePath(log_filename); 132 } 133} 134 135} // namespace installer 136