diff options
author | hansl@google.com <hansl@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-23 00:56:37 +0000 |
---|---|---|
committer | hansl@google.com <hansl@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-23 00:56:37 +0000 |
commit | 58014de258cdb66f3b3b733031f386c6124f8e16 (patch) | |
tree | deba2032a4dd584ac51bb44f98a165307691dc2d /ceee | |
parent | f0b6b4881e24a1e7cd9524c4e381382c14bde1f1 (diff) | |
download | chromium_src-58014de258cdb66f3b3b733031f386c6124f8e16.zip chromium_src-58014de258cdb66f3b3b733031f386c6124f8e16.tar.gz chromium_src-58014de258cdb66f3b3b733031f386c6124f8e16.tar.bz2 |
Add UMA histograms services to CEEE. The histograms are aggregated in the broker, using RPC to send them, and then sent once every 15 minutes to the server.
Uses metrics_service.cc from chrome_frame. Adds dependency to RPC runtime for the BHO and to glue_renderer for linking.
This depends on http://codereview.chromium.org/5247001 for uploading data.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/5116008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67035 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ceee')
-rw-r--r-- | ceee/ie/broker/broker.gyp | 7 | ||||
-rw-r--r-- | ceee/ie/broker/broker_module.cc | 8 | ||||
-rw-r--r-- | ceee/ie/broker/broker_rpc_client.cc | 22 | ||||
-rw-r--r-- | ceee/ie/broker/broker_rpc_client.h | 8 | ||||
-rw-r--r-- | ceee/ie/broker/broker_rpc_lib.idl | 11 | ||||
-rw-r--r-- | ceee/ie/broker/broker_rpc_server.cc | 41 | ||||
-rw-r--r-- | ceee/ie/common/common.gyp | 1 | ||||
-rw-r--r-- | ceee/ie/common/metrics_util.h | 61 | ||||
-rw-r--r-- | ceee/ie/common/metrics_util_unittest.cc | 72 | ||||
-rw-r--r-- | ceee/ie/ie.gyp | 1 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/bho.gyp | 6 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/browser_helper_object.cc | 20 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/browser_helper_object.h | 4 |
13 files changed, 261 insertions, 1 deletions
diff --git a/ceee/ie/broker/broker.gyp b/ceee/ie/broker/broker.gyp index b7f40ef..e669013 100644 --- a/ceee/ie/broker/broker.gyp +++ b/ceee/ie/broker/broker.gyp @@ -62,6 +62,8 @@ '../../../ceee/common/common.gyp:initializing_coclass', '../../../ceee/common/common.gyp:ceee_common', '<(DEPTH)/chrome_frame/chrome_frame.gyp:chrome_tab_idl', + # Metrics service requires this. + '<(DEPTH)/webkit/support/webkit_support.gyp:webkit_user_agent', ], 'sources': [ 'api_dispatcher.cc', @@ -102,6 +104,10 @@ 'window_api_module.h', 'window_events_funnel.cc', 'window_events_funnel.h', + # For chrome metrics service + '<(DEPTH)/chrome_frame/metrics_service.cc', + '<(DEPTH)/chrome_frame/metrics_service.h', + '<(DEPTH)/chrome_frame/renderer_glue.cc', ], 'include_dirs': [ # For chrome_tab.h @@ -133,6 +139,7 @@ '<(DEPTH)/chrome/chrome.gyp:chrome_version_header', '<(DEPTH)/chrome_frame/chrome_frame.gyp:chrome_frame_ie', # for GUIDs. '<(DEPTH)/chrome_frame/chrome_frame.gyp:chrome_tab_idl', + '<(DEPTH)/chrome/chrome.gyp:common', ], 'msvs_settings': { 'VCLinkerTool': { diff --git a/ceee/ie/broker/broker_module.cc b/ceee/ie/broker/broker_module.cc index fca2164..bdfec36 100644 --- a/ceee/ie/broker/broker_module.cc +++ b/ceee/ie/broker/broker_module.cc @@ -21,6 +21,7 @@ #include "ceee/ie/common/crash_reporter.h" #include "ceee/common/com_utils.h" #include "chrome/common/url_constants.h" +#include "chrome_frame/metrics_service.h" namespace { @@ -164,6 +165,9 @@ HRESULT CeeeBrokerModule::PreMessageLoop(int show) { if (!rpc_server_.Start()) return RPC_E_FAULT; + // Initialize metrics. We need the rpc_server_ above to be available. + MetricsService::Start(); + return CAtlExeModuleT<CeeeBrokerModule>::PreMessageLoop(show); } @@ -172,6 +176,10 @@ HRESULT CeeeBrokerModule::PostMessageLoop() { Singleton<ExecutorsManager, ExecutorsManager::SingletonTraits>()->Terminate(); WindowEventsFunnel::Terminate(); + + // Upload data if necessary. + MetricsService::Stop(); + chrome_postman_.Term(); return hr; } diff --git a/ceee/ie/broker/broker_rpc_client.cc b/ceee/ie/broker/broker_rpc_client.cc index d24025c..54a308b 100644 --- a/ceee/ie/broker/broker_rpc_client.cc +++ b/ceee/ie/broker/broker_rpc_client.cc @@ -132,3 +132,25 @@ HRESULT BrokerRpcClient::FireEvent(const char* event_name, } RpcEndExcept return RPC_E_FAULT; } + +bool BrokerRpcClient::SendUmaHistogramTimes(BSTR event_name, int sample) { + RpcTryExcept { + BrokerRpcClient_SendUmaHistogramTimes(binding_handle_, event_name, sample); + return true; + } RpcExcept(HandleRpcException(RpcExceptionCode())) { + LogRpcException("RPC error in SendUmaHistogramTimes", RpcExceptionCode()); + } RpcEndExcept + return false; +} + +bool BrokerRpcClient::SendUmaHistogramData(BSTR event_name, int sample, + int min, int max, int bucket_count) { + RpcTryExcept { + BrokerRpcClient_SendUmaHistogramData(binding_handle_, event_name, sample, + min, max, bucket_count); + return true; + } RpcExcept(HandleRpcException(RpcExceptionCode())) { + LogRpcException("RPC error in SendUmaHistogramData", RpcExceptionCode()); + } RpcEndExcept + return false; +} diff --git a/ceee/ie/broker/broker_rpc_client.h b/ceee/ie/broker/broker_rpc_client.h index 6a9c79d..d204e62 100644 --- a/ceee/ie/broker/broker_rpc_client.h +++ b/ceee/ie/broker/broker_rpc_client.h @@ -31,6 +31,14 @@ class BrokerRpcClient { // @{ // Calls FireEvent on server side. HRESULT FireEvent(const char* event_name, const char* event_args); + // Adds uma to histograms on the server side. Either performance timings or + // generic histogram. + virtual bool SendUmaHistogramTimes(BSTR event_name, + int sample); + virtual bool SendUmaHistogramData(BSTR event_name, + int sample, + int min, int max, + int bucket_count); // @} // Starts new CEEE broker if nessesary. diff --git a/ceee/ie/broker/broker_rpc_lib.idl b/ceee/ie/broker/broker_rpc_lib.idl index 7077e48..abb583a 100644 --- a/ceee/ie/broker/broker_rpc_lib.idl +++ b/ceee/ie/broker/broker_rpc_lib.idl @@ -31,6 +31,17 @@ void FireEvent( [in] handle_t binding_handle, [in, string] const char* event_name, [in, string] const char* event_args); +void SendUmaHistogramTimes( + [in] handle_t binding_handle, + [in] BSTR event_name, + [in] int sample); +void SendUmaHistogramData( + [in] handle_t binding_handle, + [in] BSTR event_name, + [in] int sample, + [in] int min, + [in] int max, + [in] int bucket_count); // @} } diff --git a/ceee/ie/broker/broker_rpc_server.cc b/ceee/ie/broker/broker_rpc_server.cc index 24147dd..0e899be 100644 --- a/ceee/ie/broker/broker_rpc_server.cc +++ b/ceee/ie/broker/broker_rpc_server.cc @@ -7,6 +7,7 @@ #include "ceee/ie/broker/broker_rpc_server.h" #include "base/atomic_sequence_num.h" +#include "base/metrics/histogram.h" #include "base/logging.h" #include "base/win_util.h" #include "broker_rpc_lib.h" // NOLINT @@ -15,6 +16,10 @@ #include "ceee/ie/broker/broker_rpc_utils.h" #include "ceee/ie/broker/chrome_postman.h" +// This lock ensures that histograms created by the broker are thread safe. +// The histograms created here can be initialized on multiple threads. +Lock g_metrics_lock; + BrokerRpcServer::BrokerRpcServer() : is_started_(false), current_thread_(::GetCurrentThreadId()) { @@ -128,3 +133,39 @@ void BrokerRpcServer_FireEvent( if (ChromePostman::GetInstance()) ChromePostman::GetInstance()->FireEvent(event_name, event_args); } + +void BrokerRpcServer_SendUmaHistogramTimes(handle_t binding_handle, + BSTR event_name, + int sample) { + // We can't unfortunately use the HISTOGRAM_*_TIMES here because they use + // static variables to save time. FactoryTimeGet is not so expensive though + // and this call is non-blocking. + AutoLock lock(g_metrics_lock); + std::string name(CW2A(event_name).m_psz); + scoped_refptr<base::Histogram> counter = + base::Histogram::FactoryTimeGet(name, + base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromSeconds(10), + 50, base::Histogram::kUmaTargetedHistogramFlag); + DCHECK_EQ(name, counter->histogram_name()); + if (counter.get()) + counter->AddTime(base::TimeDelta::FromMilliseconds(sample)); +} + +void BrokerRpcServer_SendUmaHistogramData(handle_t binding_handle, + BSTR event_name, + int sample, + int min, int max, + int bucket_count) { + // We can't unfortunately use the HISTOGRAM_*_COUNT here because they use + // static variables to save time. FactoryTimeGet is not so expensive though + // and this call is non-blocking. + AutoLock lock(g_metrics_lock); + std::string name(CW2A(event_name).m_psz); + scoped_refptr<base::Histogram> counter = + base::Histogram::FactoryGet(name, min, max, bucket_count, + base::Histogram::kUmaTargetedHistogramFlag); + DCHECK_EQ(name, counter->histogram_name()); + if (counter.get()) + counter->AddTime(base::TimeDelta::FromMilliseconds(sample)); +} diff --git a/ceee/ie/common/common.gyp b/ceee/ie/common/common.gyp index 94e79f4..0790fb5 100644 --- a/ceee/ie/common/common.gyp +++ b/ceee/ie/common/common.gyp @@ -77,6 +77,7 @@ 'mock_ie_tab_interfaces.h', 'ceee_module_util.cc', 'ceee_module_util.h', + 'metrics_util.h', # TODO(joi@chromium.org) Refactor to use chrome/common library. '../../../chrome/browser/automation/extension_automation_constants.cc', diff --git a/ceee/ie/common/metrics_util.h b/ceee/ie/common/metrics_util.h new file mode 100644 index 0000000..fed8033 --- /dev/null +++ b/ceee/ie/common/metrics_util.h @@ -0,0 +1,61 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// CEEE module-wide metrics utilities. + +#ifndef CEEE_IE_COMMON_METRICS_UTIL_H__ +#define CEEE_IE_COMMON_METRICS_UTIL_H__ + +#include <atlsafe.h> +#include <string> + +#include "base/logging.h" +#include "base/time.h" +#include "base/utf_string_conversions.h" +#include "base/win/scoped_bstr.h" +#include "base/win/windows_version.h" +#include "ceee/ie/broker/broker_rpc_client.h" + +namespace metrics_util { + +// This is a class that measures the time taken from its construction to its +// destruction. A good way to use it is to instantiate it on the stack. +// TODO(hansl): Make sure the BrokerRpcClient calls from this class are non- +// blocking. +class ScopedTimer { + public: + // Callers must ensure broker_rpc exceeds the life of this object. + ScopedTimer(const std::string name, BrokerRpcClient* broker_rpc) + : name_(name), broker_rpc_(broker_rpc), start_(base::TimeTicks::Now()) { + CHECK(broker_rpc) << "Invalid parameter."; + + if (name.length() == 0) { + NOTREACHED() << "Histogram name shouldn't be empty."; + broker_rpc_ = NULL; // Ensure we don't call the broker_rpc. + } + } + ~ScopedTimer() { + if (broker_rpc_) { + base::win::ScopedBstr name(CA2W(name_.c_str()).m_psz); + base::TimeDelta delta = base::TimeTicks::Now() - start_; + if (!broker_rpc_->SendUmaHistogramTimes( + name, static_cast<int>(delta.InMilliseconds()))) { + NOTREACHED() << "An error happened during RPC."; + } + } + } + + protected: + base::TimeTicks start_; + + // The RPC Client to use when sending events. + BrokerRpcClient* broker_rpc_; + + // The name of the event when sending it. + std::string name_; +}; + +} + +#endif // CEEE_IE_COMMON_METRICS_UTIL_H__ diff --git a/ceee/ie/common/metrics_util_unittest.cc b/ceee/ie/common/metrics_util_unittest.cc new file mode 100644 index 0000000..2acc41c --- /dev/null +++ b/ceee/ie/common/metrics_util_unittest.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Unit tests for the CEEE metrics utilities. + +#include <atlconv.h> + +#include "ceee/ie/common/metrics_util.h" + +#include <wtypes.h> +#include <string> + +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/logging.h" +#include "base/path_service.h" +#include "base/win/registry.h" +#include "base/string_util.h" +#include "ceee/common/process_utils_win.h" +#include "ceee/ie/testing/mock_broker_and_friends.h" +#include "ceee/testing/utils/mock_com.h" +#include "ceee/testing/utils/mock_window_utils.h" +#include "ceee/testing/utils/mock_win32.h" +#include "ceee/testing/utils/test_utils.h" +#include "base/time.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace { + +using testing::_; +using testing::DoAll; +using testing::NotNull; +using testing::SetArgumentPointee; +using testing::StrictMock; +using testing::Return; + +class BrokerRpcClientMock : public BrokerRpcClient { +public: + MOCK_METHOD2(SendUmaHistogramTimes, bool(BSTR, int)); + MOCK_METHOD5(SendUmaHistogramData, bool(BSTR, int, int, int, int)); +}; + +class CeeeMetricsUtilTest : public testing::Test { + protected: + virtual void CreateAndDestroyTimer(BrokerRpcClient* rpc_client) { + metrics_util::ScopedTimer timer("NonEmptyName", rpc_client); + } +}; + +// Invalid broker or empty name initialization should CHECK(false). +TEST_F(CeeeMetricsUtilTest, ScopedTimerError) { + testing::LogDisabler no_dcheck; + // Since we can't test yet for NOTREACHED() or CHECK(false), do nothing. + // TODO(hansl): when we can test for NOTREACHED, validate that passing invalid + // values to the ScopedTimer will indeed fail. +} + + +// Test for successful uses of the ScopedTimer. +TEST_F(CeeeMetricsUtilTest, ScopedTimerSuccess) { + testing::LogDisabler no_dcheck; + + // Test that timing is right. This should ultimately succeed. + // We expect less than a couple milliseconds on this call. + BrokerRpcClientMock broker_rpc; + EXPECT_CALL(broker_rpc, SendUmaHistogramTimes(_, testing::Lt(10))); + CreateAndDestroyTimer(&broker_rpc); +} + +} // namespace diff --git a/ceee/ie/ie.gyp b/ceee/ie/ie.gyp index a731e8e..91e7ebf 100644 --- a/ceee/ie/ie.gyp +++ b/ceee/ie/ie.gyp @@ -34,6 +34,7 @@ 'common/crash_reporter_unittest.cc', 'common/extension_manifest_unittest.cc', 'common/ceee_module_util_unittest.cc', + 'common/metrics_util_unittest.cc', 'plugin/bho/browser_helper_object_unittest.cc', 'plugin/bho/cookie_accountant_unittest.cc', 'plugin/bho/cookie_events_funnel_unittest.cc', diff --git a/ceee/ie/plugin/bho/bho.gyp b/ceee/ie/plugin/bho/bho.gyp index d6e4d9e..c38d820 100644 --- a/ceee/ie/plugin/bho/bho.gyp +++ b/ceee/ie/plugin/bho/bho.gyp @@ -16,6 +16,7 @@ 'dependencies': [ '../toolband/toolband.gyp:toolband_idl', '../../broker/broker.gyp:broker', + '../../broker/broker.gyp:broker_rpc_lib', '../../common/common.gyp:ie_common', '../../common/common.gyp:ie_common_settings', '../../../common/common.gyp:ceee_common', @@ -23,7 +24,7 @@ '../../../../base/base.gyp:base', '../../../../chrome_frame/chrome_frame.gyp:chrome_tab_idl', # For the vtable patching stuff... - '../../../../chrome_frame/chrome_frame.gyp:chrome_frame_ie', + '<(DEPTH)/chrome_frame/chrome_frame.gyp:chrome_frame_ie', ], 'sources': [ 'browser_helper_object.cc', @@ -79,6 +80,9 @@ # For chrome_tab.h '<(SHARED_INTERMEDIATE_DIR)', ], + 'libraries': [ + 'rpcrt4.lib', + ], }, ] } diff --git a/ceee/ie/plugin/bho/browser_helper_object.cc b/ceee/ie/plugin/bho/browser_helper_object.cc index 545e65f..e237442 100644 --- a/ceee/ie/plugin/bho/browser_helper_object.cc +++ b/ceee/ie/plugin/bho/browser_helper_object.cc @@ -22,6 +22,7 @@ #include "ceee/ie/broker/tab_api_module.h" #include "ceee/ie/common/extension_manifest.h" #include "ceee/ie/common/ie_util.h" +#include "ceee/ie/common/metrics_util.h" #include "ceee/ie/common/ceee_module_util.h" #include "ceee/ie/plugin/bho/cookie_accountant.h" #include "ceee/ie/plugin/bho/http_negotiate.h" @@ -105,6 +106,8 @@ BrowserHelperObject::BrowserHelperObject() } BrowserHelperObject::~BrowserHelperObject() { + broker_rpc_.Disconnect(); + TRACE_EVENT_END("ceee.bho", this, ""); } @@ -129,6 +132,8 @@ STDMETHODIMP BrowserHelperObject::SetSite(IUnknown* site) { } if (NULL == site) { + metrics_util::ScopedTimer metrics_timer("ceee/BHO.TearDown", &broker_rpc_); + // We're being torn down. TearDown(); @@ -137,6 +142,7 @@ STDMETHODIMP BrowserHelperObject::SetSite(IUnknown* site) { FireOnUnmappedEvent(); } + metrics_util::ScopedTimer metrics_timer("ceee/BHO.Initialize", &broker_rpc_); HRESULT hr = SuperSite::SetSite(site); if (FAILED(hr)) return hr; @@ -252,6 +258,9 @@ HRESULT BrowserHelperObject::Initialize(IUnknown* site) { com::LogHr(hr); DCHECK(SUCCEEDED(hr)) << "CoCreating Broker. " << com::LogHr(hr); if (SUCCEEDED(hr)) { + broker_rpc_.Connect(); + DCHECK(broker_rpc_.is_connected()); + DCHECK(executor_ == NULL); hr = CreateExecutor(&executor_); LOG_IF(ERROR, FAILED(hr)) << "Failed to create Executor, hr=" << @@ -742,6 +751,9 @@ STDMETHODIMP_(void) BrowserHelperObject::OnBeforeNavigate2( void BrowserHelperObject::OnBeforeNavigate2Impl( const ScopedDispatchPtr& webbrowser_disp, const CComBSTR& url) { + metrics_util::ScopedTimer metrics_timer("ceee/BHO.BeforeNavigate", + &broker_rpc_); + base::win::ScopedComPtr<IWebBrowser2> webbrowser; HRESULT hr = webbrowser.QueryFrom(webbrowser_disp); if (FAILED(hr)) { @@ -805,6 +817,8 @@ STDMETHODIMP_(void) BrowserHelperObject::OnDocumentComplete( void BrowserHelperObject::OnDocumentCompleteImpl( const ScopedWebBrowser2Ptr& webbrowser, const CComBSTR& url) { + metrics_util::ScopedTimer metrics_timer("ceee/BHO.DocumentComplete", + &broker_rpc_); for (std::vector<Sink*>::iterator iter = sinks_.begin(); iter != sinks_.end(); ++iter) { (*iter)->OnDocumentComplete(webbrowser, url); @@ -843,6 +857,9 @@ STDMETHODIMP_(void) BrowserHelperObject::OnNavigateComplete2( void BrowserHelperObject::OnNavigateComplete2Impl( const ScopedWebBrowser2Ptr& webbrowser, const CComBSTR& url) { + metrics_util::ScopedTimer metrics_timer("ceee/BHO.NavigateComplete", + &broker_rpc_); + HandleNavigateComplete(webbrowser, url); for (std::vector<Sink*>::iterator iter = sinks_.begin(); @@ -892,6 +909,9 @@ STDMETHODIMP_(void) BrowserHelperObject::OnNavigateError( void BrowserHelperObject::OnNavigateErrorImpl( const ScopedWebBrowser2Ptr& webbrowser, const CComBSTR& url, LONG status_code) { + metrics_util::ScopedTimer metrics_timer("ceee/BHO.NavigateError", + &broker_rpc_); + for (std::vector<Sink*>::iterator iter = sinks_.begin(); iter != sinks_.end(); ++iter) { (*iter)->OnNavigateError(webbrowser, url, status_code); diff --git a/ceee/ie/plugin/bho/browser_helper_object.h b/ceee/ie/plugin/bho/browser_helper_object.h index 3758fec..039b305 100644 --- a/ceee/ie/plugin/bho/browser_helper_object.h +++ b/ceee/ie/plugin/bho/browser_helper_object.h @@ -21,6 +21,7 @@ #include "base/win/scoped_bstr.h" #include "base/win/scoped_comptr.h" #include "base/task.h" +#include "ceee/ie/broker/broker_rpc_client.h" #include "ceee/ie/plugin/bho/tab_events_funnel.h" #include "ceee/ie/common/chrome_frame_host.h" #include "ceee/ie/plugin/bho/frame_event_handler.h" @@ -366,6 +367,9 @@ class ATL_NO_VTABLE BrowserHelperObject // Indicates if the current shown page is a full-tab chrome frame. bool full_tab_chrome_frame_; + // The RPC client used to communicate with the broker. + BrokerRpcClient broker_rpc_; + private: // Used during initialization to get the tab information from Chrome and // register ourselves with the broker. |