diff --git a/metricsd/Android.mk b/metricsd/Android.mk index 63bc7b2c7..c35f4e868 100644 --- a/metricsd/Android.mk +++ b/metricsd/Android.mk @@ -30,6 +30,7 @@ metrics_client_sources := \ metrics_client.cc metrics_daemon_sources := \ + collectors/disk_usage_collector.cc \ metrics_daemon.cc \ metrics_daemon_main.cc \ persistent_integer.cc \ @@ -43,6 +44,7 @@ metrics_daemon_sources := \ serialization/serialization_utils.cc metrics_tests_sources := \ + collectors/disk_usage_collector.cc \ metrics_daemon.cc \ metrics_daemon_test.cc \ metrics_library_test.cc \ diff --git a/metricsd/collectors/disk_usage_collector.cc b/metricsd/collectors/disk_usage_collector.cc new file mode 100644 index 000000000..5ab51fb5d --- /dev/null +++ b/metricsd/collectors/disk_usage_collector.cc @@ -0,0 +1,75 @@ +/* + * 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/disk_usage_collector.h" + +#include +#include +#include +#include + +#include "metrics/metrics_library.h" + +namespace { + +const char kDiskUsageMB[] = "Platform.DataPartitionUsed.MB"; +const char kDiskUsagePercent[] = "Platform.DataPartitionUsed.Percent"; +const char kDataPartitionPath[] = "/data"; + +// Collect every 15 minutes. +const int kDiskUsageCollectorIntervalSeconds = 900; + +} // namespace + +DiskUsageCollector::DiskUsageCollector( + MetricsLibraryInterface* metrics_library) { + collect_interval_ = base::TimeDelta::FromSeconds( + kDiskUsageCollectorIntervalSeconds); + CHECK(metrics_library); + metrics_lib_ = metrics_library; +} + +void DiskUsageCollector::Collect() { + struct statvfs buf; + int result = statvfs(kDataPartitionPath, &buf); + if (result != 0) { + PLOG(ERROR) << "Failed to check the available space in " + << kDataPartitionPath; + return; + } + + unsigned long total_space = buf.f_blocks * buf.f_bsize; + unsigned long used_space = (buf.f_blocks - buf.f_bfree) * buf.f_bsize; + int percent_used = (used_space * 100) / total_space; + + metrics_lib_->SendToUMA(kDiskUsageMB, + used_space / (1024 * 1024), + 0, + 1024, // up to 1 GB. + 100); + metrics_lib_->SendEnumToUMA(kDiskUsagePercent, percent_used, 101); +} + +void DiskUsageCollector::CollectCallback() { + Collect(); + Schedule(); +} + +void DiskUsageCollector::Schedule() { + base::MessageLoop::current()->PostDelayedTask(FROM_HERE, + base::Bind(&DiskUsageCollector::CollectCallback, base::Unretained(this)), + collect_interval_); +} diff --git a/metricsd/collectors/disk_usage_collector.h b/metricsd/collectors/disk_usage_collector.h new file mode 100644 index 000000000..c1d45466f --- /dev/null +++ b/metricsd/collectors/disk_usage_collector.h @@ -0,0 +1,42 @@ +/* + * 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_DISK_USAGE_COLLECTOR_H_ +#define METRICSD_COLLECTORS_DISK_USAGE_COLLECTOR_H_ + +#include + +#include "metrics/metrics_library.h" + +class DiskUsageCollector { + public: + DiskUsageCollector(MetricsLibraryInterface* metrics_library); + + // Schedule the next collection. + void Schedule(); + + // Callback used by the main loop. + void CollectCallback(); + + // Collect the disk usage statistics and report them. + void Collect(); + + private: + base::TimeDelta collect_interval_; + MetricsLibraryInterface* metrics_lib_; +}; + +#endif // METRICSD_COLLECTORS_DISK_USAGE_COLLECTOR_H_ diff --git a/metricsd/metrics_daemon.cc b/metricsd/metrics_daemon.cc index f399c55a8..b63be4694 100644 --- a/metricsd/metrics_daemon.cc +++ b/metricsd/metrics_daemon.cc @@ -278,6 +278,7 @@ void MetricsDaemon::Init(bool testing, diskstats_path_ = diskstats_path; scaling_max_freq_path_ = scaling_max_freq_path; cpuinfo_max_freq_path_ = cpuinfo_max_freq_path; + disk_usage_collector_.reset(new DiskUsageCollector(metrics_lib_)); // If testing, initialize Stats Reporter without connecting DBus if (testing_) @@ -492,6 +493,7 @@ bool MetricsDaemon::CheckSystemCrash(const string& crash_file) { } void MetricsDaemon::StatsReporterInit() { + disk_usage_collector_->Schedule(); DiskStatsReadStats(&read_sectors_, &write_sectors_); VmStatsReadStats(&vmstats_); // The first time around just run the long stat, so we don't delay boot. diff --git a/metricsd/metrics_daemon.h b/metricsd/metrics_daemon.h index fbb871ec1..eaa82192b 100644 --- a/metricsd/metrics_daemon.h +++ b/metricsd/metrics_daemon.h @@ -29,6 +29,7 @@ #include #include // for FRIEND_TEST +#include "collectors/disk_usage_collector.h" #include "metrics/metrics_library.h" #include "persistent_integer.h" #include "uploader/upload_service.h" @@ -327,6 +328,7 @@ class MetricsDaemon : public chromeos::DBusDaemon { scoped_ptr kernel_crashes_version_count_; scoped_ptr unclean_shutdowns_daily_count_; scoped_ptr unclean_shutdowns_weekly_count_; + scoped_ptr disk_usage_collector_; std::string diskstats_path_; std::string scaling_max_freq_path_;