Modify swap metrics to be more useful.

We need to record the amount of swap used, and correlate it
with the total amount of swap.

The metrics added are Platform.MeminfoSwapUsed and
Platform.MeminfoSwapUsedPercent.

BUG=chromium-os:38583
TEST=not really
BRANCH=none

Change-Id: Iaf26c917e3c4d23f3f58f436047f8dd165177960
Reviewed-on: https://gerrit.chromium.org/gerrit/43245
Tested-by: Luigi Semenzato <semenzato@chromium.org>
Reviewed-by: Sonny Rao <sonnyrao@chromium.org>
diff --git a/metrics_daemon.cc b/metrics_daemon.cc
index d7c12c4..798d022 100644
--- a/metrics_daemon.cc
+++ b/metrics_daemon.cc
@@ -806,16 +806,16 @@
     { "InactiveAnon", "Inactive(anon)" },
     { "ActiveFile" , "Active(file)" },
     { "InactiveFile", "Inactive(file)" },
-    { "Unevictable", "Unevictable", kMeminfoScaleLog },
+    { "Unevictable", "Unevictable", kMeminfoOp_HistLog },
     // { "Mlocked", "Mlocked" },
-    // { "SwapTotal", "SwapTotal" },
-    { "SwapFree", "SwapFree", kMeminfoScaleLogLarge },
+    { "SwapTotal", "SwapTotal", kMeminfoOp_SwapTotal },
+    { "SwapFree", "SwapFree", kMeminfoOp_SwapFree },
     // { "Dirty", "Dirty" },
     // { "Writeback", "Writeback" },
     { "AnonPages", "AnonPages" },
     { "Mapped", "Mapped" },
-    { "Shmem", "Shmem", kMeminfoScaleLog },
-    { "Slab", "Slab", kMeminfoScaleLog },
+    { "Shmem", "Shmem", kMeminfoOp_HistLog },
+    { "Slab", "Slab", kMeminfoOp_HistLog },
     // { "SReclaimable", "SReclaimable" },
     // { "SUnreclaim", "SUnreclaim" },
   };
@@ -830,26 +830,36 @@
     LOG(WARNING) << "borked meminfo parser";
     return false;
   }
+  int swap_total = 0;
+  int swap_free = 0;
   // Send all fields retrieved, except total memory.
   for (unsigned int i = 1; i < fields.size(); i++) {
     string metrics_name = StringPrintf("Platform.Meminfo%s", fields[i].name);
     int percent;
-    switch (fields[i].scale) {
-      case kMeminfoScalePercent:
+    switch (fields[i].op) {
+      case kMeminfoOp_HistPercent:
         // report value as percent of total memory
         percent = fields[i].value * 100 / total_memory;
         SendLinearMetric(metrics_name, percent, 100, 101);
         break;
-      case kMeminfoScaleLog:
+      case kMeminfoOp_HistLog:
         // report value in kbytes, log scale, 4Gb max
         SendMetric(metrics_name, fields[i].value, 1, 4 * 1000 * 1000, 100);
         break;
-      case kMeminfoScaleLogLarge:
-        // report value in kbytes, log scale, 8Gb max
-        SendMetric(metrics_name, fields[i].value, 1, 8 * 1000 * 1000, 100);
+      case kMeminfoOp_SwapTotal:
+        swap_total = fields[i].value;
+      case kMeminfoOp_SwapFree:
+        swap_free = fields[i].value;
         break;
     }
   }
+  if (swap_total > 0) {
+    int swap_used = swap_total - swap_free;
+    int swap_used_percent = swap_used * 100 / swap_total;
+    SendMetric("Platform.MeminfoSwapUsed", swap_used, 1, 8 * 1000 * 1000, 100);
+    SendLinearMetric("Platform.MeminfoSwapUsedPercent", swap_used_percent,
+                     100, 101);
+  }
   return true;
 }
 
diff --git a/metrics_daemon.h b/metrics_daemon.h
index b93a2bc..0bebbc7 100644
--- a/metrics_daemon.h
+++ b/metrics_daemon.h
@@ -101,17 +101,18 @@
   // percent of total RAM, but for some we use absolute numbers, usually in
   // megabytes, on a log scale from 0 to 4000, and 0 to 8000 for compressed
   // swap (since it can be larger than total RAM).
-  enum MeminfoScaleType {
-    kMeminfoScalePercent = 0,
-    kMeminfoScaleLog,
-    kMeminfoScaleLogLarge,
+  enum MeminfoOp {
+    kMeminfoOp_HistPercent = 0,
+    kMeminfoOp_HistLog,
+    kMeminfoOp_SwapTotal,
+    kMeminfoOp_SwapFree,
   };
 
   // Record for retrieving and reporting values from /proc/meminfo.
   struct MeminfoRecord {
     const char* name;        // print name
     const char* match;       // string to match in output of /proc/meminfo
-    MeminfoScaleType scale;  // histogram scale selector
+    MeminfoOp op;            // histogram scale selector, or other operator
     int value;               // value from /proc/meminfo
   };