| OLD | NEW |
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "system_log_uploader.h" | |
| 6 | |
| 7 #include <utility> | 5 #include <utility> |
| 8 | 6 |
| 9 #include "base/bind.h" | 7 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 11 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 12 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| 11 #include "base/memory/ptr_util.h" |
| 13 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 15 #include "base/task_runner_util.h" | 14 #include "base/task_runner_util.h" |
| 16 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
| 17 #include "chrome/browser/chromeos/policy/upload_job_impl.h" | 16 #include "chrome/browser/chromeos/policy/upload_job_impl.h" |
| 18 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" | 17 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" |
| 19 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h
" | 18 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h
" |
| 20 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
| 21 #include "components/feedback/anonymizer_tool.h" | 20 #include "components/feedback/anonymizer_tool.h" |
| 22 #include "components/policy/core/browser/browser_policy_connector.h" | 21 #include "components/policy/core/browser/browser_policy_connector.h" |
| 23 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
| 24 #include "net/http/http_request_headers.h" | 23 #include "net/http/http_request_headers.h" |
| 24 #include "system_log_uploader.h" |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 // The maximum number of successive retries. | 27 // The maximum number of successive retries. |
| 28 const int kMaxNumRetries = 1; | 28 const int kMaxNumRetries = 1; |
| 29 | 29 |
| 30 // String constant defining the url tail we upload system logs to. | 30 // String constant defining the url tail we upload system logs to. |
| 31 const char* kSystemLogUploadUrlTail = "/upload"; | 31 const char* kSystemLogUploadUrlTail = "/upload"; |
| 32 | 32 |
| 33 // The file names of the system logs to upload. | 33 // The file names of the system logs to upload. |
| 34 // Note: do not add anything to this list without checking for PII in the file. | 34 // Note: do not add anything to this list without checking for PII in the file. |
| 35 const char* const kSystemLogFileNames[] = { | 35 const char* const kSystemLogFileNames[] = { |
| 36 "/var/log/bios_info.txt", "/var/log/chrome/chrome", | 36 "/var/log/bios_info.txt", "/var/log/chrome/chrome", |
| 37 "/var/log/eventlog.txt", "/var/log/platform_info.txt", | 37 "/var/log/eventlog.txt", "/var/log/platform_info.txt", |
| 38 "/var/log/messages", "/var/log/messages.1", | 38 "/var/log/messages", "/var/log/messages.1", |
| 39 "/var/log/net.log", "/var/log/net.1.log", | 39 "/var/log/net.log", "/var/log/net.1.log", |
| 40 "/var/log/ui/ui.LATEST", "/var/log/update_engine.log"}; | 40 "/var/log/ui/ui.LATEST", "/var/log/update_engine.log"}; |
| 41 | 41 |
| 42 // Reads the system log files as binary files, anonymizes data, stores the files | 42 // Reads the system log files as binary files, anonymizes data, stores the files |
| 43 // as pairs (file name, data) and returns. Called on blocking thread. | 43 // as pairs (file name, data) and returns. Called on blocking thread. |
| 44 scoped_ptr<policy::SystemLogUploader::SystemLogs> ReadFiles() { | 44 std::unique_ptr<policy::SystemLogUploader::SystemLogs> ReadFiles() { |
| 45 scoped_ptr<policy::SystemLogUploader::SystemLogs> system_logs( | 45 std::unique_ptr<policy::SystemLogUploader::SystemLogs> system_logs( |
| 46 new policy::SystemLogUploader::SystemLogs()); | 46 new policy::SystemLogUploader::SystemLogs()); |
| 47 feedback::AnonymizerTool anonymizer; | 47 feedback::AnonymizerTool anonymizer; |
| 48 for (auto const file_path : kSystemLogFileNames) { | 48 for (auto const file_path : kSystemLogFileNames) { |
| 49 if (!base::PathExists(base::FilePath(file_path))) | 49 if (!base::PathExists(base::FilePath(file_path))) |
| 50 continue; | 50 continue; |
| 51 std::string data = std::string(); | 51 std::string data = std::string(); |
| 52 if (!base::ReadFileToString(base::FilePath(file_path), &data)) { | 52 if (!base::ReadFileToString(base::FilePath(file_path), &data)) { |
| 53 LOG(ERROR) << "Failed to read the system log file from the disk " | 53 LOG(ERROR) << "Failed to read the system log file from the disk " |
| 54 << file_path << std::endl; | 54 << file_path << std::endl; |
| 55 } | 55 } |
| 56 system_logs->push_back(std::make_pair( | 56 system_logs->push_back(std::make_pair( |
| 57 file_path, | 57 file_path, |
| 58 policy::SystemLogUploader::RemoveSensitiveData(&anonymizer, data))); | 58 policy::SystemLogUploader::RemoveSensitiveData(&anonymizer, data))); |
| 59 } | 59 } |
| 60 return system_logs; | 60 return system_logs; |
| 61 } | 61 } |
| 62 | 62 |
| 63 // An implementation of the |SystemLogUploader::Delegate|, that is used to | 63 // An implementation of the |SystemLogUploader::Delegate|, that is used to |
| 64 // create an upload job and load system logs from the disk. | 64 // create an upload job and load system logs from the disk. |
| 65 class SystemLogDelegate : public policy::SystemLogUploader::Delegate { | 65 class SystemLogDelegate : public policy::SystemLogUploader::Delegate { |
| 66 public: | 66 public: |
| 67 SystemLogDelegate(); | 67 SystemLogDelegate(); |
| 68 ~SystemLogDelegate() override; | 68 ~SystemLogDelegate() override; |
| 69 | 69 |
| 70 // SystemLogUploader::Delegate: | 70 // SystemLogUploader::Delegate: |
| 71 void LoadSystemLogs(const LogUploadCallback& upload_callback) override; | 71 void LoadSystemLogs(const LogUploadCallback& upload_callback) override; |
| 72 | 72 |
| 73 scoped_ptr<policy::UploadJob> CreateUploadJob( | 73 std::unique_ptr<policy::UploadJob> CreateUploadJob( |
| 74 const GURL& upload_url, | 74 const GURL& upload_url, |
| 75 policy::UploadJob::Delegate* delegate) override; | 75 policy::UploadJob::Delegate* delegate) override; |
| 76 | 76 |
| 77 private: | 77 private: |
| 78 DISALLOW_COPY_AND_ASSIGN(SystemLogDelegate); | 78 DISALLOW_COPY_AND_ASSIGN(SystemLogDelegate); |
| 79 }; | 79 }; |
| 80 | 80 |
| 81 SystemLogDelegate::SystemLogDelegate() {} | 81 SystemLogDelegate::SystemLogDelegate() {} |
| 82 | 82 |
| 83 SystemLogDelegate::~SystemLogDelegate() {} | 83 SystemLogDelegate::~SystemLogDelegate() {} |
| 84 | 84 |
| 85 void SystemLogDelegate::LoadSystemLogs( | 85 void SystemLogDelegate::LoadSystemLogs( |
| 86 const LogUploadCallback& upload_callback) { | 86 const LogUploadCallback& upload_callback) { |
| 87 // Run ReadFiles() in the thread that interacts with the file system and | 87 // Run ReadFiles() in the thread that interacts with the file system and |
| 88 // return system logs to |upload_callback| on the current thread. | 88 // return system logs to |upload_callback| on the current thread. |
| 89 base::PostTaskAndReplyWithResult(content::BrowserThread::GetBlockingPool(), | 89 base::PostTaskAndReplyWithResult(content::BrowserThread::GetBlockingPool(), |
| 90 FROM_HERE, base::Bind(&ReadFiles), | 90 FROM_HERE, base::Bind(&ReadFiles), |
| 91 upload_callback); | 91 upload_callback); |
| 92 } | 92 } |
| 93 | 93 |
| 94 scoped_ptr<policy::UploadJob> SystemLogDelegate::CreateUploadJob( | 94 std::unique_ptr<policy::UploadJob> SystemLogDelegate::CreateUploadJob( |
| 95 const GURL& upload_url, | 95 const GURL& upload_url, |
| 96 policy::UploadJob::Delegate* delegate) { | 96 policy::UploadJob::Delegate* delegate) { |
| 97 chromeos::DeviceOAuth2TokenService* device_oauth2_token_service = | 97 chromeos::DeviceOAuth2TokenService* device_oauth2_token_service = |
| 98 chromeos::DeviceOAuth2TokenServiceFactory::Get(); | 98 chromeos::DeviceOAuth2TokenServiceFactory::Get(); |
| 99 | 99 |
| 100 scoped_refptr<net::URLRequestContextGetter> system_request_context = | 100 scoped_refptr<net::URLRequestContextGetter> system_request_context = |
| 101 g_browser_process->system_request_context(); | 101 g_browser_process->system_request_context(); |
| 102 std::string robot_account_id = | 102 std::string robot_account_id = |
| 103 device_oauth2_token_service->GetRobotAccountId(); | 103 device_oauth2_token_service->GetRobotAccountId(); |
| 104 return scoped_ptr<policy::UploadJob>(new policy::UploadJobImpl( | 104 return std::unique_ptr<policy::UploadJob>(new policy::UploadJobImpl( |
| 105 upload_url, robot_account_id, device_oauth2_token_service, | 105 upload_url, robot_account_id, device_oauth2_token_service, |
| 106 system_request_context, delegate, | 106 system_request_context, delegate, |
| 107 make_scoped_ptr(new policy::UploadJobImpl::RandomMimeBoundaryGenerator))); | 107 base::WrapUnique( |
| 108 new policy::UploadJobImpl::RandomMimeBoundaryGenerator))); |
| 108 } | 109 } |
| 109 | 110 |
| 110 // Returns the system log upload frequency. | 111 // Returns the system log upload frequency. |
| 111 base::TimeDelta GetUploadFrequency() { | 112 base::TimeDelta GetUploadFrequency() { |
| 112 base::TimeDelta upload_frequency(base::TimeDelta::FromMilliseconds( | 113 base::TimeDelta upload_frequency(base::TimeDelta::FromMilliseconds( |
| 113 policy::SystemLogUploader::kDefaultUploadDelayMs)); | 114 policy::SystemLogUploader::kDefaultUploadDelayMs)); |
| 114 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 115 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 115 switches::kSystemLogUploadFrequency)) { | 116 switches::kSystemLogUploadFrequency)) { |
| 116 std::string string_value = | 117 std::string string_value = |
| 117 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 118 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| (...skipping 30 matching lines...) Expand all Loading... |
| 148 // String constant signalling that the data segment contains log files. | 149 // String constant signalling that the data segment contains log files. |
| 149 const char* const SystemLogUploader::kFileTypeLogFile = "log_file"; | 150 const char* const SystemLogUploader::kFileTypeLogFile = "log_file"; |
| 150 | 151 |
| 151 // String constant signalling that the segment contains a plain text. | 152 // String constant signalling that the segment contains a plain text. |
| 152 const char* const SystemLogUploader::kContentTypePlainText = "text/plain"; | 153 const char* const SystemLogUploader::kContentTypePlainText = "text/plain"; |
| 153 | 154 |
| 154 // Template string constant for populating the name field. | 155 // Template string constant for populating the name field. |
| 155 const char* const SystemLogUploader::kNameFieldTemplate = "file%d"; | 156 const char* const SystemLogUploader::kNameFieldTemplate = "file%d"; |
| 156 | 157 |
| 157 SystemLogUploader::SystemLogUploader( | 158 SystemLogUploader::SystemLogUploader( |
| 158 scoped_ptr<Delegate> syslog_delegate, | 159 std::unique_ptr<Delegate> syslog_delegate, |
| 159 const scoped_refptr<base::SequencedTaskRunner>& task_runner) | 160 const scoped_refptr<base::SequencedTaskRunner>& task_runner) |
| 160 : retry_count_(0), | 161 : retry_count_(0), |
| 161 upload_frequency_(GetUploadFrequency()), | 162 upload_frequency_(GetUploadFrequency()), |
| 162 task_runner_(task_runner), | 163 task_runner_(task_runner), |
| 163 syslog_delegate_(std::move(syslog_delegate)), | 164 syslog_delegate_(std::move(syslog_delegate)), |
| 164 upload_enabled_(false), | 165 upload_enabled_(false), |
| 165 weak_factory_(this) { | 166 weak_factory_(this) { |
| 166 if (!syslog_delegate_) | 167 if (!syslog_delegate_) |
| 167 syslog_delegate_.reset(new SystemLogDelegate()); | 168 syslog_delegate_.reset(new SystemLogDelegate()); |
| 168 DCHECK(syslog_delegate_); | 169 DCHECK(syslog_delegate_); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 return; | 230 return; |
| 230 } | 231 } |
| 231 | 232 |
| 232 // CrosSettings are trusted - we want to use the last trusted values, by | 233 // CrosSettings are trusted - we want to use the last trusted values, by |
| 233 // default do not upload system logs. | 234 // default do not upload system logs. |
| 234 if (!settings->GetBoolean(chromeos::kSystemLogUploadEnabled, | 235 if (!settings->GetBoolean(chromeos::kSystemLogUploadEnabled, |
| 235 &upload_enabled_)) | 236 &upload_enabled_)) |
| 236 upload_enabled_ = false; | 237 upload_enabled_ = false; |
| 237 } | 238 } |
| 238 | 239 |
| 239 void SystemLogUploader::UploadSystemLogs(scoped_ptr<SystemLogs> system_logs) { | 240 void SystemLogUploader::UploadSystemLogs( |
| 241 std::unique_ptr<SystemLogs> system_logs) { |
| 240 // Must be called on the main thread. | 242 // Must be called on the main thread. |
| 241 DCHECK(thread_checker_.CalledOnValidThread()); | 243 DCHECK(thread_checker_.CalledOnValidThread()); |
| 242 DCHECK(!upload_job_); | 244 DCHECK(!upload_job_); |
| 243 | 245 |
| 244 GURL upload_url(GetUploadUrl()); | 246 GURL upload_url(GetUploadUrl()); |
| 245 DCHECK(upload_url.is_valid()); | 247 DCHECK(upload_url.is_valid()); |
| 246 upload_job_ = syslog_delegate_->CreateUploadJob(upload_url, this); | 248 upload_job_ = syslog_delegate_->CreateUploadJob(upload_url, this); |
| 247 | 249 |
| 248 // Start a system log upload. | 250 // Start a system log upload. |
| 249 int file_number = 1; | 251 int file_number = 1; |
| 250 for (const auto& syslog_entry : *system_logs) { | 252 for (const auto& syslog_entry : *system_logs) { |
| 251 std::map<std::string, std::string> header_fields; | 253 std::map<std::string, std::string> header_fields; |
| 252 scoped_ptr<std::string> data = | 254 std::unique_ptr<std::string> data = |
| 253 make_scoped_ptr(new std::string(syslog_entry.second)); | 255 base::WrapUnique(new std::string(syslog_entry.second)); |
| 254 header_fields.insert(std::make_pair(kFileTypeHeaderName, kFileTypeLogFile)); | 256 header_fields.insert(std::make_pair(kFileTypeHeaderName, kFileTypeLogFile)); |
| 255 header_fields.insert(std::make_pair(net::HttpRequestHeaders::kContentType, | 257 header_fields.insert(std::make_pair(net::HttpRequestHeaders::kContentType, |
| 256 kContentTypePlainText)); | 258 kContentTypePlainText)); |
| 257 upload_job_->AddDataSegment( | 259 upload_job_->AddDataSegment( |
| 258 base::StringPrintf(kNameFieldTemplate, file_number), syslog_entry.first, | 260 base::StringPrintf(kNameFieldTemplate, file_number), syslog_entry.first, |
| 259 header_fields, std::move(data)); | 261 header_fields, std::move(data)); |
| 260 ++file_number; | 262 ++file_number; |
| 261 } | 263 } |
| 262 upload_job_->Start(); | 264 upload_job_->Start(); |
| 263 } | 265 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 284 base::TimeDelta()); | 286 base::TimeDelta()); |
| 285 // Ensure that we never have more than one pending delayed task. | 287 // Ensure that we never have more than one pending delayed task. |
| 286 weak_factory_.InvalidateWeakPtrs(); | 288 weak_factory_.InvalidateWeakPtrs(); |
| 287 task_runner_->PostDelayedTask(FROM_HERE, | 289 task_runner_->PostDelayedTask(FROM_HERE, |
| 288 base::Bind(&SystemLogUploader::StartLogUpload, | 290 base::Bind(&SystemLogUploader::StartLogUpload, |
| 289 weak_factory_.GetWeakPtr()), | 291 weak_factory_.GetWeakPtr()), |
| 290 delay); | 292 delay); |
| 291 } | 293 } |
| 292 | 294 |
| 293 } // namespace policy | 295 } // namespace policy |
| OLD | NEW |