summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-12 15:35:03 +0000
committerygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-12 15:35:03 +0000
commit395a03967310f3a869c6d2e486cdd73677e7ab69 (patch)
treef5de9386234f42f039169cc2c62118d0b668bd80 /chrome/browser
parent283794fa145a785af7dc74020ff66cdc1552239a (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/resources/net_internals/browser_bridge.js20
-rw-r--r--chrome/browser/resources/net_internals/chromeos_view.html9
-rw-r--r--chrome/browser/resources/net_internals/chromeos_view.js21
-rw-r--r--chrome/browser/ui/webui/net_internals/net_internals_ui.cc111
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(