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.
7 #include "chrome/installer/util/logging_installer.h"
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"
23 // {93BCE0BF-3FAF-43b1-9E28-BEB6FAB5ECE7}
24 static const GUID kSetupTraceProvider
= { 0x93bce0bf, 0x3faf, 0x43b1,
25 { 0x9e, 0x28, 0xbe, 0xb6, 0xfa, 0xb5, 0xec, 0xe7 } };
29 // This should be true for the period between the end of
30 // InitInstallerLogging() and the beginning of EndInstallerLogging().
31 bool installer_logging_
= false;
33 TruncateResult
TruncateLogFileIfNeeded(const base::FilePath
& log_file
) {
34 TruncateResult result
= LOGFILE_UNTOUCHED
;
37 if (base::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
));
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 base::Move will attempt to replace existing files.
51 if (base::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
,
57 kTruncatedInstallerLogFileSize
);
59 (bytes_read
== file_util::WriteFile(log_file
,
62 base::PathExists(log_file
))) {
63 result
= LOGFILE_TRUNCATED
;
66 } else if (base::DeleteFile(log_file
, false)) {
67 // Couldn't get sufficient access to the log file, optimistically try to
69 result
= LOGFILE_DELETED
;
77 void InitInstallerLogging(const installer::MasterPreferences
& prefs
) {
78 if (installer_logging_
)
81 installer_logging_
= true;
84 if (prefs
.GetBool(installer::master_preferences::kDisableLogging
,
89 base::FilePath
log_file_path(GetLogFilePath(prefs
));
90 TruncateLogFileIfNeeded(log_file_path
);
92 logging::LoggingSettings settings
;
93 settings
.logging_dest
= logging::LOG_TO_FILE
;
94 settings
.log_file
= log_file_path
.value().c_str();
95 logging::InitLogging(settings
);
97 if (prefs
.GetBool(installer::master_preferences::kVerboseLogging
,
99 logging::SetMinLogLevel(logging::LOG_VERBOSE
);
101 logging::SetMinLogLevel(logging::LOG_ERROR
);
104 // Enable ETW logging.
105 logging::LogEventProvider::Initialize(kSetupTraceProvider
);
108 void EndInstallerLogging() {
109 logging::CloseLogFile();
111 installer_logging_
= false;
114 base::FilePath
GetLogFilePath(const installer::MasterPreferences
& prefs
) {
116 prefs
.GetString(installer::master_preferences::kLogFile
, &path
);
118 return base::FilePath(base::UTF8ToWide(path
));
120 static const base::FilePath::CharType kLogFilename
[] =
121 FILE_PATH_LITERAL("chrome_installer.log");
123 // Fallback to current directory if getting the temp directory fails.
124 base::FilePath tmp_path
;
125 ignore_result(PathService::Get(base::DIR_TEMP
, &tmp_path
));
126 return tmp_path
.Append(kLogFilename
);
129 } // namespace installer