You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by GitBox <gi...@apache.org> on 2019/01/14 02:41:02 UTC

[servicecomb-java-chassis] Diff for: [GitHub] liubao68 closed pull request #1047: [SCB-1096]change the method calculate process cpu rate to same with top

diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/CpuMeter.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/CpuMeter.java
index 6edcf1b46..c53d22207 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/CpuMeter.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/CpuMeter.java
@@ -20,16 +20,19 @@
 
 import org.apache.servicecomb.metrics.core.meter.os.cpu.OsCpuUsage;
 import org.apache.servicecomb.metrics.core.meter.os.cpu.ProcessCpuUsage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.netflix.spectator.api.Id;
 import com.netflix.spectator.api.Measurement;
 
 public class CpuMeter {
+  private static final Logger LOGGER = LoggerFactory.getLogger(CpuMeter.class);
 
   // read from /proc/stat
   private OsCpuUsage allCpuUsage;
 
-  // read from /proc/{pid}/stat
+  // read from /proc/self/stat /proc/uptime
   private ProcessCpuUsage processCpuUsage;
 
   public CpuMeter(Id id) {
@@ -49,9 +52,12 @@ public void calcMeasurements(List<Measurement> measurements, long msNow) {
   }
 
   public void update() {
-    allCpuUsage.update();
-    processCpuUsage.setPeriodTotalTime(allCpuUsage.getPeriodTotalTime());
-    processCpuUsage.update();
+    try {
+      allCpuUsage.update();
+      processCpuUsage.update();
+    } catch (Throwable e) {
+      LOGGER.error("Failed to update usage", e);
+    }
   }
 
   public OsCpuUsage getAllCpuUsage() {
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/AbstractCpuUsage.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/AbstractCpuUsage.java
index af4f51440..375a64875 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/AbstractCpuUsage.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/AbstractCpuUsage.java
@@ -16,48 +16,33 @@
  */
 package org.apache.servicecomb.metrics.core.meter.os.cpu;
 
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.commons.io.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import com.netflix.spectator.api.Id;
 
 public abstract class AbstractCpuUsage {
-  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractCpuUsage.class);
-
-  protected String filePath;
 
   protected Id id;
 
-  protected long lastBusyTime;
-
-  protected long periodTotalTime;
-
   protected double usage;
 
-  public AbstractCpuUsage(Id id, String filePath) {
-    this.id = id;
-    this.filePath = filePath;
-  }
+  protected int cpuCount = Runtime.getRuntime().availableProcessors();
 
-  public Id getId() {
-    return id;
-  }
+  static class Period {
+    double last;
 
-  public long getPeriodTotalTime() {
-    return periodTotalTime;
+    double period;
+
+    void update(double current) {
+      period = current - last;
+      last = current;
+    }
   }
 
-  public long getLastBusyTime() {
-    return lastBusyTime;
+  public AbstractCpuUsage(Id id) {
+    this.id = id;
   }
 
-  public String getFilePath() {
-    return filePath;
+  public Id getId() {
+    return id;
   }
 
   public double getUsage() {
@@ -68,36 +53,13 @@ public void setUsage(double usage) {
     this.usage = usage;
   }
 
-  public void setPeriodTotalTime(long periodTotalTime) {
-    this.periodTotalTime = periodTotalTime;
-  }
-
-  protected String[] readAndSplitStat() throws IOException {
-    File file = new File(filePath);
-    String stat = FileUtils.readLines(file, StandardCharsets.UTF_8).get(0);
-    return stat.trim().split("\\s+");
-  }
-
-  public void update() {
-    String[] stats;
-    try {
-      stats = readAndSplitStat();
-    } catch (IOException e) {
-      LOGGER.error(String.format("Failed to read cpu info/%s.", filePath), e);
-      return;
+  protected void updateUsage(double periodBusy, double periodTotal, boolean irixMode) {
+    usage = periodTotal == 0 ? 0 : periodBusy / periodTotal;
+    if (usage > 1) {
+      usage = 1;
+    }
+    if (irixMode) {
+      usage *= cpuCount;
     }
-
-    update(stats);
-  }
-
-  protected void update(String[] stats) {
-    long currentBusyTime = readCurrentBusyTime(stats);
-
-    usage = periodTotalTime == 0 ? 0 : (double) (currentBusyTime - lastBusyTime) / periodTotalTime;
-    usage *= Runtime.getRuntime().availableProcessors();
-
-    lastBusyTime = currentBusyTime;
   }
-
-  protected abstract long readCurrentBusyTime(String[] stats);
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/CpuUtils.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/CpuUtils.java
new file mode 100644
index 000000000..75eb83d9d
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/CpuUtils.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.servicecomb.metrics.core.meter.os.cpu;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.Files;
+
+public final class CpuUtils {
+  private static final Logger LOGGER = LoggerFactory.getLogger(CpuUtils.class);
+
+  public static final File PROC_STAT = new File("/proc/stat");
+
+  public static final File UPTIME = new File("/proc/uptime");
+
+  public static final File SELF_PROCESS = new File("/proc/self/stat");
+
+  private CpuUtils() {
+  }
+
+  public static String[] readAndSplitFirstLine(File file) throws IOException {
+    return Files.asCharSource(file, StandardCharsets.UTF_8).readFirstLine().trim().split("\\s+");
+  }
+
+  public static double summary(String[] stats, int start, int len) {
+    double total = 0;
+    for (int idx = start; idx < start + len; idx++) {
+      total += Double.parseDouble(stats[idx]);
+    }
+    return total;
+  }
+
+  public static double readProcSelfBusy() throws IOException {
+    String[] stats = readAndSplitFirstLine(SELF_PROCESS);
+    return summary(stats, 13, 2);
+  }
+
+  public static double readProcStatTotal() throws IOException {
+    String[] stats = readAndSplitFirstLine(PROC_STAT);
+    return summary(stats, 1, 8);
+  }
+
+  public static double readUptimeTotal() throws IOException {
+    String[] uptime = readAndSplitFirstLine(UPTIME);
+    return Double.parseDouble(uptime[0]);
+  }
+
+  private static boolean isBetween(long x, long lower, long upper) {
+    return lower <= x && x <= upper;
+  }
+
+  /**
+   *  unit of /proc/uptime is seconds
+   *  unit of /proc/self/stat is jiffies
+   *  hence, we should calculate userHZ to get process cpu rate
+   *
+   * @return userHZ
+   */
+  public static int calcHertz() {
+    double up1, up2, seconds;
+    double jiffies;
+
+    for (; ; ) {
+      try {
+        up1 = readUptimeTotal();
+        jiffies = readProcStatTotal();
+        up2 = readUptimeTotal();
+      } catch (Throwable e) {
+        LOGGER.error("Failed to calc hertz, should never happened, try again.", e);
+        continue;
+      }
+
+      if (0 == (long) ((up2 - up1) * 1000.0 / up1)) {
+        break;
+      }
+    }
+
+    seconds = (up1 + up2) / 2;
+    long hz = Math.round(jiffies / seconds / Runtime.getRuntime().availableProcessors());
+    /* S/390 (sometimes) */
+    if (isBetween(hz, 9, 11)) {
+      return 10;
+    }
+
+    /* user-mode Linux */
+    if (isBetween(hz, 18, 22)) {
+      return 20;
+    }
+
+    /* ia64 emulator */
+    if (isBetween(hz, 30, 34)) {
+      return 32;
+    }
+
+    if (isBetween(hz, 48, 52)) {
+      return 50;
+    }
+
+    if (isBetween(hz, 58, 61)) {
+      return 60;
+    }
+
+    /* StrongARM /Shark */
+    if (isBetween(hz, 62, 65)) {
+      return 64;
+    }
+
+    /* normal Linux */
+    if (isBetween(hz, 95, 105)) {
+      return 100;
+    }
+
+    /* MIPS, ARM */
+    if (isBetween(hz, 124, 132)) {
+      return 128;
+    }
+
+    /* normal << 1 */
+    if (isBetween(hz, 195, 204)) {
+      return 200;
+    }
+
+    if (isBetween(hz, 247, 252)) {
+      return 250;
+    }
+
+    if (isBetween(hz, 253, 260)) {
+      return 256;
+    }
+
+    /* normal << 2 */
+    if (isBetween(hz, 393, 408)) {
+      return 400;
+    }
+
+    /* SMP WinNT */
+    if (isBetween(hz, 410, 600)) {
+      return 500;
+    }
+
+    /* normal << 3 */
+    if (isBetween(hz, 790, 808)) {
+      return 800;
+    }
+
+    /* ARM */
+    if (isBetween(hz, 990, 1010)) {
+      return 1000;
+    }
+
+    /* Alpha, ia64 */
+    if (isBetween(hz, 1015, 1035)) {
+      return 1024;
+    }
+
+    /* Alpha */
+    if (isBetween(hz, 1180, 1220)) {
+      return 1200;
+    }
+
+    LOGGER.warn("Unknown HZ value! ({}) Assume {}.\n", hz, 100);
+    return 100;
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/OsCpuUsage.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/OsCpuUsage.java
index 48b9a8ce7..b79ceb854 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/OsCpuUsage.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/OsCpuUsage.java
@@ -16,51 +16,37 @@
  */
 package org.apache.servicecomb.metrics.core.meter.os.cpu;
 
+import java.io.IOException;
+
 import com.netflix.spectator.api.Id;
 
 /*
- * unit : 1 jiffies = 10ms = 0.01 s
+ * unit : 1 jiffies
  * more details :
  * http://man7.org/linux/man-pages/man5/proc.5.html
  * CMD :  /proc/stat
  * cpu  2445171 599297 353967 24490633 11242   0    10780    2993             0      0
  * cpu  user    nice   system idle     iowait  irq  softirq  stealstolen      guest  guest_nice
- * 0    1       2      3      4        5        6   7        8
+ * 0    1       2      3      4        5        6   7        8                9      10
  * total = user + nice + system + idle + iowait + irq + softirq + stealstolen
  * busy = total - idle
  */
 public class OsCpuUsage extends AbstractCpuUsage {
-  private long lastTotalTime;
 
-  private long currentTotalTime;
+  private Period total = new Period();
 
-  public OsCpuUsage(Id id) {
-    super(id, "/proc/stat");
-  }
+  private Period idle = new Period();
 
-  @Override
-  protected void update(String[] stats) {
-    currentTotalTime = readCurrentTotalTime(stats);
-    periodTotalTime = currentTotalTime - lastTotalTime;
-    lastTotalTime = currentTotalTime;
-
-    super.update(stats);
-  }
-
-  private long readCurrentTotalTime(String[] stats) {
-    long total = 0L;
-    for (int i = 1; i <= 8; i++) {
-      total += Long.parseLong(stats[i]);
-    }
-    return total;
-  }
-
-  @Override
-  protected long readCurrentBusyTime(String[] stats) {
-    return currentTotalTime - Long.parseLong(stats[4]);
+  public OsCpuUsage(Id id) {
+    super(id);
   }
 
-  public long getLastTotalTime() {
-    return lastTotalTime;
+  public void update() throws IOException {
+    String[] stats = CpuUtils.readAndSplitFirstLine(CpuUtils.PROC_STAT);
+    long currentIdle = Long.parseLong(stats[4]);
+    double totalCpu = CpuUtils.summary(stats, 1, 8);
+    idle.update(currentIdle);
+    total.update(totalCpu);
+    updateUsage(total.period - idle.period, total.period, false);
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/ProcessCpuUsage.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/ProcessCpuUsage.java
index 57efd8579..96d681048 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/ProcessCpuUsage.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/ProcessCpuUsage.java
@@ -16,7 +16,7 @@
  */
 package org.apache.servicecomb.metrics.core.meter.os.cpu;
 
-import java.lang.management.ManagementFactory;
+import java.io.IOException;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -24,40 +24,36 @@
 import com.netflix.spectator.api.Id;
 
 /*
- * unit : 1 jiffies = 10ms = 0.01 s
+ * unit : 1 jiffies
  * more details :
  * http://man7.org/linux/man-pages/man5/proc.5.html
  * CMD :  /proc/[pid]/stat
  * 6754 (kubelet) S      1     995   995      0       -1     4202752   193281  592501546 0       12       1152076 907044 87991  113319  ..
  * pid  comm      state  ppid  pgrp  session  tty_nr  tpgid  flags     minflt  cminflt   majflt  cmajflt  utime   stime  cutime cstime
  * 0    1         2      3     4     5        6       7      8         9       10        11      12       13      14     15     16
- * busy = utime + stime + cutime + cstime
+ * busy = utime + stime
+ * CMD: /proc/uptime
+ * total = uptime[0] * cpuNum * userHZ
  *
  */
 public class ProcessCpuUsage extends AbstractCpuUsage {
   private static final Logger LOGGER = LoggerFactory.getLogger(ProcessCpuUsage.class);
 
-  public ProcessCpuUsage(Id id) {
-    super(id, String.format("/proc/%s/stat", getCurrentPid()));
-  }
+  private Period busy = new Period();
 
-  private static String getCurrentPid() {
-    String name = ManagementFactory.getRuntimeMXBean().getName();
-    int idx = name.indexOf('@');
-    if (idx > 0) {
-      return name.substring(0, idx);
-    }
+  private Period total = new Period();
 
-    LOGGER.error("Failed to get current process id. {}", name);
-    throw new IllegalStateException("Failed to get current process Id");
+  private int userHZ = CpuUtils.calcHertz();
+
+  public ProcessCpuUsage(Id id) {
+    super(id);
   }
 
-  @Override
-  protected long readCurrentBusyTime(String[] stats) {
-    long busy = 0L;
-    for (int i = 13; i <= 16; i++) {
-      busy += Long.parseLong(stats[i]);
-    }
-    return busy;
+  public void update() throws IOException {
+    double processBusy = CpuUtils.readProcSelfBusy();
+    double uptime = CpuUtils.readUptimeTotal();
+    busy.update(processBusy);
+    total.update(uptime * userHZ * cpuCount);
+    updateUsage(busy.period, total.period, true);
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultLogPublisher.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultLogPublisher.java
index 7b3b48841..f7ed8d258 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultLogPublisher.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultLogPublisher.java
@@ -32,7 +32,6 @@
 import org.apache.servicecomb.foundation.vertx.VertxUtils;
 import org.apache.servicecomb.metrics.core.VertxMetersInitializer;
 import org.apache.servicecomb.metrics.core.meter.invocation.MeterInvocationConst;
-import org.apache.servicecomb.metrics.core.meter.os.CpuMeter;
 import org.apache.servicecomb.metrics.core.meter.os.NetMeter;
 import org.apache.servicecomb.metrics.core.meter.os.OsMeter;
 import org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel;
@@ -176,7 +175,8 @@ private void printCpuLog(StringBuilder sb, MeasurementNode osNode) {
     double processRate = processNode.summary();
 
     appendLine(sb, "  cpu:");
-    appendLine(sb, "    all: %.2f%%    process: %.2f%%", allRate * 100, processRate * 100);
+    appendLine(sb, "    all usage: %.2f%%    all idle: %.2f%%    process: %.2f%%", allRate * 100,
+        (1 - allRate) * 100, processRate * 100);
   }
 
 
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestOsMeterInitializer.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestOsMeterInitializer.java
index 8f2f60f86..251493470 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestOsMeterInitializer.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestOsMeterInitializer.java
@@ -31,6 +31,7 @@
 import org.apache.servicecomb.metrics.core.meter.os.CpuMeter;
 import org.apache.servicecomb.metrics.core.meter.os.NetMeter;
 import org.apache.servicecomb.metrics.core.meter.os.OsMeter;
+import org.apache.servicecomb.metrics.core.meter.os.cpu.CpuUtils;
 import org.apache.servicecomb.metrics.core.meter.os.net.InterfaceUsage;
 import org.junit.After;
 import org.junit.Assert;
@@ -38,6 +39,7 @@
 import org.junit.Test;
 
 import com.google.common.eventbus.EventBus;
+import com.google.common.io.Files;
 import com.netflix.spectator.api.DefaultRegistry;
 import com.netflix.spectator.api.ManualClock;
 import com.netflix.spectator.api.Registry;
@@ -66,15 +68,28 @@ public void beforeTest() {
   public void init(@Mocked Runtime runtime, @Mocked RuntimeMXBean mxBean) {
     ReflectUtils.setField(SystemUtils.class, null, "IS_OS_LINUX", true);
     List<String> list = new ArrayList<>();
-    list.add("cpu  1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1");
+    list.add("13  1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1");
     list.add("useless");
     list.add("eth0: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0");
+    new MockUp<Files>() {
+      //Files.readFirstLine
+      @Mock
+      public String readFirstLine(File file, Charset encoding) {
+        return list.get(0);
+      }
+    };
     new MockUp<FileUtils>() {
       @Mock
       public List<String> readLines(File file, Charset encoding) {
         return list;
       }
     };
+    new MockUp<CpuUtils>() {
+      @Mock
+      public int calcHertz() {
+        return 100;
+      }
+    };
     new MockUp<ManagementFactory>() {
       @Mock
       RuntimeMXBean getRuntimeMXBean() {
@@ -92,8 +107,6 @@ public Runtime getRuntime() {
       {
         runtime.availableProcessors();
         result = 2;
-        mxBean.getName();
-        result = "6666@desktop111";
       }
     };
     globalRegistry.add(registry);
@@ -106,14 +119,8 @@ public Runtime getRuntime() {
     CpuMeter cpuMeter = osMeter.getCpuMeter();
     NetMeter netMeter = osMeter.getNetMeter();
     Assert.assertEquals(0.0, cpuMeter.getProcessCpuUsage().getUsage(), 0.0);
-    Assert.assertEquals("/proc/6666/stat", cpuMeter.getProcessCpuUsage().getFilePath());
-    Assert.assertEquals(4L, cpuMeter.getProcessCpuUsage().getLastBusyTime());
-    Assert.assertEquals(8L, cpuMeter.getProcessCpuUsage().getPeriodTotalTime());
 
     Assert.assertEquals(0.0, cpuMeter.getAllCpuUsage().getUsage(), 0.0);
-    Assert.assertEquals(8L, cpuMeter.getAllCpuUsage().getPeriodTotalTime());
-    Assert.assertEquals(7L, cpuMeter.getAllCpuUsage().getLastBusyTime());
-    Assert.assertEquals("/proc/stat", cpuMeter.getAllCpuUsage().getFilePath());
 
     Map<String, InterfaceUsage> interfaceInfoMap = netMeter.getInterfaceUsageMap();
     Assert.assertEquals(1, interfaceInfoMap.size());
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestCpuMeter.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestCpuMeter.java
index 5b2819132..b2f321db0 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestCpuMeter.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestCpuMeter.java
@@ -17,16 +17,19 @@
 package org.apache.servicecomb.metrics.core.meter.os;
 
 import java.io.File;
+import java.io.IOException;
 import java.lang.management.ManagementFactory;
 import java.lang.management.RuntimeMXBean;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.commons.io.FileUtils;
+import org.apache.servicecomb.metrics.core.meter.os.cpu.CpuUtils;
 import org.junit.Assert;
 import org.junit.Test;
 
+import com.google.common.io.CharSource;
+import com.google.common.io.Files;
 import com.netflix.spectator.api.Id;
 import com.netflix.spectator.api.Measurement;
 
@@ -38,13 +41,12 @@
 public class TestCpuMeter {
 
   @Test
-  public void testRefreshCpuSuccess(@Mocked Id id, @Mocked Runtime runtime, @Mocked RuntimeMXBean mxBean) {
-    List<String> list = new ArrayList<>();
-    list.add("cpu  1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1");
-    new MockUp<FileUtils>() {
+  public void testRefreshCpuSuccess(@Mocked Id id, @Mocked Runtime runtime, @Mocked RuntimeMXBean mxBean,
+      @Mocked CharSource charSource) throws IOException {
+    new MockUp<Files>() {
       @Mock
-      public List<String> readLines(File file, Charset encoding) {
-        return list;
+      public CharSource asCharSource(File file, Charset encoding) {
+        return charSource;
       }
     };
     new MockUp<ManagementFactory>() {
@@ -53,7 +55,12 @@ RuntimeMXBean getRuntimeMXBean() {
         return mxBean;
       }
     };
-
+    new MockUp<CpuUtils>() {
+      @Mock
+      public int calcHertz() {
+        return 4;
+      }
+    };
     new MockUp<Runtime>() {
       @Mock
       public Runtime getRuntime() {
@@ -64,44 +71,42 @@ public Runtime getRuntime() {
       {
         runtime.availableProcessors();
         result = 2;
-        mxBean.getName();
-        result = "6666@desktop111";
+        charSource.readFirstLine();
+        result = "1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1";
       }
     };
     CpuMeter cpuMeter = new CpuMeter(id);
     Assert.assertEquals(0.0, cpuMeter.getAllCpuUsage().getUsage(), 0.0);
     Assert.assertEquals(0.0, cpuMeter.getProcessCpuUsage().getUsage(), 0.0);
 
-    Assert.assertEquals(4L, cpuMeter.getProcessCpuUsage().getLastBusyTime());
-    Assert.assertEquals(8L, cpuMeter.getAllCpuUsage().getPeriodTotalTime());
-    Assert.assertEquals(8L, cpuMeter.getAllCpuUsage().getLastTotalTime());
-    Assert.assertEquals(7L, cpuMeter.getAllCpuUsage().getLastBusyTime());
-
-    Assert.assertEquals("/proc/stat", cpuMeter.getAllCpuUsage().getFilePath());
-    Assert.assertEquals("/proc/6666/stat", cpuMeter.getProcessCpuUsage().getFilePath());
-
-    list.add(0, "cpu  2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2");
+    new Expectations() {
+      {
+        charSource.readFirstLine();
+        result = "2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2";
+      }
+    };
     cpuMeter.update();
-    Assert.assertEquals(1.0, cpuMeter.getProcessCpuUsage().getUsage(), 0.0);
-    Assert.assertEquals(1.75, cpuMeter.getAllCpuUsage().getUsage(), 0.0);
 
-    Assert.assertEquals(8L, cpuMeter.getProcessCpuUsage().getLastBusyTime());
-    Assert.assertEquals(16L, cpuMeter.getAllCpuUsage().getLastTotalTime());
-    Assert.assertEquals(8L, cpuMeter.getAllCpuUsage().getPeriodTotalTime());
-    Assert.assertEquals(14L, cpuMeter.getAllCpuUsage().getLastBusyTime());
+    Assert.assertEquals(0.875, cpuMeter.getAllCpuUsage().getUsage(), 0.0);
+    Assert.assertEquals(0.5, cpuMeter.getProcessCpuUsage().getUsage(), 0.0);
   }
 
   @Test
-  public void testRefreshError(@Mocked Id id, @Mocked Runtime runtime, @Mocked RuntimeMXBean mxBean) {
-    List<String> list = new ArrayList<>();
-    list.add("cpu  1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1");
-    new MockUp<FileUtils>() {
+  public void testRefreshError(@Mocked Id id, @Mocked Runtime runtime, @Mocked RuntimeMXBean mxBean,
+      @Mocked CharSource charSource) throws IOException {
+
+    new MockUp<Files>() {
       @Mock
-      public List<String> readLines(File file, Charset encoding) {
-        return list;
+      public CharSource asCharSource(File file, Charset encoding) {
+        return charSource;
+      }
+    };
+    new MockUp<CpuUtils>() {
+      @Mock
+      public int calcHertz() {
+        return 4;
       }
     };
-
     new MockUp<ManagementFactory>() {
       @Mock
       RuntimeMXBean getRuntimeMXBean() {
@@ -118,46 +123,42 @@ public Runtime getRuntime() {
       {
         runtime.availableProcessors();
         result = 2;
-        mxBean.getName();
-        result = "6666@desktop111";
+        charSource.readFirstLine();
+        result = "1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1";
       }
     };
     CpuMeter cpuMeter = new CpuMeter(id);
     Assert.assertEquals(0.0, cpuMeter.getAllCpuUsage().getUsage(), 0.0);
     Assert.assertEquals(0.0, cpuMeter.getProcessCpuUsage().getUsage(), 0.0);
-
-    Assert.assertEquals(4L, cpuMeter.getProcessCpuUsage().getLastBusyTime());
-    Assert.assertEquals(8L, cpuMeter.getAllCpuUsage().getPeriodTotalTime());
-    Assert.assertEquals(8L, cpuMeter.getAllCpuUsage().getLastTotalTime());
-    Assert.assertEquals(7L, cpuMeter.getAllCpuUsage().getLastBusyTime());
-
-    Assert.assertEquals("/proc/stat", cpuMeter.getAllCpuUsage().getFilePath());
-    Assert.assertEquals("/proc/6666/stat", cpuMeter.getProcessCpuUsage().getFilePath());
-
-    list.add(0, "cpu  1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1");
+    new Expectations() {
+      {
+        charSource.readFirstLine();
+        result = "1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1";
+      }
+    };
     cpuMeter.update();
 
     Assert.assertEquals(0.0, cpuMeter.getAllCpuUsage().getUsage(), 0.0);
     Assert.assertEquals(0.0, cpuMeter.getProcessCpuUsage().getUsage(), 0.0);
-
-    Assert.assertEquals(4L, cpuMeter.getProcessCpuUsage().getLastBusyTime());
-    Assert.assertEquals(0L, cpuMeter.getAllCpuUsage().getPeriodTotalTime());
-    Assert.assertEquals(8L, cpuMeter.getAllCpuUsage().getLastTotalTime());
-    Assert.assertEquals(7L, cpuMeter.getAllCpuUsage().getLastBusyTime());
   }
 
   @Test
-  public void testCalcMeasurements(@Mocked Id id, @Mocked Runtime runtime, @Mocked RuntimeMXBean mxBean) {
+  public void testCalcMeasurements(@Mocked Id id, @Mocked Runtime runtime, @Mocked RuntimeMXBean mxBean,
+      @Mocked CharSource charSource) throws IOException {
     List<Measurement> measurements = new ArrayList<>();
-    List<String> list = new ArrayList<>();
-    list.add("cpu  1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1");
-    new MockUp<FileUtils>() {
+
+    new MockUp<Files>() {
       @Mock
-      public List<String> readLines(File file, Charset encoding) {
-        return list;
+      public CharSource asCharSource(File file, Charset encoding) {
+        return charSource;
+      }
+    };
+    new MockUp<CpuUtils>() {
+      @Mock
+      public int calcHertz() {
+        return 4;
       }
     };
-
     new MockUp<ManagementFactory>() {
       @Mock
       RuntimeMXBean getRuntimeMXBean() {
@@ -174,19 +175,25 @@ public Runtime getRuntime() {
       {
         runtime.availableProcessors();
         result = 2;
-        mxBean.getName();
-        result = "6666@desktop111";
+        charSource.readFirstLine();
+        result = "1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1";
       }
     };
     CpuMeter cpuMeter = new CpuMeter(id);
-    list.add(0, "cpu  2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2");
+
+    new Expectations() {
+      {
+        charSource.readFirstLine();
+        result = "2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2";
+      }
+    };
     cpuMeter.calcMeasurements(measurements, 0);
     Assert.assertEquals(2, measurements.size());
     Measurement measurement = measurements.get(0);
     Assert.assertEquals(0, measurement.timestamp());
-    Assert.assertEquals(1.75, measurement.value(), 0.0);
+    Assert.assertEquals(0.875, measurement.value(), 0.0);
     measurement = measurements.get(1);
     Assert.assertEquals(0, measurement.timestamp());
-    Assert.assertEquals(1.0, measurement.value(), 0.0);
+    Assert.assertEquals(0.5, measurement.value(), 0.0);
   }
 }
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestOsMeter.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestOsMeter.java
index 79b20a718..994c3ddde 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestOsMeter.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestOsMeter.java
@@ -18,6 +18,7 @@
 
 
 import java.io.File;
+import java.io.IOException;
 import java.lang.management.ManagementFactory;
 import java.lang.management.RuntimeMXBean;
 import java.nio.charset.Charset;
@@ -25,10 +26,13 @@
 import java.util.List;
 
 import org.apache.commons.io.FileUtils;
+import org.apache.servicecomb.metrics.core.meter.os.cpu.CpuUtils;
 import org.junit.Assert;
 import org.junit.Test;
 
 import com.google.common.collect.Lists;
+import com.google.common.io.CharSource;
+import com.google.common.io.Files;
 import com.netflix.spectator.api.DefaultRegistry;
 import com.netflix.spectator.api.ManualClock;
 import com.netflix.spectator.api.Measurement;
@@ -43,9 +47,10 @@
   Registry registry = new DefaultRegistry(new ManualClock());
 
   @Test
-  public void testCalcMeasurement(@Mocked Runtime runtime, @Mocked RuntimeMXBean mxBean) {
+  public void testCalcMeasurement(@Mocked Runtime runtime, @Mocked RuntimeMXBean mxBean,
+      @Mocked CharSource charSource) throws IOException {
     List<String> list = new ArrayList<>();
-    list.add("cpu  1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1");
+    list.add("useless");
     list.add("useless");
     list.add("eth0: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0");
     new MockUp<FileUtils>() {
@@ -54,6 +59,18 @@ public void testCalcMeasurement(@Mocked Runtime runtime, @Mocked RuntimeMXBean m
         return list;
       }
     };
+    new MockUp<CpuUtils>() {
+      @Mock
+      public int calcHertz() {
+        return 4;
+      }
+    };
+    new MockUp<Files>() {
+      @Mock
+      public CharSource asCharSource(File file, Charset encoding) {
+        return charSource;
+      }
+    };
     new MockUp<ManagementFactory>() {
       @Mock
       RuntimeMXBean getRuntimeMXBean() {
@@ -70,21 +87,26 @@ public Runtime getRuntime() {
       {
         runtime.availableProcessors();
         result = 2;
-        mxBean.getName();
-        result = "6666@desktop111";
+        charSource.readFirstLine();
+        result = "1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1";
       }
     };
     OsMeter osMeter = new OsMeter(registry);
     list.clear();
-    list.add("cpu  2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2");
+    list.add("useless");
     list.add("useless");
     list.add("eth0: 1 1    0    0    0     0          0          1         1 1    1      0     0     0    0    0");
-
+    new Expectations() {
+      {
+        charSource.readFirstLine();
+        result = "2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2";
+      }
+    };
     osMeter.calcMeasurements(1, 1);
     ArrayList<Measurement> measurements = Lists.newArrayList(osMeter.measure());
     Assert.assertEquals(6, measurements.size());
-    Assert.assertEquals(1.75, measurements.get(0).value(), 0.0);
-    Assert.assertEquals(1.0, measurements.get(1).value(), 0.0);
+    Assert.assertEquals(0.875, measurements.get(0).value(), 0.0);
+    Assert.assertEquals(0.5, measurements.get(1).value(), 0.0);
     Assert.assertEquals(1.0, measurements.get(2).value(), 0.0);
     Assert.assertEquals(1.0, measurements.get(3).value(), 0.0);
     Assert.assertEquals(1.0, measurements.get(4).value(), 0.0);
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestDefaultLogPublisher.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestDefaultLogPublisher.java
index 81f29dc35..622ca4677 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestDefaultLogPublisher.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestDefaultLogPublisher.java
@@ -238,7 +238,7 @@ MeasurementTree getTree() {
     Assert.assertEquals("\n"
             + "os:\n"
             + "  cpu:\n"
-            + "    all: 100.00%    process: 100.00%\n"
+            + "    all usage: 100.00%    all idle: 0.00%    process: 100.00%\n"
             + "  net:\n"
             + "    send(Bps)    recv(Bps)    send(pps)    recv(pps)    interface\n"
             + "    1            1            1            1            eth0\n"


With regards,
Apache Git Services