OLD | NEW |
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 #include "chrome/browser/browser_process.h" | 174 #include "chrome/browser/browser_process.h" |
175 #include "chrome/browser/load_notification_details.h" | 175 #include "chrome/browser/load_notification_details.h" |
176 #include "chrome/browser/memory_details.h" | 176 #include "chrome/browser/memory_details.h" |
177 #include "chrome/browser/plugin_service.h" | 177 #include "chrome/browser/plugin_service.h" |
178 #include "chrome/browser/profile.h" | 178 #include "chrome/browser/profile.h" |
179 #include "chrome/browser/renderer_host/render_process_host.h" | 179 #include "chrome/browser/renderer_host/render_process_host.h" |
180 #include "chrome/browser/search_engines/template_url.h" | 180 #include "chrome/browser/search_engines/template_url.h" |
181 #include "chrome/browser/search_engines/template_url_model.h" | 181 #include "chrome/browser/search_engines/template_url_model.h" |
182 #include "chrome/common/child_process_info.h" | 182 #include "chrome/common/child_process_info.h" |
183 #include "chrome/common/chrome_paths.h" | 183 #include "chrome/common/chrome_paths.h" |
| 184 #include "chrome/common/histogram_synchronizer.h" |
184 #include "chrome/common/libxml_utils.h" | 185 #include "chrome/common/libxml_utils.h" |
185 #include "chrome/common/notification_service.h" | 186 #include "chrome/common/notification_service.h" |
186 #include "chrome/common/pref_names.h" | 187 #include "chrome/common/pref_names.h" |
187 #include "chrome/common/pref_service.h" | 188 #include "chrome/common/pref_service.h" |
188 #include "chrome/common/render_messages.h" | 189 #include "chrome/common/render_messages.h" |
189 #include "googleurl/src/gurl.h" | 190 #include "googleurl/src/gurl.h" |
190 #include "net/base/load_flags.h" | 191 #include "net/base/load_flags.h" |
191 #include "third_party/bzip2/bzlib.h" | 192 #include "third_party/bzip2/bzlib.h" |
192 | 193 |
193 #if defined(OS_POSIX) | 194 #if defined(OS_POSIX) |
194 // TODO(port): Move these headers above as they are ported. | 195 // TODO(port): Move these headers above as they are ported. |
195 #include "chrome/common/temp_scaffolding_stubs.h" | 196 #include "chrome/common/temp_scaffolding_stubs.h" |
196 #else | 197 #else |
197 #include "chrome/installer/util/browser_distribution.h" | 198 #include "chrome/installer/util/browser_distribution.h" |
198 #include "chrome/installer/util/google_update_settings.h" | 199 #include "chrome/installer/util/google_update_settings.h" |
199 #endif | 200 #endif |
200 | 201 |
201 using base::Time; | 202 using base::Time; |
202 using base::TimeDelta; | 203 using base::TimeDelta; |
203 | 204 |
204 // Check to see that we're being called on only one thread. | 205 // Check to see that we're being called on only one thread. |
205 static bool IsSingleThreaded(); | 206 static bool IsSingleThreaded(); |
206 | 207 |
207 static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2"; | 208 static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2"; |
208 | 209 |
209 // The delay, in seconds, after startup before sending the first log message. | 210 // The delay, in seconds, after startup before sending the first log message. |
210 static const int kInitialInterlogDuration = 60; // one minute | 211 static const int kInitialInterlogDuration = 60; // one minute |
211 | 212 |
| 213 // This specifies the amount of time to wait for all renderers to send their |
| 214 // data. |
| 215 static const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds. |
| 216 |
212 // The default maximum number of events in a log uploaded to the UMA server. | 217 // The default maximum number of events in a log uploaded to the UMA server. |
213 static const int kInitialEventLimit = 2400; | 218 static const int kInitialEventLimit = 2400; |
214 | 219 |
215 // If an upload fails, and the transmission was over this byte count, then we | 220 // If an upload fails, and the transmission was over this byte count, then we |
216 // will discard the log, and not try to retransmit it. We also don't persist | 221 // will discard the log, and not try to retransmit it. We also don't persist |
217 // the log to the prefs for transmission during the next chrome session if this | 222 // the log to the prefs for transmission during the next chrome session if this |
218 // limit is exceeded. | 223 // limit is exceeded. |
219 static const int kUploadLogAvoidRetransmitSize = 50000; | 224 static const int kUploadLogAvoidRetransmitSize = 50000; |
220 | 225 |
221 // When we have logs from previous Chrome sessions to send, how long should we | 226 // When we have logs from previous Chrome sessions to send, how long should we |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 // If timer_pending is true because the fetch is waiting for a response, | 879 // If timer_pending is true because the fetch is waiting for a response, |
875 // we return for now and let the response handler start the timer. | 880 // we return for now and let the response handler start the timer. |
876 if (timer_pending_) | 881 if (timer_pending_) |
877 return; | 882 return; |
878 | 883 |
879 // Before starting the timer, set timer_pending_ to true. | 884 // Before starting the timer, set timer_pending_ to true. |
880 timer_pending_ = true; | 885 timer_pending_ = true; |
881 | 886 |
882 // Right before the UMA transmission gets started, there's one more thing we'd | 887 // Right before the UMA transmission gets started, there's one more thing we'd |
883 // like to record: the histogram of memory usage, so we spawn a task to | 888 // like to record: the histogram of memory usage, so we spawn a task to |
884 // collect the memory details and when that task is finished, we arrange for | 889 // collect the memory details and when that task is finished, it will call |
885 // TryToStartTransmission to take over. | 890 // OnMemoryDetailCollectionDone, which will call HistogramSynchronization to |
| 891 // collect histograms from all renderers and then we will call |
| 892 // OnHistogramSynchronizationDone to continue processing. |
886 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 893 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
887 log_sender_factory_. | 894 log_sender_factory_. |
888 NewRunnableMethod(&MetricsService::CollectMemoryDetails), | 895 NewRunnableMethod(&MetricsService::LogTransmissionTimerDone), |
889 static_cast<int>(interlog_duration_.InMilliseconds())); | 896 static_cast<int>(interlog_duration_.InMilliseconds())); |
890 } | 897 } |
891 | 898 |
892 void MetricsService::TryToStartTransmission() { | 899 void MetricsService::LogTransmissionTimerDone() { |
| 900 Task* task = log_sender_factory_. |
| 901 NewRunnableMethod(&MetricsService::OnMemoryDetailCollectionDone); |
| 902 |
| 903 MetricsMemoryDetails* details = new MetricsMemoryDetails(task); |
| 904 details->StartFetch(); |
| 905 |
| 906 // Collect WebCore cache information to put into a histogram. |
| 907 for (RenderProcessHost::iterator it = RenderProcessHost::begin(); |
| 908 it != RenderProcessHost::end(); ++it) { |
| 909 it->second->Send(new ViewMsg_GetCacheResourceStats()); |
| 910 } |
| 911 } |
| 912 |
| 913 void MetricsService::OnMemoryDetailCollectionDone() { |
| 914 DCHECK(IsSingleThreaded()); |
| 915 |
| 916 // HistogramSynchronizer will Collect histograms from all renderers and it |
| 917 // will call OnHistogramSynchronizationDone (if wait time elapses before it |
| 918 // heard from all renderers, then also it will call |
| 919 // OnHistogramSynchronizationDone). |
| 920 |
| 921 // Create a callback_task for OnHistogramSynchronizationDone. |
| 922 Task* callback_task = log_sender_factory_.NewRunnableMethod( |
| 923 &MetricsService::OnHistogramSynchronizationDone); |
| 924 |
| 925 // Set up the callback to task to call after we receive histograms from all |
| 926 // renderer processes. Wait time specifies how long to wait before absolutely |
| 927 // calling us back on the task. |
| 928 HistogramSynchronizer::FetchRendererHistogramsAsynchronously( |
| 929 MessageLoop::current(), callback_task, |
| 930 kMaxHistogramGatheringWaitDuration); |
| 931 } |
| 932 |
| 933 void MetricsService::OnHistogramSynchronizationDone() { |
893 DCHECK(IsSingleThreaded()); | 934 DCHECK(IsSingleThreaded()); |
894 | 935 |
895 // This function should only be called via timer, so timer_pending_ | 936 // This function should only be called via timer, so timer_pending_ |
896 // should be true. | 937 // should be true. |
897 DCHECK(timer_pending_); | 938 DCHECK(timer_pending_); |
898 timer_pending_ = false; | 939 timer_pending_ = false; |
899 | 940 |
900 DCHECK(!current_fetch_.get()); | 941 DCHECK(!current_fetch_.get()); |
901 | 942 |
902 // If we're getting no notifications, then the log won't have much in it, and | 943 // If we're getting no notifications, then the log won't have much in it, and |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 case SEND_OLD_INITIAL_LOGS: | 1069 case SEND_OLD_INITIAL_LOGS: |
1029 case SENDING_OLD_LOGS: | 1070 case SENDING_OLD_LOGS: |
1030 return true; | 1071 return true; |
1031 | 1072 |
1032 case SENDING_CURRENT_LOGS: | 1073 case SENDING_CURRENT_LOGS: |
1033 default: | 1074 default: |
1034 return false; | 1075 return false; |
1035 } | 1076 } |
1036 } | 1077 } |
1037 | 1078 |
1038 void MetricsService::CollectMemoryDetails() { | |
1039 Task* task = log_sender_factory_. | |
1040 NewRunnableMethod(&MetricsService::TryToStartTransmission); | |
1041 MetricsMemoryDetails* details = new MetricsMemoryDetails(task); | |
1042 details->StartFetch(); | |
1043 | |
1044 // Collect WebCore cache information to put into a histogram. | |
1045 for (RenderProcessHost::iterator it = RenderProcessHost::begin(); | |
1046 it != RenderProcessHost::end(); ++it) { | |
1047 it->second->Send(new ViewMsg_GetCacheResourceStats()); | |
1048 } | |
1049 } | |
1050 | |
1051 void MetricsService::PrepareInitialLog() { | 1079 void MetricsService::PrepareInitialLog() { |
1052 DCHECK(state_ == PLUGIN_LIST_ARRIVED); | 1080 DCHECK(state_ == PLUGIN_LIST_ARRIVED); |
1053 std::vector<WebPluginInfo> plugins; | 1081 std::vector<WebPluginInfo> plugins; |
1054 PluginService::GetInstance()->GetPlugins(false, &plugins); | 1082 PluginService::GetInstance()->GetPlugins(false, &plugins); |
1055 | 1083 |
1056 MetricsLog* log = new MetricsLog(client_id_, session_id_); | 1084 MetricsLog* log = new MetricsLog(client_id_, session_id_); |
1057 log->RecordEnvironment(plugins, profile_dictionary_.get()); | 1085 log->RecordEnvironment(plugins, profile_dictionary_.get()); |
1058 | 1086 |
1059 // Histograms only get written to current_log_, so setup for the write. | 1087 // Histograms only get written to current_log_, so setup for the write. |
1060 MetricsLog* save_log = current_log_; | 1088 MetricsLog* save_log = current_log_; |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1774 pref->SetBoolean(path, value); | 1802 pref->SetBoolean(path, value); |
1775 RecordCurrentState(pref); | 1803 RecordCurrentState(pref); |
1776 } | 1804 } |
1777 | 1805 |
1778 void MetricsService::RecordCurrentState(PrefService* pref) { | 1806 void MetricsService::RecordCurrentState(PrefService* pref) { |
1779 pref->SetInt64(prefs::kStabilityLastTimestampSec, Time::Now().ToTimeT()); | 1807 pref->SetInt64(prefs::kStabilityLastTimestampSec, Time::Now().ToTimeT()); |
1780 | 1808 |
1781 RecordPluginChanges(pref); | 1809 RecordPluginChanges(pref); |
1782 } | 1810 } |
1783 | 1811 |
1784 void MetricsService::CollectRendererHistograms() { | |
1785 for (RenderProcessHost::iterator it = RenderProcessHost::begin(); | |
1786 it != RenderProcessHost::end(); ++it) { | |
1787 it->second->Send(new ViewMsg_GetRendererHistograms()); | |
1788 } | |
1789 } | |
1790 | |
1791 void MetricsService::RecordCurrentHistograms() { | 1812 void MetricsService::RecordCurrentHistograms() { |
1792 DCHECK(current_log_); | 1813 DCHECK(current_log_); |
1793 | 1814 |
1794 CollectRendererHistograms(); | |
1795 | |
1796 // TODO(raman): Delay the metrics collection activities until we get all the | |
1797 // updates from the renderers, or we time out (1 second? 3 seconds?). | |
1798 | |
1799 StatisticsRecorder::Histograms histograms; | 1815 StatisticsRecorder::Histograms histograms; |
1800 StatisticsRecorder::GetHistograms(&histograms); | 1816 StatisticsRecorder::GetHistograms(&histograms); |
1801 for (StatisticsRecorder::Histograms::iterator it = histograms.begin(); | 1817 for (StatisticsRecorder::Histograms::iterator it = histograms.begin(); |
1802 histograms.end() != it; | 1818 histograms.end() != it; |
1803 ++it) { | 1819 ++it) { |
1804 if ((*it)->flags() & kUmaTargetedHistogramFlag) | 1820 if ((*it)->flags() & kUmaTargetedHistogramFlag) |
1805 // TODO(petersont): Only record historgrams if they are not precluded by | 1821 // TODO(petersont): Only record historgrams if they are not precluded by |
1806 // the UMA response data. | 1822 // the UMA response data. |
1807 // Bug http://code.google.com/p/chromium/issues/detail?id=2739. | 1823 // Bug http://code.google.com/p/chromium/issues/detail?id=2739. |
1808 RecordHistogram(**it); | 1824 RecordHistogram(**it); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1862 L"." + key; | 1878 L"." + key; |
1863 prof_prefs->SetInteger(pref_key.c_str(), value); | 1879 prof_prefs->SetInteger(pref_key.c_str(), value); |
1864 } | 1880 } |
1865 | 1881 |
1866 static bool IsSingleThreaded() { | 1882 static bool IsSingleThreaded() { |
1867 static PlatformThreadId thread_id = 0; | 1883 static PlatformThreadId thread_id = 0; |
1868 if (!thread_id) | 1884 if (!thread_id) |
1869 thread_id = PlatformThread::CurrentId(); | 1885 thread_id = PlatformThread::CurrentId(); |
1870 return PlatformThread::CurrentId() == thread_id; | 1886 return PlatformThread::CurrentId() == thread_id; |
1871 } | 1887 } |
OLD | NEW |