Loading metricsd/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ metrics_client_sources := \ metrics_daemon_common := \ collectors/averaged_statistics_collector.cc \ collectors/cpu_usage_collector.cc \ collectors/disk_usage_collector.cc \ metrics_daemon.cc \ persistent_integer.cc \ Loading @@ -41,6 +42,7 @@ metrics_daemon_common := \ metrics_tests_sources := \ collectors/averaged_statistics_collector_test.cc \ collectors/cpu_usage_collector_test.cc \ metrics_daemon_test.cc \ metrics_library_test.cc \ persistent_integer_test.cc \ Loading metricsd/collectors/cpu_usage_collector.cc 0 → 100644 +125 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "collectors/cpu_usage_collector.h" #include <base/bind.h> #include <base/files/file_path.h> #include <base/files/file_util.h> #include <base/message_loop/message_loop.h> #include <base/strings/string_number_conversions.h> #include <base/strings/string_split.h> #include <base/strings/string_util.h> #include <base/sys_info.h> #include "metrics/metrics_library.h" namespace { const char kCpuUsagePercent[] = "Platform.CpuUsage.Percent"; const char kMetricsProcStatFileName[] = "/proc/stat"; const int kMetricsProcStatFirstLineItemsCount = 11; // Collect every minute. const int kCollectionIntervalSecs = 60; } // namespace using base::TimeDelta; CpuUsageCollector::CpuUsageCollector(MetricsLibraryInterface* metrics_library) { CHECK(metrics_library); metrics_lib_ = metrics_library; collect_interval_ = TimeDelta::FromSeconds(kCollectionIntervalSecs); } void CpuUsageCollector::Init() { num_cpu_ = base::SysInfo::NumberOfProcessors(); // Get ticks per second (HZ) on this system. // Sysconf cannot fail, so no sanity checks are needed. ticks_per_second_ = sysconf(_SC_CLK_TCK); CHECK_GT(ticks_per_second_, uint64_t(0)) << "Number of ticks per seconds should be positive."; latest_cpu_use_ = GetCumulativeCpuUse(); } void CpuUsageCollector::CollectCallback() { Collect(); Schedule(); } void CpuUsageCollector::Schedule() { base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(&CpuUsageCollector::CollectCallback, base::Unretained(this)), collect_interval_); } void CpuUsageCollector::Collect() { TimeDelta cpu_use = GetCumulativeCpuUse(); TimeDelta diff_per_cpu = (cpu_use - latest_cpu_use_) / num_cpu_; latest_cpu_use_ = cpu_use; // Report the cpu usage as a percentage of the total cpu usage possible. int percent_use = diff_per_cpu.InMilliseconds() * 100 / (kCollectionIntervalSecs * 1000); metrics_lib_->SendEnumToUMA(kCpuUsagePercent, percent_use, 101); } TimeDelta CpuUsageCollector::GetCumulativeCpuUse() { base::FilePath proc_stat_path(kMetricsProcStatFileName); std::string proc_stat_string; if (!base::ReadFileToString(proc_stat_path, &proc_stat_string)) { LOG(WARNING) << "cannot open " << kMetricsProcStatFileName; return TimeDelta(); } uint64_t user_ticks, user_nice_ticks, system_ticks; if (!ParseProcStat(proc_stat_string, &user_ticks, &user_nice_ticks, &system_ticks)) { return TimeDelta(); } uint64_t total = user_ticks + user_nice_ticks + system_ticks; return TimeDelta::FromMicroseconds( total * 1000 * 1000 / ticks_per_second_); } bool CpuUsageCollector::ParseProcStat(const std::string& stat_content, uint64_t *user_ticks, uint64_t *user_nice_ticks, uint64_t *system_ticks) { std::vector<std::string> proc_stat_lines; base::SplitString(stat_content, '\n', &proc_stat_lines); if (proc_stat_lines.empty()) { LOG(WARNING) << "No lines found in " << kMetricsProcStatFileName; return false; } std::vector<std::string> proc_stat_totals; base::SplitStringAlongWhitespace(proc_stat_lines[0], &proc_stat_totals); if (proc_stat_totals.size() != kMetricsProcStatFirstLineItemsCount || proc_stat_totals[0] != "cpu" || !base::StringToUint64(proc_stat_totals[1], user_ticks) || !base::StringToUint64(proc_stat_totals[2], user_nice_ticks) || !base::StringToUint64(proc_stat_totals[3], system_ticks)) { LOG(WARNING) << "cannot parse first line: " << proc_stat_lines[0]; return false; } return true; } metricsd/collectors/cpu_usage_collector.h 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef METRICSD_COLLECTORS_CPU_USAGE_COLLECTOR_H_ #define METRICSD_COLLECTORS_CPU_USAGE_COLLECTOR_H_ #include <base/time/time.h> #include "metrics/metrics_library.h" class CpuUsageCollector { public: CpuUsageCollector(MetricsLibraryInterface* metrics_library); // Initialize this collector's state. void Init(); // Schedule a collection interval. void Schedule(); // Callback called at the end of the collection interval. void CollectCallback(); // Measure the cpu use and report it. void Collect(); // Gets the current cumulated Cpu usage. base::TimeDelta GetCumulativeCpuUse(); private: FRIEND_TEST(CpuUsageTest, ParseProcStat); bool ParseProcStat(const std::string& stat_content, uint64_t *user_ticks, uint64_t *user_nice_ticks, uint64_t *system_ticks); int num_cpu_; uint32_t ticks_per_second_; base::TimeDelta collect_interval_; base::TimeDelta latest_cpu_use_; MetricsLibraryInterface* metrics_lib_; }; #endif // METRICSD_COLLECTORS_CPU_USAGE_COLLECTOR_H_ metricsd/collectors/cpu_usage_collector_test.cc 0 → 100644 +50 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <gtest/gtest.h> #include "collectors/cpu_usage_collector.h" #include "metrics/metrics_library_mock.h" TEST(CpuUsageTest, ParseProcStat) { MetricsLibraryMock metrics_lib_mock; CpuUsageCollector collector(&metrics_lib_mock); std::vector<std::string> invalid_contents = { "", // First line does not start with cpu. "spu 17191 11 36579 151118 289 0 2 0 0 0\n" "cpu0 1564 2 866 48650 68 0 2 0 0 0\n" "cpu1 14299 0 35116 1844 81 0 0 0 0 0\n", // One of the field is not a number. "cpu a17191 11 36579 151118 289 0 2 0 0 0", // To many numbers in the first line. "cpu 17191 11 36579 151118 289 0 2 0 0 0 102" }; uint64_t user, nice, system; for (int i = 0; i < invalid_contents.size(); i++) { ASSERT_FALSE(collector.ParseProcStat(invalid_contents[i], &user, &nice, &system)); } ASSERT_TRUE(collector.ParseProcStat( std::string("cpu 17191 11 36579 151118 289 0 2 0 0 0"), &user, &nice, &system)); ASSERT_EQ(17191, user); ASSERT_EQ(11, nice); ASSERT_EQ(36579, system); } metricsd/metrics_daemon.cc +10 −57 Original line number Diff line number Diff line Loading @@ -71,10 +71,8 @@ const char kUncleanShutdownDetectedFile[] = const int kMetricMeminfoInterval = 30; // seconds const char kMetricsProcStatFileName[] = "/proc/stat"; const char kMeminfoFileName[] = "/proc/meminfo"; const char kVmStatFileName[] = "/proc/vmstat"; const int kMetricsProcStatFirstLineItemsCount = 11; // Thermal CPU throttling. Loading Loading @@ -103,9 +101,7 @@ static const int kMemuseIntervals[] = { MetricsDaemon::MetricsDaemon() : memuse_final_time_(0), memuse_interval_index_(0), ticks_per_second_(0), latest_cpu_use_ticks_(0) {} memuse_interval_index_(0) {} MetricsDaemon::~MetricsDaemon() { } Loading Loading @@ -188,10 +184,6 @@ void MetricsDaemon::Init(bool testing, upload_interval_ = upload_interval; server_ = server; // Get ticks per second (HZ) on this system. // Sysconf cannot fail, so no sanity checks are needed. ticks_per_second_ = sysconf(_SC_CLK_TCK); daily_active_use_.reset( new PersistentInteger("Platform.UseTime.PerDay")); version_cumulative_active_use_.reset( Loading Loading @@ -235,6 +227,7 @@ void MetricsDaemon::Init(bool testing, averaged_stats_collector_.reset( new AveragedStatisticsCollector(metrics_lib_, diskstats_path, kVmStatFileName)); cpu_usage_collector_.reset(new CpuUsageCollector(metrics_lib_)); } int MetricsDaemon::OnInit() { Loading Loading @@ -290,6 +283,7 @@ int MetricsDaemon::OnInit() { base::Bind(&MetricsDaemon::OnDisableMetrics, base::Unretained(this))); } latest_cpu_use_microseconds_ = cpu_usage_collector_->GetCumulativeCpuUse(); base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(&MetricsDaemon::HandleUpdateStatsTimeout, base::Unretained(this)), Loading Loading @@ -404,53 +398,6 @@ DBusHandlerResult MetricsDaemon::MessageFilter(DBusConnection* connection, return DBUS_HANDLER_RESULT_HANDLED; } // One might argue that parts of this should go into // chromium/src/base/sys_info_chromeos.c instead, but put it here for now. TimeDelta MetricsDaemon::GetIncrementalCpuUse() { FilePath proc_stat_path = FilePath(kMetricsProcStatFileName); std::string proc_stat_string; if (!base::ReadFileToString(proc_stat_path, &proc_stat_string)) { LOG(WARNING) << "cannot open " << kMetricsProcStatFileName; return TimeDelta(); } std::vector<std::string> proc_stat_lines; base::SplitString(proc_stat_string, '\n', &proc_stat_lines); if (proc_stat_lines.empty()) { LOG(WARNING) << "cannot parse " << kMetricsProcStatFileName << ": " << proc_stat_string; return TimeDelta(); } std::vector<std::string> proc_stat_totals; base::SplitStringAlongWhitespace(proc_stat_lines[0], &proc_stat_totals); uint64_t user_ticks, user_nice_ticks, system_ticks; if (proc_stat_totals.size() != kMetricsProcStatFirstLineItemsCount || proc_stat_totals[0] != "cpu" || !base::StringToUint64(proc_stat_totals[1], &user_ticks) || !base::StringToUint64(proc_stat_totals[2], &user_nice_ticks) || !base::StringToUint64(proc_stat_totals[3], &system_ticks)) { LOG(WARNING) << "cannot parse first line: " << proc_stat_lines[0]; return TimeDelta(base::TimeDelta::FromSeconds(0)); } uint64_t total_cpu_use_ticks = user_ticks + user_nice_ticks + system_ticks; // Sanity check. if (total_cpu_use_ticks < latest_cpu_use_ticks_) { LOG(WARNING) << "CPU time decreasing from " << latest_cpu_use_ticks_ << " to " << total_cpu_use_ticks; return TimeDelta(); } uint64_t diff = total_cpu_use_ticks - latest_cpu_use_ticks_; latest_cpu_use_ticks_ = total_cpu_use_ticks; // Use microseconds to avoid significant truncations. return base::TimeDelta::FromMicroseconds( diff * 1000 * 1000 / ticks_per_second_); } void MetricsDaemon::ProcessUserCrash() { // Counts the active time up to now. UpdateStats(TimeTicks::Now(), Time::Now()); Loading Loading @@ -506,6 +453,9 @@ bool MetricsDaemon::CheckSystemCrash(const string& crash_file) { void MetricsDaemon::StatsReporterInit() { disk_usage_collector_->Schedule(); cpu_usage_collector_->Init(); cpu_usage_collector_->Schedule(); // Don't start a collection cycle during the first run to avoid delaying the // boot. averaged_stats_collector_->ScheduleWait(); Loading Loading @@ -910,7 +860,10 @@ void MetricsDaemon::UpdateStats(TimeTicks now_ticks, version_cumulative_active_use_->Add(elapsed_seconds); user_crash_interval_->Add(elapsed_seconds); kernel_crash_interval_->Add(elapsed_seconds); version_cumulative_cpu_use_->Add(GetIncrementalCpuUse().InMilliseconds()); TimeDelta cpu_use = cpu_usage_collector_->GetCumulativeCpuUse(); version_cumulative_cpu_use_->Add( (cpu_use - latest_cpu_use_microseconds_).InMilliseconds()); latest_cpu_use_microseconds_ = cpu_use; last_update_stats_time_ = now_ticks; const TimeDelta since_epoch = now_wall_time - Time::UnixEpoch(); Loading Loading
metricsd/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ metrics_client_sources := \ metrics_daemon_common := \ collectors/averaged_statistics_collector.cc \ collectors/cpu_usage_collector.cc \ collectors/disk_usage_collector.cc \ metrics_daemon.cc \ persistent_integer.cc \ Loading @@ -41,6 +42,7 @@ metrics_daemon_common := \ metrics_tests_sources := \ collectors/averaged_statistics_collector_test.cc \ collectors/cpu_usage_collector_test.cc \ metrics_daemon_test.cc \ metrics_library_test.cc \ persistent_integer_test.cc \ Loading
metricsd/collectors/cpu_usage_collector.cc 0 → 100644 +125 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "collectors/cpu_usage_collector.h" #include <base/bind.h> #include <base/files/file_path.h> #include <base/files/file_util.h> #include <base/message_loop/message_loop.h> #include <base/strings/string_number_conversions.h> #include <base/strings/string_split.h> #include <base/strings/string_util.h> #include <base/sys_info.h> #include "metrics/metrics_library.h" namespace { const char kCpuUsagePercent[] = "Platform.CpuUsage.Percent"; const char kMetricsProcStatFileName[] = "/proc/stat"; const int kMetricsProcStatFirstLineItemsCount = 11; // Collect every minute. const int kCollectionIntervalSecs = 60; } // namespace using base::TimeDelta; CpuUsageCollector::CpuUsageCollector(MetricsLibraryInterface* metrics_library) { CHECK(metrics_library); metrics_lib_ = metrics_library; collect_interval_ = TimeDelta::FromSeconds(kCollectionIntervalSecs); } void CpuUsageCollector::Init() { num_cpu_ = base::SysInfo::NumberOfProcessors(); // Get ticks per second (HZ) on this system. // Sysconf cannot fail, so no sanity checks are needed. ticks_per_second_ = sysconf(_SC_CLK_TCK); CHECK_GT(ticks_per_second_, uint64_t(0)) << "Number of ticks per seconds should be positive."; latest_cpu_use_ = GetCumulativeCpuUse(); } void CpuUsageCollector::CollectCallback() { Collect(); Schedule(); } void CpuUsageCollector::Schedule() { base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(&CpuUsageCollector::CollectCallback, base::Unretained(this)), collect_interval_); } void CpuUsageCollector::Collect() { TimeDelta cpu_use = GetCumulativeCpuUse(); TimeDelta diff_per_cpu = (cpu_use - latest_cpu_use_) / num_cpu_; latest_cpu_use_ = cpu_use; // Report the cpu usage as a percentage of the total cpu usage possible. int percent_use = diff_per_cpu.InMilliseconds() * 100 / (kCollectionIntervalSecs * 1000); metrics_lib_->SendEnumToUMA(kCpuUsagePercent, percent_use, 101); } TimeDelta CpuUsageCollector::GetCumulativeCpuUse() { base::FilePath proc_stat_path(kMetricsProcStatFileName); std::string proc_stat_string; if (!base::ReadFileToString(proc_stat_path, &proc_stat_string)) { LOG(WARNING) << "cannot open " << kMetricsProcStatFileName; return TimeDelta(); } uint64_t user_ticks, user_nice_ticks, system_ticks; if (!ParseProcStat(proc_stat_string, &user_ticks, &user_nice_ticks, &system_ticks)) { return TimeDelta(); } uint64_t total = user_ticks + user_nice_ticks + system_ticks; return TimeDelta::FromMicroseconds( total * 1000 * 1000 / ticks_per_second_); } bool CpuUsageCollector::ParseProcStat(const std::string& stat_content, uint64_t *user_ticks, uint64_t *user_nice_ticks, uint64_t *system_ticks) { std::vector<std::string> proc_stat_lines; base::SplitString(stat_content, '\n', &proc_stat_lines); if (proc_stat_lines.empty()) { LOG(WARNING) << "No lines found in " << kMetricsProcStatFileName; return false; } std::vector<std::string> proc_stat_totals; base::SplitStringAlongWhitespace(proc_stat_lines[0], &proc_stat_totals); if (proc_stat_totals.size() != kMetricsProcStatFirstLineItemsCount || proc_stat_totals[0] != "cpu" || !base::StringToUint64(proc_stat_totals[1], user_ticks) || !base::StringToUint64(proc_stat_totals[2], user_nice_ticks) || !base::StringToUint64(proc_stat_totals[3], system_ticks)) { LOG(WARNING) << "cannot parse first line: " << proc_stat_lines[0]; return false; } return true; }
metricsd/collectors/cpu_usage_collector.h 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef METRICSD_COLLECTORS_CPU_USAGE_COLLECTOR_H_ #define METRICSD_COLLECTORS_CPU_USAGE_COLLECTOR_H_ #include <base/time/time.h> #include "metrics/metrics_library.h" class CpuUsageCollector { public: CpuUsageCollector(MetricsLibraryInterface* metrics_library); // Initialize this collector's state. void Init(); // Schedule a collection interval. void Schedule(); // Callback called at the end of the collection interval. void CollectCallback(); // Measure the cpu use and report it. void Collect(); // Gets the current cumulated Cpu usage. base::TimeDelta GetCumulativeCpuUse(); private: FRIEND_TEST(CpuUsageTest, ParseProcStat); bool ParseProcStat(const std::string& stat_content, uint64_t *user_ticks, uint64_t *user_nice_ticks, uint64_t *system_ticks); int num_cpu_; uint32_t ticks_per_second_; base::TimeDelta collect_interval_; base::TimeDelta latest_cpu_use_; MetricsLibraryInterface* metrics_lib_; }; #endif // METRICSD_COLLECTORS_CPU_USAGE_COLLECTOR_H_
metricsd/collectors/cpu_usage_collector_test.cc 0 → 100644 +50 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <gtest/gtest.h> #include "collectors/cpu_usage_collector.h" #include "metrics/metrics_library_mock.h" TEST(CpuUsageTest, ParseProcStat) { MetricsLibraryMock metrics_lib_mock; CpuUsageCollector collector(&metrics_lib_mock); std::vector<std::string> invalid_contents = { "", // First line does not start with cpu. "spu 17191 11 36579 151118 289 0 2 0 0 0\n" "cpu0 1564 2 866 48650 68 0 2 0 0 0\n" "cpu1 14299 0 35116 1844 81 0 0 0 0 0\n", // One of the field is not a number. "cpu a17191 11 36579 151118 289 0 2 0 0 0", // To many numbers in the first line. "cpu 17191 11 36579 151118 289 0 2 0 0 0 102" }; uint64_t user, nice, system; for (int i = 0; i < invalid_contents.size(); i++) { ASSERT_FALSE(collector.ParseProcStat(invalid_contents[i], &user, &nice, &system)); } ASSERT_TRUE(collector.ParseProcStat( std::string("cpu 17191 11 36579 151118 289 0 2 0 0 0"), &user, &nice, &system)); ASSERT_EQ(17191, user); ASSERT_EQ(11, nice); ASSERT_EQ(36579, system); }
metricsd/metrics_daemon.cc +10 −57 Original line number Diff line number Diff line Loading @@ -71,10 +71,8 @@ const char kUncleanShutdownDetectedFile[] = const int kMetricMeminfoInterval = 30; // seconds const char kMetricsProcStatFileName[] = "/proc/stat"; const char kMeminfoFileName[] = "/proc/meminfo"; const char kVmStatFileName[] = "/proc/vmstat"; const int kMetricsProcStatFirstLineItemsCount = 11; // Thermal CPU throttling. Loading Loading @@ -103,9 +101,7 @@ static const int kMemuseIntervals[] = { MetricsDaemon::MetricsDaemon() : memuse_final_time_(0), memuse_interval_index_(0), ticks_per_second_(0), latest_cpu_use_ticks_(0) {} memuse_interval_index_(0) {} MetricsDaemon::~MetricsDaemon() { } Loading Loading @@ -188,10 +184,6 @@ void MetricsDaemon::Init(bool testing, upload_interval_ = upload_interval; server_ = server; // Get ticks per second (HZ) on this system. // Sysconf cannot fail, so no sanity checks are needed. ticks_per_second_ = sysconf(_SC_CLK_TCK); daily_active_use_.reset( new PersistentInteger("Platform.UseTime.PerDay")); version_cumulative_active_use_.reset( Loading Loading @@ -235,6 +227,7 @@ void MetricsDaemon::Init(bool testing, averaged_stats_collector_.reset( new AveragedStatisticsCollector(metrics_lib_, diskstats_path, kVmStatFileName)); cpu_usage_collector_.reset(new CpuUsageCollector(metrics_lib_)); } int MetricsDaemon::OnInit() { Loading Loading @@ -290,6 +283,7 @@ int MetricsDaemon::OnInit() { base::Bind(&MetricsDaemon::OnDisableMetrics, base::Unretained(this))); } latest_cpu_use_microseconds_ = cpu_usage_collector_->GetCumulativeCpuUse(); base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(&MetricsDaemon::HandleUpdateStatsTimeout, base::Unretained(this)), Loading Loading @@ -404,53 +398,6 @@ DBusHandlerResult MetricsDaemon::MessageFilter(DBusConnection* connection, return DBUS_HANDLER_RESULT_HANDLED; } // One might argue that parts of this should go into // chromium/src/base/sys_info_chromeos.c instead, but put it here for now. TimeDelta MetricsDaemon::GetIncrementalCpuUse() { FilePath proc_stat_path = FilePath(kMetricsProcStatFileName); std::string proc_stat_string; if (!base::ReadFileToString(proc_stat_path, &proc_stat_string)) { LOG(WARNING) << "cannot open " << kMetricsProcStatFileName; return TimeDelta(); } std::vector<std::string> proc_stat_lines; base::SplitString(proc_stat_string, '\n', &proc_stat_lines); if (proc_stat_lines.empty()) { LOG(WARNING) << "cannot parse " << kMetricsProcStatFileName << ": " << proc_stat_string; return TimeDelta(); } std::vector<std::string> proc_stat_totals; base::SplitStringAlongWhitespace(proc_stat_lines[0], &proc_stat_totals); uint64_t user_ticks, user_nice_ticks, system_ticks; if (proc_stat_totals.size() != kMetricsProcStatFirstLineItemsCount || proc_stat_totals[0] != "cpu" || !base::StringToUint64(proc_stat_totals[1], &user_ticks) || !base::StringToUint64(proc_stat_totals[2], &user_nice_ticks) || !base::StringToUint64(proc_stat_totals[3], &system_ticks)) { LOG(WARNING) << "cannot parse first line: " << proc_stat_lines[0]; return TimeDelta(base::TimeDelta::FromSeconds(0)); } uint64_t total_cpu_use_ticks = user_ticks + user_nice_ticks + system_ticks; // Sanity check. if (total_cpu_use_ticks < latest_cpu_use_ticks_) { LOG(WARNING) << "CPU time decreasing from " << latest_cpu_use_ticks_ << " to " << total_cpu_use_ticks; return TimeDelta(); } uint64_t diff = total_cpu_use_ticks - latest_cpu_use_ticks_; latest_cpu_use_ticks_ = total_cpu_use_ticks; // Use microseconds to avoid significant truncations. return base::TimeDelta::FromMicroseconds( diff * 1000 * 1000 / ticks_per_second_); } void MetricsDaemon::ProcessUserCrash() { // Counts the active time up to now. UpdateStats(TimeTicks::Now(), Time::Now()); Loading Loading @@ -506,6 +453,9 @@ bool MetricsDaemon::CheckSystemCrash(const string& crash_file) { void MetricsDaemon::StatsReporterInit() { disk_usage_collector_->Schedule(); cpu_usage_collector_->Init(); cpu_usage_collector_->Schedule(); // Don't start a collection cycle during the first run to avoid delaying the // boot. averaged_stats_collector_->ScheduleWait(); Loading Loading @@ -910,7 +860,10 @@ void MetricsDaemon::UpdateStats(TimeTicks now_ticks, version_cumulative_active_use_->Add(elapsed_seconds); user_crash_interval_->Add(elapsed_seconds); kernel_crash_interval_->Add(elapsed_seconds); version_cumulative_cpu_use_->Add(GetIncrementalCpuUse().InMilliseconds()); TimeDelta cpu_use = cpu_usage_collector_->GetCumulativeCpuUse(); version_cumulative_cpu_use_->Add( (cpu_use - latest_cpu_use_microseconds_).InMilliseconds()); latest_cpu_use_microseconds_ = cpu_use; last_update_stats_time_ = now_ticks; const TimeDelta since_epoch = now_wall_time - Time::UnixEpoch(); Loading