Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: chrome/browser/metrics/metrics_service.cc

Issue 2744003: Preparation CL for adding crash metrics UMA counters to ChromeFrame. Basicall... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 5
6 6
7 //------------------------------------------------------------------------------ 7 //------------------------------------------------------------------------------
8 // Description of the life cycle of a instance of MetricsService. 8 // Description of the life cycle of a instance of MetricsService.
9 // 9 //
10 // OVERVIEW 10 // OVERVIEW
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 prefs::kMetricsOngoingLogs); 401 prefs::kMetricsOngoingLogs);
402 unsent_ongoing_logs->Clear(); 402 unsent_ongoing_logs->Clear();
403 } 403 }
404 404
405 MetricsService::MetricsService() 405 MetricsService::MetricsService()
406 : recording_active_(false), 406 : recording_active_(false),
407 reporting_active_(false), 407 reporting_active_(false),
408 user_permits_upload_(false), 408 user_permits_upload_(false),
409 server_permits_upload_(true), 409 server_permits_upload_(true),
410 state_(INITIALIZED), 410 state_(INITIALIZED),
411 pending_log_(NULL),
412 pending_log_text_(),
413 current_fetch_(NULL), 411 current_fetch_(NULL),
414 current_log_(NULL),
415 idle_since_last_transmission_(false), 412 idle_since_last_transmission_(false),
416 next_window_id_(0), 413 next_window_id_(0),
417 ALLOW_THIS_IN_INITIALIZER_LIST(log_sender_factory_(this)), 414 ALLOW_THIS_IN_INITIALIZER_LIST(log_sender_factory_(this)),
418 ALLOW_THIS_IN_INITIALIZER_LIST(state_saver_factory_(this)), 415 ALLOW_THIS_IN_INITIALIZER_LIST(state_saver_factory_(this)),
419 logged_samples_(),
420 interlog_duration_(TimeDelta::FromSeconds(kInitialInterlogDuration)), 416 interlog_duration_(TimeDelta::FromSeconds(kInitialInterlogDuration)),
421 log_event_limit_(kInitialEventLimit), 417 log_event_limit_(kInitialEventLimit),
422 timer_pending_(false) { 418 timer_pending_(false) {
423 DCHECK(IsSingleThreaded()); 419 DCHECK(IsSingleThreaded());
424 InitializeMetricsState(); 420 InitializeMetricsState();
425 } 421 }
426 422
427 MetricsService::~MetricsService() { 423 MetricsService::~MetricsService() {
428 SetRecording(false); 424 SetRecording(false);
429 if (pending_log_) {
430 delete pending_log_;
431 pending_log_ = NULL;
432 }
433 if (current_log_) {
434 delete current_log_;
435 current_log_ = NULL;
436 }
437 } 425 }
438 426
439 void MetricsService::SetUserPermitsUpload(bool enabled) { 427 void MetricsService::SetUserPermitsUpload(bool enabled) {
440 HandleIdleSinceLastTransmission(false); 428 HandleIdleSinceLastTransmission(false);
441 user_permits_upload_ = enabled; 429 user_permits_upload_ = enabled;
442 } 430 }
443 431
444 void MetricsService::Start() { 432 void MetricsService::Start() {
445 SetRecording(true); 433 SetRecording(true);
446 SetReporting(true); 434 SetReporting(true);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 case NotificationType::CHILD_PROCESS_HOST_CONNECTED: 578 case NotificationType::CHILD_PROCESS_HOST_CONNECTED:
591 case NotificationType::CHILD_PROCESS_CRASHED: 579 case NotificationType::CHILD_PROCESS_CRASHED:
592 case NotificationType::CHILD_INSTANCE_CREATED: 580 case NotificationType::CHILD_INSTANCE_CREATED:
593 LogChildProcessChange(type, source, details); 581 LogChildProcessChange(type, source, details);
594 break; 582 break;
595 583
596 case NotificationType::TEMPLATE_URL_MODEL_LOADED: 584 case NotificationType::TEMPLATE_URL_MODEL_LOADED:
597 LogKeywords(Source<TemplateURLModel>(source).ptr()); 585 LogKeywords(Source<TemplateURLModel>(source).ptr());
598 break; 586 break;
599 587
600 case NotificationType::OMNIBOX_OPENED_URL: 588 case NotificationType::OMNIBOX_OPENED_URL: {
601 current_log_->RecordOmniboxOpenedURL( 589 MetricsLog* current_log = current_log_->AsMetricsLog();
590 DCHECK(current_log);
591 current_log->RecordOmniboxOpenedURL(
602 *Details<AutocompleteLog>(details).ptr()); 592 *Details<AutocompleteLog>(details).ptr());
603 break; 593 break;
594 }
604 595
605 case NotificationType::BOOKMARK_MODEL_LOADED: { 596 case NotificationType::BOOKMARK_MODEL_LOADED: {
606 Profile* p = Source<Profile>(source).ptr(); 597 Profile* p = Source<Profile>(source).ptr();
607 if (p) 598 if (p)
608 LogBookmarks(p->GetBookmarkModel()); 599 LogBookmarks(p->GetBookmarkModel());
609 break; 600 break;
610 } 601 }
611 default: 602 default:
612 LOG(DFATAL); 603 LOG(DFATAL);
613 break; 604 break;
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 // Schedules a task on the file thread for execution of slower 832 // Schedules a task on the file thread for execution of slower
842 // initialization steps (such as plugin list generation) necessary 833 // initialization steps (such as plugin list generation) necessary
843 // for sending the initial log. This avoids blocking the main UI 834 // for sending the initial log. This avoids blocking the main UI
844 // thread. 835 // thread.
845 g_browser_process->file_thread()->message_loop()->PostDelayedTask(FROM_HERE, 836 g_browser_process->file_thread()->message_loop()->PostDelayedTask(FROM_HERE,
846 new InitTask(MessageLoop::current()), 837 new InitTask(MessageLoop::current()),
847 kInitialInterlogDuration * 1000 / 2); 838 kInitialInterlogDuration * 1000 / 2);
848 } 839 }
849 } 840 }
850 841
851 void MetricsService::StopRecording(MetricsLog** log) { 842 void MetricsService::StopRecording(MetricsLogBase** log) {
852 if (!current_log_) 843 if (!current_log_)
853 return; 844 return;
854 845
855 current_log_->set_hardware_class(hardware_class_); // Adds to ongoing logs. 846 MetricsLog* current_log = current_log_->AsMetricsLog();
847 DCHECK(current_log);
848 current_log->set_hardware_class(hardware_class_); // Adds to ongoing logs.
856 849
857 // TODO(jar): Integrate bounds on log recording more consistently, so that we 850 // TODO(jar): Integrate bounds on log recording more consistently, so that we
858 // can stop recording logs that are too big much sooner. 851 // can stop recording logs that are too big much sooner.
859 if (current_log_->num_events() > log_event_limit_) { 852 if (current_log_->num_events() > log_event_limit_) {
860 UMA_HISTOGRAM_COUNTS("UMA.Discarded Log Events", 853 UMA_HISTOGRAM_COUNTS("UMA.Discarded Log Events",
861 current_log_->num_events()); 854 current_log_->num_events());
862 current_log_->CloseLog(); 855 current_log_->CloseLog();
863 delete current_log_; 856 delete current_log_;
864 current_log_ = NULL; 857 current_log_ = NULL;
865 StartRecording(); // Start trivial log to hold our histograms. 858 StartRecording(); // Start trivial log to hold our histograms.
866 } 859 }
867 860
868 // Put incremental data (histogram deltas, and realtime stats deltas) at the 861 // Put incremental data (histogram deltas, and realtime stats deltas) at the
869 // end of all log transmissions (initial log handles this separately). 862 // end of all log transmissions (initial log handles this separately).
870 // Don't bother if we're going to discard current_log_. 863 // Don't bother if we're going to discard current_log_.
871 if (log) { 864 if (log) {
872 current_log_->RecordIncrementalStabilityElements(); 865 current_log->RecordIncrementalStabilityElements();
873 RecordCurrentHistograms(); 866 RecordCurrentHistograms();
874 } 867 }
875 868
876 current_log_->CloseLog(); 869 current_log_->CloseLog();
877 if (log) 870 if (log)
878 *log = current_log_; 871 *log = current_log;
879 else 872 else
880 delete current_log_; 873 delete current_log_;
881 current_log_ = NULL; 874 current_log_ = NULL;
882 } 875 }
883 876
884 void MetricsService::PushPendingLogsToUnsentLists() { 877 void MetricsService::PushPendingLogsToUnsentLists() {
885 if (state_ < INITIAL_LOG_READY) 878 if (state_ < INITIAL_LOG_READY)
886 return; // We didn't and still don't have time to get plugin list etc. 879 return; // We didn't and still don't have time to get plugin list etc.
887 880
888 if (pending_log()) { 881 if (pending_log()) {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 } 1127 }
1135 1128
1136 void MetricsService::PrepareInitialLog() { 1129 void MetricsService::PrepareInitialLog() {
1137 DCHECK(state_ == INIT_TASK_DONE); 1130 DCHECK(state_ == INIT_TASK_DONE);
1138 1131
1139 MetricsLog* log = new MetricsLog(client_id_, session_id_); 1132 MetricsLog* log = new MetricsLog(client_id_, session_id_);
1140 log->set_hardware_class(hardware_class_); // Adds to initial log. 1133 log->set_hardware_class(hardware_class_); // Adds to initial log.
1141 log->RecordEnvironment(plugins_, profile_dictionary_.get()); 1134 log->RecordEnvironment(plugins_, profile_dictionary_.get());
1142 1135
1143 // Histograms only get written to current_log_, so setup for the write. 1136 // Histograms only get written to current_log_, so setup for the write.
1144 MetricsLog* save_log = current_log_; 1137 MetricsLogBase* save_log = current_log_;
1145 current_log_ = log; 1138 current_log_ = log;
1146 RecordCurrentHistograms(); // Into current_log_... which is really log. 1139 RecordCurrentHistograms(); // Into current_log_... which is really log.
1147 current_log_ = save_log; 1140 current_log_ = save_log;
1148 1141
1149 log->CloseLog(); 1142 log->CloseLog();
1150 DCHECK(!pending_log()); 1143 DCHECK(!pending_log());
1151 pending_log_ = log; 1144 pending_log_ = log;
1152 } 1145 }
1153 1146
1154 void MetricsService::RecallUnsentLogs() { 1147 void MetricsService::RecallUnsentLogs() {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 return; 1226 return;
1234 } 1227 }
1235 1228
1236 current_fetch_.reset(new URLFetcher(GURL(WideToUTF16(server_url_)), 1229 current_fetch_.reset(new URLFetcher(GURL(WideToUTF16(server_url_)),
1237 URLFetcher::POST, 1230 URLFetcher::POST,
1238 this)); 1231 this));
1239 current_fetch_->set_request_context(Profile::GetDefaultRequestContext()); 1232 current_fetch_->set_request_context(Profile::GetDefaultRequestContext());
1240 current_fetch_->set_upload_data(kMetricsType, compressed_log); 1233 current_fetch_->set_upload_data(kMetricsType, compressed_log);
1241 } 1234 }
1242 1235
1243 void MetricsService::DiscardPendingLog() {
1244 if (pending_log_) { // Shutdown might have deleted it!
1245 delete pending_log_;
1246 pending_log_ = NULL;
1247 }
1248 pending_log_text_.clear();
1249 }
1250
1251 // This implementation is based on the Firefox MetricsService implementation.
1252 bool MetricsService::Bzip2Compress(const std::string& input,
1253 std::string* output) {
1254 bz_stream stream = {0};
1255 // As long as our input is smaller than the bzip2 block size, we should get
1256 // the best compression. For example, if your input was 250k, using a block
1257 // size of 300k or 500k should result in the same compression ratio. Since
1258 // our data should be under 100k, using the minimum block size of 100k should
1259 // allocate less temporary memory, but result in the same compression ratio.
1260 int result = BZ2_bzCompressInit(&stream,
1261 1, // 100k (min) block size
1262 0, // quiet
1263 0); // default "work factor"
1264 if (result != BZ_OK) { // out of memory?
1265 return false;
1266 }
1267
1268 output->clear();
1269
1270 stream.next_in = const_cast<char*>(input.data());
1271 stream.avail_in = static_cast<int>(input.size());
1272 // NOTE: we don't need a BZ_RUN phase since our input buffer contains
1273 // the entire input
1274 do {
1275 output->resize(output->size() + 1024);
1276 stream.next_out = &((*output)[stream.total_out_lo32]);
1277 stream.avail_out = static_cast<int>(output->size()) - stream.total_out_lo32;
1278 result = BZ2_bzCompress(&stream, BZ_FINISH);
1279 } while (result == BZ_FINISH_OK);
1280 if (result != BZ_STREAM_END) // unknown failure?
1281 return false;
1282 result = BZ2_bzCompressEnd(&stream);
1283 DCHECK(result == BZ_OK);
1284
1285 output->resize(stream.total_out_lo32);
1286
1287 return true;
1288 }
1289
1290 static const char* StatusToString(const URLRequestStatus& status) { 1236 static const char* StatusToString(const URLRequestStatus& status) {
1291 switch (status.status()) { 1237 switch (status.status()) {
1292 case URLRequestStatus::SUCCESS: 1238 case URLRequestStatus::SUCCESS:
1293 return "SUCCESS"; 1239 return "SUCCESS";
1294 1240
1295 case URLRequestStatus::IO_PENDING: 1241 case URLRequestStatus::IO_PENDING:
1296 return "IO_PENDING"; 1242 return "IO_PENDING";
1297 1243
1298 case URLRequestStatus::HANDLED_EXTERNALLY: 1244 case URLRequestStatus::HANDLED_EXTERNALLY:
1299 return "HANDLED_EXTERNALLY"; 1245 return "HANDLED_EXTERNALLY";
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
1869 pref->SetBoolean(path, value); 1815 pref->SetBoolean(path, value);
1870 RecordCurrentState(pref); 1816 RecordCurrentState(pref);
1871 } 1817 }
1872 1818
1873 void MetricsService::RecordCurrentState(PrefService* pref) { 1819 void MetricsService::RecordCurrentState(PrefService* pref) {
1874 pref->SetInt64(prefs::kStabilityLastTimestampSec, Time::Now().ToTimeT()); 1820 pref->SetInt64(prefs::kStabilityLastTimestampSec, Time::Now().ToTimeT());
1875 1821
1876 RecordPluginChanges(pref); 1822 RecordPluginChanges(pref);
1877 } 1823 }
1878 1824
1879 void MetricsService::RecordCurrentHistograms() {
1880 DCHECK(current_log_);
1881
1882 StatisticsRecorder::Histograms histograms;
1883 StatisticsRecorder::GetHistograms(&histograms);
1884 for (StatisticsRecorder::Histograms::iterator it = histograms.begin();
1885 histograms.end() != it;
1886 ++it) {
1887 if ((*it)->flags() & Histogram::kUmaTargetedHistogramFlag)
1888 // TODO(petersont): Only record historgrams if they are not precluded by
1889 // the UMA response data.
1890 // Bug http://code.google.com/p/chromium/issues/detail?id=2739.
1891 RecordHistogram(**it);
1892 }
1893 }
1894
1895 void MetricsService::RecordHistogram(const Histogram& histogram) {
1896 // Get up-to-date snapshot of sample stats.
1897 Histogram::SampleSet snapshot;
1898 histogram.SnapshotSample(&snapshot);
1899
1900 const std::string& histogram_name = histogram.histogram_name();
1901
1902 // Find the already sent stats, or create an empty set.
1903 LoggedSampleMap::iterator it = logged_samples_.find(histogram_name);
1904 Histogram::SampleSet* already_logged;
1905 if (logged_samples_.end() == it) {
1906 // Add new entry
1907 already_logged = &logged_samples_[histogram.histogram_name()];
1908 already_logged->Resize(histogram); // Complete initialization.
1909 } else {
1910 already_logged = &(it->second);
1911 // Deduct any stats we've already logged from our snapshot.
1912 snapshot.Subtract(*already_logged);
1913 }
1914
1915 // snapshot now contains only a delta to what we've already_logged.
1916
1917 if (snapshot.TotalCount() > 0) {
1918 current_log_->RecordHistogramDelta(histogram, snapshot);
1919 // Add new data into our running total.
1920 already_logged->Add(snapshot);
1921 }
1922 }
1923
1924 static bool IsSingleThreaded() { 1825 static bool IsSingleThreaded() {
1925 static PlatformThreadId thread_id = 0; 1826 static PlatformThreadId thread_id = 0;
1926 if (!thread_id) 1827 if (!thread_id)
1927 thread_id = PlatformThread::CurrentId(); 1828 thread_id = PlatformThread::CurrentId();
1928 return PlatformThread::CurrentId() == thread_id; 1829 return PlatformThread::CurrentId() == thread_id;
1929 } 1830 }
1930 1831
1931 #if defined(OS_CHROMEOS) 1832 #if defined(OS_CHROMEOS)
1932 // static 1833 // static
1933 std::string MetricsService::GetHardwareClass() { 1834 std::string MetricsService::GetHardwareClass() {
1934 DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::UI)); 1835 DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::UI));
1935 std::string hardware_class; 1836 std::string hardware_class;
1936 FilePath tool(kHardwareClassTool); 1837 FilePath tool(kHardwareClassTool);
1937 CommandLine command(tool); 1838 CommandLine command(tool);
1938 if (base::GetAppOutput(command, &hardware_class)) { 1839 if (base::GetAppOutput(command, &hardware_class)) {
1939 TrimWhitespaceASCII(hardware_class, TRIM_ALL, &hardware_class); 1840 TrimWhitespaceASCII(hardware_class, TRIM_ALL, &hardware_class);
1940 } else { 1841 } else {
1941 hardware_class = kUnknownHardwareClass; 1842 hardware_class = kUnknownHardwareClass;
1942 } 1843 }
1943 return hardware_class; 1844 return hardware_class;
1944 } 1845 }
1945 1846
1946 void MetricsService::StartExternalMetrics() { 1847 void MetricsService::StartExternalMetrics() {
1947 external_metrics_ = new chromeos::ExternalMetrics; 1848 external_metrics_ = new chromeos::ExternalMetrics;
1948 external_metrics_->Start(); 1849 external_metrics_->Start();
1949 } 1850 }
1950 #endif 1851 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698