- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / installer / util / logging_installer.cc
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}
24 static const GUID kSetupTraceProvider = { 0x93bce0bf, 0x3faf, 0x43b1,
25     { 0x9e, 0x28, 0xbe, 0xb6, 0xfa, 0xb5, 0xec, 0xe7 } };
26
27 namespace installer {
28
29 // This should be true for the period between the end of
30 // InitInstallerLogging() and the beginning of EndInstallerLogging().
31 bool installer_logging_ = false;
32
33 TruncateResult 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 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,
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              base::PathExists(log_file))) {
63           result = LOGFILE_TRUNCATED;
64         }
65       }
66     } else if (base::DeleteFile(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
77 void 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::LoggingSettings settings;
93   settings.logging_dest = logging::LOG_TO_FILE;
94   settings.log_file = log_file_path.value().c_str();
95   logging::InitLogging(settings);
96
97   if (prefs.GetBool(installer::master_preferences::kVerboseLogging,
98                     &value) && value) {
99     logging::SetMinLogLevel(logging::LOG_VERBOSE);
100   } else {
101     logging::SetMinLogLevel(logging::LOG_ERROR);
102   }
103
104   // Enable ETW logging.
105   logging::LogEventProvider::Initialize(kSetupTraceProvider);
106 }
107
108 void EndInstallerLogging() {
109   logging::CloseLogFile();
110
111   installer_logging_ = false;
112 }
113
114 base::FilePath GetLogFilePath(const installer::MasterPreferences& prefs) {
115   std::string path;
116   prefs.GetString(installer::master_preferences::kLogFile, &path);
117   if (!path.empty()) {
118     return base::FilePath(UTF8ToWide(path));
119   }
120
121   std::wstring log_filename = prefs.install_chrome_frame() ?
122       L"chrome_frame_installer.log" : L"chrome_installer.log";
123
124   base::FilePath log_path;
125   if (PathService::Get(base::DIR_TEMP, &log_path)) {
126     log_path = log_path.Append(log_filename);
127     return log_path;
128   } else {
129     return base::FilePath(log_filename);
130   }
131 }
132
133 }  // namespace installer