diff options
author | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-12 15:35:03 +0000 |
---|---|---|
committer | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-12 15:35:03 +0000 |
commit | 395a03967310f3a869c6d2e486cdd73677e7ab69 (patch) | |
tree | f5de9386234f42f039169cc2c62118d0b668bd80 /chrome/browser | |
parent | 283794fa145a785af7dc74020ff66cdc1552239a (diff) | |
download | chromium_src-395a03967310f3a869c6d2e486cdd73677e7ab69.zip chromium_src-395a03967310f3a869c6d2e486cdd73677e7ab69.tar.gz chromium_src-395a03967310f3a869c6d2e486cdd73677e7ab69.tar.bz2 |
Added "Store Debug Logs" functionality. Logs from /var/log are gzipped
and stored on the fileshelf.
BUG=chromium-os:25700
TEST=
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=131963
Review URL: http://codereview.chromium.org/9965072
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131988 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
4 files changed, 160 insertions, 1 deletions
diff --git a/chrome/browser/resources/net_internals/browser_bridge.js b/chrome/browser/resources/net_internals/browser_bridge.js index 7353b45..5184f3a 100644 --- a/chrome/browser/resources/net_internals/browser_bridge.js +++ b/chrome/browser/resources/net_internals/browser_bridge.js @@ -26,6 +26,7 @@ var BrowserBridge = (function() { this.httpThrottlingObservers_ = []; this.constantsObservers_ = []; this.crosONCFileParseObservers_ = []; + this.storeDebugLogsObservers_ = []; this.pollableDataHelpers_ = {}; this.pollableDataHelpers_.proxySettings = @@ -233,6 +234,10 @@ var BrowserBridge = (function() { this.send('importONCFile', [fileContent, passcode]); }, + storeDebugLogs: function() { + this.send('storeDebugLogs'); + }, + sendGetHttpPipeliningStatus: function() { this.send('getHttpPipeliningStatus'); }, @@ -325,6 +330,11 @@ var BrowserBridge = (function() { this.crosONCFileParseObservers_[i].onONCFileParse(error); }, + receivedStoreDebugLogs: function(status) { + for (var i = 0; i < this.storeDebugLogsObservers_.length; i++) + this.storeDebugLogsObservers_[i].onStoreDebugLogs(status); + }, + receivedHttpCacheInfo: function(info) { this.pollableDataHelpers_.httpCacheInfo.update(info); }, @@ -521,6 +531,16 @@ var BrowserBridge = (function() { }, /** + * Adds a listener for storing log file status. The observer will be called + * back with: + * + * observer.onStoreDebugLogs(status); + */ + addStoreDebugLogsObserver: function(observer) { + this.storeDebugLogsObservers_.push(observer); + }, + + /** * Adds a listener for HTTP throttling-related events. |observer| will be * called back when HTTP throttling is enabled/disabled, through: * diff --git a/chrome/browser/resources/net_internals/chromeos_view.html b/chrome/browser/resources/net_internals/chromeos_view.html index 6b552ae..098b04f 100644 --- a/chrome/browser/resources/net_internals/chromeos_view.html +++ b/chrome/browser/resources/net_internals/chromeos_view.html @@ -11,4 +11,13 @@ </div> <div id="chromeos-view-parse-status" hidden> </div> + <div id="chromeos-view-store-debug-logs-div"> + <h3>Store Logs</h3> + <input type="button" + id="chromeos-view-store-debug-logs" + value="Store Debug Logs"> + <label for="chromeos-view-store-debug-logs" + id="chromeos-view-store-debug-logs-status"> + </label> + </div> </div> diff --git a/chrome/browser/resources/net_internals/chromeos_view.js b/chrome/browser/resources/net_internals/chromeos_view.js index fea3e36..61955ab 100644 --- a/chrome/browser/resources/net_internals/chromeos_view.js +++ b/chrome/browser/resources/net_internals/chromeos_view.js @@ -125,7 +125,17 @@ var CrosView = (function() { } /** - * Add event listeners for the file selection and passcode input fields. + * Set storing debug logs status. + * + * @private + */ + function setStoreDebugLogsStatus_(status) { + $(CrosView.STORE_DEBUG_LOGS_STATUS_ID).innerText = status; + } + + /** + * Add event listeners for the file selection, passcode input + * fields and for the button for debug logs storing. * * @private */ @@ -137,6 +147,11 @@ var CrosView = (function() { $(CrosView.PASSCODE_INPUT_ID).addEventListener('change', function(event) { setPasscode_(this.value); }, false); + + $(CrosView.STORE_DEBUG_LOGS_ID).addEventListener('click', function(event) { + $(CrosView.STORE_DEBUG_LOGS_STATUS_ID).innerText = ''; + g_browser.storeDebugLogs(); + }, false); } /** @@ -161,6 +176,7 @@ var CrosView = (function() { DivView.call(this, CrosView.MAIN_BOX_ID); g_browser.addCrosONCFileParseObserver(this); + g_browser.addStoreDebugLogsObserver(this); addEventListeners_(); } @@ -173,6 +189,8 @@ var CrosView = (function() { CrosView.PASSCODE_ID = 'chromeos-view-password-div'; CrosView.PASSCODE_INPUT_ID = 'chromeos-view-onc-password'; CrosView.PARSE_STATUS_ID = 'chromeos-view-parse-status'; + CrosView.STORE_DEBUG_LOGS_ID = 'chromeos-view-store-debug-logs'; + CrosView.STORE_DEBUG_LOGS_STATUS_ID = 'chromeos-view-store-debug-logs-status'; cr.addSingletonGetter(CrosView); @@ -181,6 +199,7 @@ var CrosView = (function() { __proto__: DivView.prototype, onONCFileParse: setParseStatus_, + onStoreDebugLogs: setStoreDebugLogsStatus_, }; return CrosView; diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc index 4d77bf8..dc77e63 100644 --- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc +++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc @@ -14,10 +14,14 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" +#include "base/file_path.h" +#include "base/file_util.h" #include "base/memory/singleton.h" +#include "base/memory/weak_ptr.h" #include "base/message_loop.h" #include "base/message_loop_helpers.h" #include "base/path_service.h" +#include "base/platform_file.h" #include "base/string_number_conversions.h" #include "base/string_piece.h" #include "base/string_split.h" @@ -39,6 +43,7 @@ #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_version_info.h" +#include "chrome/common/logging_chrome.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "content/public/browser/browser_thread.h" @@ -72,11 +77,15 @@ #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros/network_library.h" #include "chrome/browser/chromeos/system/syslogs_provider.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/debug_daemon_client.h" #endif #ifdef OS_WIN #include "chrome/browser/net/service_providers_win.h" #endif +using base::PlatformFile; +using base::PlatformFileError; using content::BrowserThread; using content::WebContents; using content::WebUIMessageHandler; @@ -148,6 +157,84 @@ ChromeWebUIDataSource* CreateNetInternalsHTMLSource() { return source; } +#ifdef OS_CHROMEOS +// Following functions are used for getting debug logs. Logs are +// fetched from /var/log/* and put on the fileshelf. + +// Called once StoreDebugLogs is complete. Takes two parameters: +// - log_path: where the log file was saved in the case of success; +// - succeeded: was the log file saved successfully. +typedef base::Callback<void(const FilePath& log_path, + bool succeded)> StoreDebugLogsCallback; + +// Called once creation of the debug log file is completed. If +// creation failed, deletes the file by |log_path|. So, this function +// should be called on the FILE thread. After all, calls |callback| on +// the UI thread. +void CreateDebugLogFileCompleted(const StoreDebugLogsCallback& callback, + const FilePath& log_path, + bool succeeded) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + if (!succeeded) + file_util::Delete(log_path, false); + + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(callback, log_path, succeeded)); +} + +// Retrieves debug logs from DebugDaemon and puts them on the +// fileshelf directory into .tgz archive. So, this function should be +// called on the FILE thread. Calls CreateDebugLogFileCompleted on the +// FILE thread when creation of archive is completed. +void CreateDebugLogFile(const StoreDebugLogsCallback& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + const FilePath::CharType kLogFileName[] = FILE_PATH_LITERAL("debug-log.tgz"); + + FilePath fileshelf_dir; + if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &fileshelf_dir)) { + LOG(ERROR) << "Can't get fileshelf dir"; + CreateDebugLogFileCompleted(callback, FilePath(), false); + return; + } + + FilePath log_path = fileshelf_dir.Append(kLogFileName); + log_path = logging::GenerateTimestampedName(log_path, base::Time::Now()); + + int flags = base::PLATFORM_FILE_CREATE_ALWAYS | + base::PLATFORM_FILE_WRITE; + bool created; + PlatformFileError error; + PlatformFile log_file = base::CreatePlatformFile( + log_path, flags, &created, &error); + + if (!created) { + LOG(ERROR) << + "Can't create log file: " << log_path.AsUTF8Unsafe() << ", " << + "error: " << error; + CreateDebugLogFileCompleted(callback, log_path, false); + return; + } + chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> + GetDebugLogs(log_file, + base::Bind(&CreateDebugLogFileCompleted, + callback, log_path)); +} + +// Delegates the job of saving debug logs on the fileshelf to +// CreateDebugLogsFile on the FILE thread. Calls |callback| on the UI +// thread when saving is completed. This function should be called on +// the UI thread. +void StoreDebugLogs(const StoreDebugLogsCallback& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + base::Bind(&CreateDebugLogFile, callback)); +} +#endif // OS_CHROMEOS + // This class receives javascript messages from the renderer. // Note that the WebUI infrastructure runs on the UI thread, therefore all of // this class's methods are expected to run on the UI thread. @@ -187,6 +274,8 @@ class NetInternalsMessageHandler void OnRefreshSystemLogs(const ListValue* list); void OnGetSystemLog(const ListValue* list); void OnImportONCFile(const ListValue* list); + void OnStoreDebugLogs(const ListValue* list); + void OnStoreDebugLogsCompleted(const FilePath& log_path, bool succeeded); #endif private: @@ -556,6 +645,10 @@ void NetInternalsMessageHandler::RegisterMessages() { "importONCFile", base::Bind(&NetInternalsMessageHandler::OnImportONCFile, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "storeDebugLogs", + base::Bind(&NetInternalsMessageHandler::OnStoreDebugLogs, + base::Unretained(this))); #endif } @@ -1268,6 +1361,24 @@ void NetInternalsMessageHandler::OnImportONCFile(const ListValue* list) { SendJavascriptCommand("receivedONCFileParse", Value::CreateStringValue(error)); } + +void NetInternalsMessageHandler::OnStoreDebugLogs(const ListValue* list) { + StoreDebugLogs( + base::Bind(&NetInternalsMessageHandler::OnStoreDebugLogsCompleted, + AsWeakPtr())); +} + +void NetInternalsMessageHandler::OnStoreDebugLogsCompleted( + const FilePath& log_path, bool succeeded) { + std::string status; + if (succeeded) + status = "Created log file: " + log_path.BaseName().AsUTF8Unsafe(); + else + status = "Failed to create log file"; + SendJavascriptCommand("receivedStoreDebugLogs", + Value::CreateStringValue(status)); +} + #endif void NetInternalsMessageHandler::IOThreadImpl::OnGetHttpPipeliningStatus( |