| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/chromeos/system_logs/debug_log_writer.h" | 5 #include "chrome/browser/chromeos/system_logs/debug_log_writer.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/files/file.h" | 14 #include "base/files/file.h" |
| 15 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
| 16 #include "base/lazy_instance.h" |
| 16 #include "base/process/kill.h" | 17 #include "base/process/kill.h" |
| 17 #include "base/process/launch.h" | 18 #include "base/process/launch.h" |
| 18 #include "base/task_scheduler/post_task.h" | 19 #include "base/task_scheduler/post_task.h" |
| 19 #include "base/threading/sequenced_worker_pool.h" | |
| 20 #include "chrome/common/logging_chrome.h" | 20 #include "chrome/common/logging_chrome.h" |
| 21 #include "chromeos/dbus/dbus_thread_manager.h" | 21 #include "chromeos/dbus/dbus_thread_manager.h" |
| 22 #include "chromeos/dbus/debug_daemon_client.h" | 22 #include "chromeos/dbus/debug_daemon_client.h" |
| 23 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 24 | 24 |
| 25 namespace chromeos { | 25 namespace chromeos { |
| 26 | 26 |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 // Callback for returning status of executed external command. | 29 // Callback for returning status of executed external command. |
| 30 typedef base::Callback<void(bool succeeded)> CommandCompletionCallback; | 30 typedef base::Callback<void(bool succeeded)> CommandCompletionCallback; |
| 31 | 31 |
| 32 const char kGzipCommand[] = "/bin/gzip"; | 32 const char kGzipCommand[] = "/bin/gzip"; |
| 33 const char kTarCommand[] = "/bin/tar"; | 33 const char kTarCommand[] = "/bin/tar"; |
| 34 | 34 |
| 35 scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner( | 35 struct DebugLogWriterTaskRunner { |
| 36 const std::string sequence_name) { | 36 const scoped_refptr<base::SequencedTaskRunner> task_runner = |
| 37 base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool(); | 37 base::CreateSequencedTaskRunnerWithTraits( |
| 38 return pool->GetSequencedTaskRunnerWithShutdownBehavior( | 38 {base::MayBlock(), base::TaskPriority::BACKGROUND, |
| 39 pool->GetNamedSequenceToken(sequence_name), | 39 base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); |
| 40 base::SequencedWorkerPool::BLOCK_SHUTDOWN); | 40 }; |
| 41 } | 41 |
| 42 base::LazyInstance<DebugLogWriterTaskRunner>::Leaky g_sequenced_task_runner = |
| 43 LAZY_INSTANCE_INITIALIZER; |
| 42 | 44 |
| 43 // Called upon completion of |WriteDebugLogToFile|. Closes file | 45 // Called upon completion of |WriteDebugLogToFile|. Closes file |
| 44 // descriptor, deletes log file in the case of failure and calls | 46 // descriptor, deletes log file in the case of failure and calls |
| 45 // |callback|. | 47 // |callback|. |
| 46 void WriteDebugLogToFileCompleted( | 48 void WriteDebugLogToFileCompleted( |
| 47 const base::FilePath& file_path, | 49 const base::FilePath& file_path, |
| 48 const std::string& sequence_token_name, | 50 const std::string& sequence_token_name, |
| 49 const DebugLogWriter::StoreLogsCallback& callback, | 51 const DebugLogWriter::StoreLogsCallback& callback, |
| 50 bool succeeded) { | 52 bool succeeded) { |
| 51 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 53 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 52 if (!succeeded) { | 54 if (!succeeded) { |
| 53 bool posted = GetSequencedTaskRunner(sequence_token_name)->PostTaskAndReply( | 55 bool posted = g_sequenced_task_runner.Get().task_runner->PostTaskAndReply( |
| 54 FROM_HERE, | 56 FROM_HERE, |
| 55 base::Bind(base::IgnoreResult(&base::DeleteFile), file_path, false), | 57 base::Bind(base::IgnoreResult(&base::DeleteFile), file_path, false), |
| 56 base::Bind(callback, file_path, false)); | 58 base::Bind(callback, file_path, false)); |
| 57 DCHECK(posted); | 59 DCHECK(posted); |
| 58 return; | 60 return; |
| 59 } | 61 } |
| 60 if (!callback.is_null()) | 62 if (!callback.is_null()) |
| 61 callback.Run(file_path, true); | 63 callback.Run(file_path, true); |
| 62 } | 64 } |
| 63 | 65 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 74 << ", " | 76 << ", " |
| 75 << "error: " << file->error_details(); | 77 << "error: " << file->error_details(); |
| 76 return; | 78 return; |
| 77 } | 79 } |
| 78 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->DumpDebugLogs( | 80 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->DumpDebugLogs( |
| 79 should_compress, file->GetPlatformFile(), | 81 should_compress, file->GetPlatformFile(), |
| 80 base::Bind(&WriteDebugLogToFileCompleted, file_path, sequence_token_name, | 82 base::Bind(&WriteDebugLogToFileCompleted, file_path, sequence_token_name, |
| 81 callback)); | 83 callback)); |
| 82 | 84 |
| 83 // Close the file on an IO-allowed thread. | 85 // Close the file on an IO-allowed thread. |
| 84 GetSequencedTaskRunner(sequence_token_name) | 86 g_sequenced_task_runner.Get().task_runner->DeleteSoon(FROM_HERE, |
| 85 ->PostTask(FROM_HERE, | 87 file.release()); |
| 86 base::Bind(&base::DeletePointer<base::File>, file.release())); | |
| 87 } | 88 } |
| 88 | 89 |
| 89 // Runs command with its parameters as defined in |argv|. | 90 // Runs command with its parameters as defined in |argv|. |
| 90 // Upon completion, it will report command run outcome via |callback| on the | 91 // Upon completion, it will report command run outcome via |callback| on the |
| 91 // same thread from where it was initially called from. | 92 // same thread from where it was initially called from. |
| 92 void RunCommand(const std::vector<std::string>& argv, | 93 void RunCommand(const std::vector<std::string>& argv, |
| 93 const CommandCompletionCallback& callback) { | 94 const CommandCompletionCallback& callback) { |
| 94 base::Process process = base::LaunchProcess(argv, base::LaunchOptions()); | 95 base::Process process = base::LaunchProcess(argv, base::LaunchOptions()); |
| 95 if (!process.IsValid()) { | 96 if (!process.IsValid()) { |
| 96 LOG(ERROR) << "Failed to execute command " << argv[0]; | 97 LOG(ERROR) << "Failed to execute command " << argv[0]; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 void StartLogRetrieval(const base::FilePath& file_name_template, | 221 void StartLogRetrieval(const base::FilePath& file_name_template, |
| 221 bool should_compress, | 222 bool should_compress, |
| 222 const std::string& sequence_token_name, | 223 const std::string& sequence_token_name, |
| 223 const DebugLogWriter::StoreLogsCallback& callback) { | 224 const DebugLogWriter::StoreLogsCallback& callback) { |
| 224 base::FilePath file_path = | 225 base::FilePath file_path = |
| 225 logging::GenerateTimestampedName(file_name_template, base::Time::Now()); | 226 logging::GenerateTimestampedName(file_name_template, base::Time::Now()); |
| 226 | 227 |
| 227 int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE; | 228 int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE; |
| 228 std::unique_ptr<base::File> file(new base::File); | 229 std::unique_ptr<base::File> file(new base::File); |
| 229 base::File* file_ptr = file.get(); | 230 base::File* file_ptr = file.get(); |
| 230 GetSequencedTaskRunner(sequence_token_name) | 231 g_sequenced_task_runner.Get().task_runner->PostTaskAndReply( |
| 231 ->PostTaskAndReply( | 232 FROM_HERE, |
| 232 FROM_HERE, base::Bind(&InitializeLogFile, base::Unretained(file_ptr), | 233 base::Bind(&InitializeLogFile, base::Unretained(file_ptr), file_path, |
| 233 file_path, flags), | 234 flags), |
| 234 base::Bind(&WriteDebugLogToFile, base::Passed(&file), | 235 base::Bind(&WriteDebugLogToFile, base::Passed(&file), sequence_token_name, |
| 235 sequence_token_name, file_path, should_compress, | 236 file_path, should_compress, callback)); |
| 236 callback)); | |
| 237 } | 237 } |
| 238 | 238 |
| 239 const char kDefaultSequenceName[] = "DebugLogWriter"; | 239 const char kDefaultSequenceName[] = "DebugLogWriter"; |
| 240 | 240 |
| 241 } // namespace | 241 } // namespace |
| 242 | 242 |
| 243 // static. | 243 // static. |
| 244 void DebugLogWriter::StoreLogs(const base::FilePath& fileshelf, | 244 void DebugLogWriter::StoreLogs(const base::FilePath& fileshelf, |
| 245 bool should_compress, | 245 bool should_compress, |
| 246 const StoreLogsCallback& callback) { | 246 const StoreLogsCallback& callback) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 265 fileshelf.Append(FILE_PATH_LITERAL("combined-logs.tar")); | 265 fileshelf.Append(FILE_PATH_LITERAL("combined-logs.tar")); |
| 266 | 266 |
| 267 // Get system logs from /var/log first, then add user-specific stuff. | 267 // Get system logs from /var/log first, then add user-specific stuff. |
| 268 StartLogRetrieval(file_path, | 268 StartLogRetrieval(file_path, |
| 269 false, | 269 false, |
| 270 sequence_token_name, | 270 sequence_token_name, |
| 271 base::Bind(&OnSystemLogsAdded, callback)); | 271 base::Bind(&OnSystemLogsAdded, callback)); |
| 272 } | 272 } |
| 273 | 273 |
| 274 } // namespace chromeos | 274 } // namespace chromeos |
| OLD | NEW |