diff options
3 files changed, 87 insertions, 0 deletions
diff --git a/libraries/collectors-helper/statsd/src/com/android/helpers/CpuUsageHelper.java b/libraries/collectors-helper/statsd/src/com/android/helpers/CpuUsageHelper.java index 2858c7364..231100b67 100644 --- a/libraries/collectors-helper/statsd/src/com/android/helpers/CpuUsageHelper.java +++ b/libraries/collectors-helper/statsd/src/com/android/helpers/CpuUsageHelper.java @@ -25,10 +25,12 @@ import com.android.os.StatsLog.GaugeMetricData; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; +import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; /** * CpuUsageHelper consist of helper methods to set the app @@ -47,12 +49,18 @@ public class CpuUsageHelper implements ICollectorHelper<Long> { private static final String FREQ_INDEX = "freq_index"; private static final String USER_TIME = "user_time"; private static final String SYSTEM_TIME = "system_time"; + private static final String TOTAL_CPU_TIME = "total_cpu_time"; + private static final String CPU_UTILIZATION = "cpu_utilization_average_per_core_percent"; private StatsdHelper mStatsdHelper = new StatsdHelper(); private boolean isPerFreqDisabled; private boolean isPerPkgDisabled; private boolean isTotalPkgDisabled; private boolean isTotalFreqDisabled; + private boolean isCpuUtilizationEnabled; + private long mStartTime; + private long mEndTime; + private Integer mCpuCores = null; @Override public boolean startCollecting() { @@ -62,6 +70,10 @@ public class CpuUsageHelper implements ICollectorHelper<Long> { atomIdList.add(Atom.CPU_TIME_PER_UID_FIELD_NUMBER); atomIdList.add(Atom.CPU_TIME_PER_FREQ_FIELD_NUMBER); + if (isCpuUtilizationEnabled) { + mStartTime = System.currentTimeMillis(); + } + return mStatsdHelper.addGaugeConfig(atomIdList); } @@ -70,6 +82,11 @@ public class CpuUsageHelper implements ICollectorHelper<Long> { Map<String, Long> cpuUsageFinalMap = new HashMap<>(); List<GaugeMetricData> gaugeMetricList = mStatsdHelper.getGaugeMetrics(); + + if (isCpuUtilizationEnabled) { + mEndTime = System.currentTimeMillis(); + } + ListMultimap<String, Long> cpuUsageMap = ArrayListMultimap.create(); for (GaugeMetricData gaugeMetric : gaugeMetricList) { @@ -158,6 +175,18 @@ public class CpuUsageHelper implements ICollectorHelper<Long> { if (!isTotalFreqDisabled) { cpuUsageFinalMap.put(TOTAL_CPU_USAGE_FREQ, totalCpuFreq); } + + // Calculate cpu utilization + if (isCpuUtilizationEnabled) { + long totalCpuTime = (mEndTime - mStartTime) * getCores(); + cpuUsageFinalMap.put(TOTAL_CPU_TIME, totalCpuTime); + if (!isTotalPkgDisabled) { + double utilization = + ((double) cpuUsageFinalMap.get(TOTAL_CPU_USAGE) / totalCpuTime) * 100; + cpuUsageFinalMap.put(CPU_UTILIZATION, (long) utilization); + } + } + return cpuUsageFinalMap; } @@ -196,4 +225,30 @@ public class CpuUsageHelper implements ICollectorHelper<Long> { public void setDisableTotalFrequency() { isTotalFreqDisabled = true; } + + /** + * Enable the collection of cpu utilization. + */ + public void setEnableCpuUtilization() { + isCpuUtilizationEnabled = true; + } + + /** + * return the number of cores that the device has. + */ + private int getCores() { + if (mCpuCores == null) { + int count = 0; + // every core corresponds to a folder named "cpu[0-9]+" under /sys/devices/system/cpu + File cpuDir = new File("/sys/devices/system/cpu"); + File[] files = cpuDir.listFiles(); + for (File file : files) { + if (Pattern.matches("cpu[0-9]+", file.getName())) { + ++count; + } + } + mCpuCores = count; + } + return mCpuCores.intValue(); + } } diff --git a/libraries/collectors-helper/statsd/test/src/com/android/helpers/CpuUsageHelperTest.java b/libraries/collectors-helper/statsd/test/src/com/android/helpers/CpuUsageHelperTest.java index 37e0ac495..ed551569a 100644 --- a/libraries/collectors-helper/statsd/test/src/com/android/helpers/CpuUsageHelperTest.java +++ b/libraries/collectors-helper/statsd/test/src/com/android/helpers/CpuUsageHelperTest.java @@ -51,6 +51,10 @@ public class CpuUsageHelperTest { private static final String TOTAL_CPU_USAGE = "total_cpu_usage"; // Key used for total CPU usage in frequency buckets private static final String TOTAL_CPU_USAGE_FREQ = "total_cpu_usage_freq"; + // key used for total CPU time + private static final String TOTAL_CPU_TIME = "total_cpu_time"; + // Key used for CPU utilization average over each core + private static final String CPU_UTILIZATION = "cpu_utilization_average_per_core_percent"; private CpuUsageHelper mCpuUsageHelper; private HelperAccessor<ICalendarHelper> mHelper = @@ -206,4 +210,27 @@ public class CpuUsageHelperTest { assertTrue(mCpuUsageHelper.stopCollecting()); mHelper.get().exit(); } + + /** + * Test cpu utilization is collected. + */ + @Test + public void testCpuEnableCpuUtilization() throws Exception { + mCpuUsageHelper.setEnableCpuUtilization(); + assertTrue(mCpuUsageHelper.startCollecting()); + mHelper.get().open(); + Map<String, Long> cpuUsage = mCpuUsageHelper.getMetrics(); + assertTrue(cpuUsage.size() > 3); + assertTrue(cpuUsage.containsKey(TOTAL_CPU_USAGE)); + assertTrue(cpuUsage.containsKey(TOTAL_CPU_TIME)); + assertTrue(cpuUsage.containsKey(CPU_UTILIZATION)); + // TOTAL_CPU_TIME >= TOTAL_CPU_USAGE > 0 + assertTrue(cpuUsage.get(TOTAL_CPU_TIME) >= cpuUsage.get(TOTAL_CPU_USAGE)); + assertTrue(cpuUsage.get(TOTAL_CPU_USAGE) > 0); + // 100 >= CPU_UTILIZATION >=0 (%), it could be equal to 0 due to rounding. + assertTrue(100 >= cpuUsage.get(CPU_UTILIZATION)); + assertTrue(cpuUsage.get(CPU_UTILIZATION) >= 0); + assertTrue(mCpuUsageHelper.stopCollecting()); + mHelper.get().exit(); + } } diff --git a/libraries/device-collectors/src/main/platform-collectors/src/android/device/collectors/CpuUsageListener.java b/libraries/device-collectors/src/main/platform-collectors/src/android/device/collectors/CpuUsageListener.java index 383554826..cefcb4188 100644 --- a/libraries/device-collectors/src/main/platform-collectors/src/android/device/collectors/CpuUsageListener.java +++ b/libraries/device-collectors/src/main/platform-collectors/src/android/device/collectors/CpuUsageListener.java @@ -33,6 +33,7 @@ public class CpuUsageListener extends BaseCollectionListener<Long> { private static final String DISABLE_PER_FREQ = "disable_per_freq"; private static final String DISABLE_TOTAL_PKG = "disable_total_pkg"; private static final String DISABLE_TOTAL_FREQ = "disable_total_freq"; + private static final String ENABLE_CPU_UTILIZATION = "enable_cpu_utilization"; public CpuUsageListener() { createHelperInstance(new CpuUsageHelper()); @@ -60,6 +61,10 @@ public class CpuUsageListener extends BaseCollectionListener<Long> { if ("true".equals(args.getString(DISABLE_TOTAL_FREQ))) { cpuUsageHelper.setDisableTotalFrequency(); } + + if ("true".equals(args.getString(ENABLE_CPU_UTILIZATION))) { + cpuUsageHelper.setEnableCpuUtilization(); + } } } |