You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/12/05 08:10:32 UTC

[servicecomb-java-chassis] 03/04: [SCB-1044]add current process CPU rate and net packets in the metrics: reconstruct code

This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git

commit dcaf643605bcd58df36bdb62a10d7828ebff6612
Author: heyile <25...@qq.com>
AuthorDate: Tue Dec 4 17:44:29 2018 +0800

    [SCB-1044]add current process CPU rate  and net packets in the metrics: reconstruct code
---
 .../metrics/publish/spectator/MeasurementTree.java |   2 +-
 .../metrics/core/meter/os/CpuMeter.java            | 184 +++---------------
 .../metrics/core/meter/os/NetMeter.java            | 142 ++------------
 .../servicecomb/metrics/core/meter/os/OsMeter.java |  15 +-
 .../core/meter/os/cpu/AbstractCpuUsage.java        | 103 ++++++++++
 .../metrics/core/meter/os/cpu/OsCpuUsage.java      |  68 +++++++
 .../metrics/core/meter/os/cpu/ProcessCpuUsage.java |  63 ++++++
 .../metrics/core/meter/os/net/InterfaceUsage.java  |  65 +++++++
 .../metrics/core/meter/os/net/NetStat.java         |  63 ++++++
 .../metrics/core/publish/DefaultLogPublisher.java  |  12 +-
 .../metrics/core/TestOsMeterInitializer.java       |  54 +++---
 .../metrics/core/meter/os/TestCpuMeter.java        |  76 ++++----
 .../metrics/core/meter/os/TestNetMeter.java        | 212 +++++++++++++--------
 .../core/publish/TestDefaultLogPublisher.java      |   8 +-
 14 files changed, 618 insertions(+), 449 deletions(-)

diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementTree.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementTree.java
index 5e18de6..79101fa 100644
--- a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementTree.java
+++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementTree.java
@@ -56,7 +56,7 @@ public class MeasurementTree extends MeasurementNode {
         Tag tag = tagFinder.find(id.tags());
         if (tag == null) {
           if (tagFinder.skipOnNull()) {
-            continue;
+            break;
           }
           throw new IllegalStateException(
               String.format("tag key \"%s\" not exist in %s",
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 0b1e386..4a64715 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
@@ -16,15 +16,10 @@
  */
 package org.apache.servicecomb.metrics.core.meter.os;
 
-import java.io.File;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.nio.charset.StandardCharsets;
 import java.util.List;
 
-import org.apache.commons.io.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.servicecomb.metrics.core.meter.os.cpu.OsCpuUsage;
+import org.apache.servicecomb.metrics.core.meter.os.cpu.ProcessCpuUsage;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.netflix.spectator.api.BasicTag;
@@ -33,176 +28,47 @@ import com.netflix.spectator.api.Measurement;
 import com.netflix.spectator.api.Tag;
 
 public class CpuMeter {
-  private static final Logger LOGGER = LoggerFactory.getLogger(CpuMeter.class);
 
-  public static final String STATISTIC = "statistic";
+  public static final Tag TAG_All = new BasicTag(OsMeter.OS_TYPE, OsMeter.OS_TYPE_ALL_CPU);
 
-  public static final Tag TAG_All = new BasicTag(STATISTIC, "allProcess");
+  public static final Tag TAG_CURRENT = new BasicTag(OsMeter.OS_TYPE, OsMeter.OS_TYPE_PROCESS_CPU);
 
-  public static final Tag TAG_CURRENT = new BasicTag(STATISTIC, "currentProcess");
-
-  private CpuInfo aCpuInfo;
-
-  private CpuInfo pCpuInfo;
-
-  private long lastTotalTime;
-
-  private long currentTotalTime;
-
-  private int cpuNum;
-
-  // process id
-  private String pid;
+  // read from /proc/stat
+  private OsCpuUsage allCpuUsage;
 
+  // read from /proc/{pid}/stat
+  private ProcessCpuUsage processCpuUsage;
 
   public CpuMeter(Id id) {
-    this.pid = getCurrentPid();
-    this.cpuNum = Runtime.getRuntime().availableProcessors();
-    aCpuInfo = new CpuInfo(id.withTag(TAG_All), true, "/proc/stat", this);
-    pCpuInfo = new CpuInfo(id.withTag(TAG_CURRENT), false, String.format("/proc/%s/stat", pid), this);
-    //must refresh all first
-    refreshCpu();
-    aCpuInfo.rate = 0.0;
-    pCpuInfo.rate = 0.0;
-  }
-
-  public static class CpuInfo {
-    private Id id;
-
-    private CpuMeter cpuMeter;
-
-    private boolean hasTotal;
-
-    private long lastTime;
-
-    private String filePath;
-
-    private double rate;
-
-    public CpuInfo(Id id, boolean hasTotal, String filePath, CpuMeter cpuMeter) {
-      this.cpuMeter = cpuMeter;
-      this.id = id;
-      this.hasTotal = hasTotal;
-      this.filePath = filePath;
-    }
-
-    @VisibleForTesting
-    public boolean isHasTotal() {
-      return hasTotal;
-    }
+    allCpuUsage = new OsCpuUsage(id.withTag(TAG_All));
+    processCpuUsage = new ProcessCpuUsage(id.withTag(TAG_CURRENT));
 
-    @VisibleForTesting
-    public long getLastTime() {
-      return lastTime;
-    }
-
-    @VisibleForTesting
-    public String getFilePath() {
-      return filePath;
-    }
-
-    @VisibleForTesting
-    public double getRate() {
-      return rate;
-    }
-
-    /*
-     * unit : 1 jiffies = 10ms = 0.01 s
-     * 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
-     * cpuTotal = user + nice + system + idle + iowait + irq + softirq + stealstolen
-     *
-     * 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
-     * processTotalTime = utime + stime + cutime + cstime
-     *
-     */
-    public void refreshCpu() {
-      try {
-        File file = new File(filePath);
-        String cpuStr = FileUtils.readLines(file, StandardCharsets.UTF_8).get(0);
-        String[] cpuInfo = cpuStr.trim().split("\\s+");
-        long total = 0L;
-        long currentTime = 0L;
-        if (hasTotal) {
-          // pathFile:  /proc/stat
-          currentTime = Long.parseLong(cpuInfo[4]);
-          for (int i = 1; i <= 8; i++) {
-            total += Long.parseLong(cpuInfo[i]);
-          }
-          this.cpuMeter.currentTotalTime = total;
-          if (total != this.cpuMeter.lastTotalTime) {
-            rate = 1.0 - (double) (currentTime - lastTime) / (total - this.cpuMeter.lastTotalTime);
-            rate *= this.cpuMeter.cpuNum;
-          }
-        } else {
-          // pathFile:  /proc/[pid]/stat
-          for (int i = 13; i <= 16; i++) {
-            currentTime += Long.parseLong(cpuInfo[i]);
-          }
-          total = this.cpuMeter.currentTotalTime;
-          if (total != this.cpuMeter.lastTotalTime) {
-            rate = (double) (currentTime - lastTime) / (total - this.cpuMeter.lastTotalTime);
-            rate *= this.cpuMeter.cpuNum;
-          }
-        }
-
-        lastTime = currentTime;
-      } catch (IOException e) {
-        LOGGER.error(String.format("Failed to read cpu info/%s.", filePath), e);
-      }
-    }
-  }
-
-  private String getCurrentPid() {
-    String name = ManagementFactory.getRuntimeMXBean().getName();
-    if (name.contains("@")) {
-      return name.substring(0, name.indexOf("@"));
-    }
-    LOGGER.error("Failed to get current process id. {}", name);
-    throw new IllegalStateException("Failed to get current process Id");
+    //must refresh all first
+    update();
+    allCpuUsage.setUsage(0);
+    processCpuUsage.setUsage(0);
   }
 
   public void calcMeasurements(List<Measurement> measurements, long msNow) {
-    refreshCpu();
-    measurements.add(new Measurement(aCpuInfo.id, msNow, aCpuInfo.rate));
-    measurements.add(new Measurement(pCpuInfo.id, msNow, pCpuInfo.rate));
-  }
-
-  public void refreshCpu() {
-    aCpuInfo.refreshCpu();
-    pCpuInfo.refreshCpu();
-    this.lastTotalTime = this.currentTotalTime;
-  }
-
-  @VisibleForTesting
-  public CpuInfo getACpuInfo() {
-    return aCpuInfo;
-  }
-
-  @VisibleForTesting
-  public CpuInfo getPCpuInfo() {
-    return pCpuInfo;
+    update();
+    measurements.add(new Measurement(allCpuUsage.getId(), msNow, allCpuUsage.getUsage()));
+    measurements.add(new Measurement(processCpuUsage.getId(), msNow, processCpuUsage.getUsage()));
   }
 
   @VisibleForTesting
-  public long getLastTotalTime() {
-    return lastTotalTime;
+  public void update() {
+    allCpuUsage.update();
+    processCpuUsage.setPeriodTotalTime(allCpuUsage.getPeriodTotalTime());
+    processCpuUsage.update();
   }
 
   @VisibleForTesting
-  public int getCpuNum() {
-    return cpuNum;
+  public OsCpuUsage getAllCpuUsage() {
+    return allCpuUsage;
   }
 
   @VisibleForTesting
-  public String getPid() {
-    return pid;
+  public ProcessCpuUsage getProcessCpuUsage() {
+    return processCpuUsage;
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/NetMeter.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/NetMeter.java
index e6f72fb..acfe1c7 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/NetMeter.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/NetMeter.java
@@ -26,6 +26,8 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.commons.io.FileUtils;
+import org.apache.servicecomb.metrics.core.meter.os.net.InterfaceUsage;
+import org.apache.servicecomb.metrics.core.meter.os.net.NetStat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,137 +54,27 @@ public class NetMeter {
 
   private final Id id;
 
-  private Map<String, InterfaceInfo> interfaceInfoMap = new ConcurrentHashMap<>();
-
-  public static class InterfaceInfo {
-    private final String name;
-
-    private PartInterface sendPartInterface;
-
-    private PartInterface recvPartInterface;
-
-
-    InterfaceInfo(Id id, String name) {
-      this.name = name;
-      id = id.withTag(INTERFACE, name);
-      this.recvPartInterface = new PartInterface(id.withTag(TAG_RECEIVE), id.withTag(TAG_PACKETS_RECEIVE), 0);
-      this.sendPartInterface = new PartInterface(id.withTag(TAG_SEND), id.withTag(TAG_PACKETS_SEND), 8);
-    }
-
-    public void update(String interfaceData, long secondInterval) {
-      String[] netInfo = interfaceData.trim().split("\\s+");
-      this.sendPartInterface.update(netInfo, secondInterval);
-      this.recvPartInterface.update(netInfo, secondInterval);
-    }
-
-    public String getName() {
-      return name;
-    }
-
-    @VisibleForTesting
-    public PartInterface getSendPartInterface() {
-      return sendPartInterface;
-    }
-
-    @VisibleForTesting
-    public PartInterface getRecvPartInterface() {
-      return recvPartInterface;
-    }
-  }
-
-  public static class PartInterface {
-    private final int index;
-
-    private Id id;
-
-    private Id packetsId;
-
-    // send/recv bytes
-    private long lastBytes;
-
-    // send/recv packets
-    private long lastPackets;
-
-    //Bps
-    private double rate;
-
-    //Bps
-    private double packetsRate;
-
-    public PartInterface(Id id, Id packetsId, int index) {
-      this.id = id;
-      this.packetsId = packetsId;
-      this.index = index;
-    }
-
-    public void clearRate() {
-      rate = 0;
-      packetsRate = 0;
-    }
-
-    public void update(String[] netInfo, long secondInterval) {
-      long currentBytes = Long.parseLong(netInfo[index]);
-      long currentPackets = Long.parseLong(netInfo[index + 1]);
-
-      rate = (double) (currentBytes - lastBytes) / secondInterval;
-      packetsRate = (double) (currentPackets - lastPackets) / secondInterval;
-
-      lastBytes = currentBytes;
-      lastPackets = currentPackets;
-    }
-
-    @VisibleForTesting
-    public long getLastBytes() {
-      return lastBytes;
-    }
-
-    @VisibleForTesting
-    public long getLastPackets() {
-      return lastPackets;
-    }
-
-    @VisibleForTesting
-    public double getRate() {
-      return rate;
-    }
-
-    @VisibleForTesting
-    public double getPacketsRate() {
-      return packetsRate;
-    }
-
-    @VisibleForTesting
-    public int getIndex() {
-      return index;
-    }
-  }
+  private Map<String, InterfaceUsage> interfaceUsageMap = new ConcurrentHashMap<>();
 
   public NetMeter(Id id) {
     this.id = id;
-
     // init lastRxBytes, lastRxPackets, lastTxBytes, lastTxPackets
     refreshNet(1);
-    for (InterfaceInfo interfaceInfo : interfaceInfoMap.values()) {
-      interfaceInfo.sendPartInterface.clearRate();
-      interfaceInfo.recvPartInterface.clearRate();
-    }
+    interfaceUsageMap.values().forEach(interfaceUsage -> {
+      interfaceUsage.getNetStats().forEach(NetStat::clearRate);
+    });
   }
 
   public void calcMeasurements(List<Measurement> measurements, long msNow, long secondInterval) {
     refreshNet(secondInterval);
 
-    for (InterfaceInfo interfaceInfo : interfaceInfoMap.values()) {
-      measurements
-          .add(new Measurement(interfaceInfo.sendPartInterface.id, msNow, interfaceInfo.sendPartInterface.rate));
-      measurements.add(new Measurement(interfaceInfo.sendPartInterface.packetsId, msNow,
-          interfaceInfo.sendPartInterface.packetsRate));
-      measurements
-          .add(new Measurement(interfaceInfo.recvPartInterface.id, msNow, interfaceInfo.recvPartInterface.rate));
-      measurements.add(new Measurement(interfaceInfo.recvPartInterface.packetsId, msNow,
-          interfaceInfo.recvPartInterface.packetsRate));
-    }
+    interfaceUsageMap.values().stream()
+        .flatMap(interfaceUsage -> interfaceUsage.getNetStats().stream())
+        .map(netStat -> new Measurement(netStat.getId(), msNow, netStat.getRate()))
+        .forEach(measurements::add);
   }
 
+
   /*
    * Inter-|   Receive                                                            |  Transmit
    *  face |bytes      packets     errs drop fifo  frame      compressed multicast|bytes       packets     errs   drop  fifo colls carrier compressed
@@ -207,14 +99,14 @@ public class NetMeter {
         String name = strings[0].trim();
         nameSet.add(name);
 
-        InterfaceInfo interfaceInfo = interfaceInfoMap.computeIfAbsent(name, key -> new InterfaceInfo(id, key));
-        interfaceInfo.update(strings[1], secondInterval);
+        InterfaceUsage interfaceUsage = interfaceUsageMap.computeIfAbsent(name, key -> new InterfaceUsage(id, key));
+        interfaceUsage.update(strings[1], secondInterval);
       }
 
       // clear deleted interfaces
-      for (String interfaceName : interfaceInfoMap.keySet()) {
+      for (String interfaceName : interfaceUsageMap.keySet()) {
         if (!nameSet.contains(interfaceName)) {
-          this.interfaceInfoMap.remove(interfaceName);
+          this.interfaceUsageMap.remove(interfaceName);
         }
       }
     } catch (IOException e) {
@@ -223,7 +115,7 @@ public class NetMeter {
   }
 
   @VisibleForTesting
-  public Map<String, InterfaceInfo> getInterfaceInfoMap() {
-    return interfaceInfoMap;
+  public Map<String, InterfaceUsage> getInterfaceUsageMap() {
+    return interfaceUsageMap;
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/OsMeter.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/OsMeter.java
index f3a97f0..b435665 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/OsMeter.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/OsMeter.java
@@ -26,19 +26,21 @@ import com.netflix.spectator.api.Measurement;
 import com.netflix.spectator.api.Registry;
 
 /**
- * name=os type=cpu statistic=allProcess value = 0
- * name=os type=cpu statistic=currentProcess value = 0
+ * name=os type=cpu value = 0
+ * name=os type=processCpu value = 0
  * name=os type=net interface=eth0 statistic=send value=100
  * name=os type=net interface=eth0 statistic=receive value=100
- * name=os type=net interface=eth0 statistic=sendP value=100
- * name=os type=net interface=eth0 statistic=receiveP value=100
+ * name=os type=net interface=eth0 statistic=sendPackets value=100
+ * name=os type=net interface=eth0 statistic=receivePackets value=100
  */
 public class OsMeter extends AbstractPeriodMeter {
   public static final String OS_NAME = "os";
 
   public static final String OS_TYPE = "type";
 
-  public static final String OS_TYPE_CPU = "cpu";
+  public static final String OS_TYPE_ALL_CPU = "cpu";
+
+  public static final String OS_TYPE_PROCESS_CPU = "processCpu";
 
   public static final String OS_TYPE_NET = "net";
 
@@ -48,8 +50,7 @@ public class OsMeter extends AbstractPeriodMeter {
 
   public OsMeter(Registry registry) {
     this.id = registry.createId(OS_NAME);
-
-    cpuMeter = new CpuMeter(id.withTag(OS_TYPE, OS_TYPE_CPU));
+    cpuMeter = new CpuMeter(id);
     netMeter = new NetMeter(id.withTag(OS_TYPE, OS_TYPE_NET));
   }
 
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
new file mode 100644
index 0000000..af4f514
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/AbstractCpuUsage.java
@@ -0,0 +1,103 @@
+/*
+ * 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.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;
+  }
+
+  public Id getId() {
+    return id;
+  }
+
+  public long getPeriodTotalTime() {
+    return periodTotalTime;
+  }
+
+  public long getLastBusyTime() {
+    return lastBusyTime;
+  }
+
+  public String getFilePath() {
+    return filePath;
+  }
+
+  public double getUsage() {
+    return usage;
+  }
+
+  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;
+    }
+
+    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/OsCpuUsage.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/OsCpuUsage.java
new file mode 100644
index 0000000..aa9de7e
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/OsCpuUsage.java
@@ -0,0 +1,68 @@
+/*
+ * 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 com.google.common.annotations.VisibleForTesting;
+import com.netflix.spectator.api.Id;
+
+/*
+ * unit : 1 jiffies = 10ms = 0.01 s
+ * 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
+ * total = user + nice + system + idle + iowait + irq + softirq + stealstolen
+ * busy = total - idle
+ */
+public class OsCpuUsage extends AbstractCpuUsage {
+  private long lastTotalTime;
+
+  private long currentTotalTime;
+
+  public OsCpuUsage(Id id) {
+    super(id, "/proc/stat");
+  }
+
+  @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]);
+  }
+
+  @VisibleForTesting
+  public long getLastTotalTime() {
+    return lastTotalTime;
+  }
+}
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
new file mode 100644
index 0000000..57efd85
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/cpu/ProcessCpuUsage.java
@@ -0,0 +1,63 @@
+/*
+ * 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.lang.management.ManagementFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.netflix.spectator.api.Id;
+
+/*
+ * unit : 1 jiffies = 10ms = 0.01 s
+ * 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
+ *
+ */
+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 static String getCurrentPid() {
+    String name = ManagementFactory.getRuntimeMXBean().getName();
+    int idx = name.indexOf('@');
+    if (idx > 0) {
+      return name.substring(0, idx);
+    }
+
+    LOGGER.error("Failed to get current process id. {}", name);
+    throw new IllegalStateException("Failed to get current process Id");
+  }
+
+  @Override
+  protected long readCurrentBusyTime(String[] stats) {
+    long busy = 0L;
+    for (int i = 13; i <= 16; i++) {
+      busy += Long.parseLong(stats[i]);
+    }
+    return busy;
+  }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/net/InterfaceUsage.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/net/InterfaceUsage.java
new file mode 100644
index 0000000..d6f1ac7
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/net/InterfaceUsage.java
@@ -0,0 +1,65 @@
+/*
+ * 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.net;
+
+import static org.apache.servicecomb.metrics.core.meter.os.NetMeter.INTERFACE;
+import static org.apache.servicecomb.metrics.core.meter.os.NetMeter.TAG_PACKETS_RECEIVE;
+import static org.apache.servicecomb.metrics.core.meter.os.NetMeter.TAG_PACKETS_SEND;
+import static org.apache.servicecomb.metrics.core.meter.os.NetMeter.TAG_RECEIVE;
+import static org.apache.servicecomb.metrics.core.meter.os.NetMeter.TAG_SEND;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.netflix.spectator.api.Id;
+
+public class InterfaceUsage {
+  private final String name;
+
+  private List<NetStat> netStats = new ArrayList<>();
+
+  public InterfaceUsage(Id id, String name) {
+    this.name = name;
+    id = id.withTag(INTERFACE, name);
+    init(id);
+  }
+
+  private void init(Id id) {
+    // recv/Bps
+    netStats.add(new NetStat(id.withTag(TAG_RECEIVE), 0));
+    // send/Bps
+    netStats.add(new NetStat(id.withTag(TAG_SEND), 8));
+
+    // recv/pps
+    netStats.add(new NetStat(id.withTag(TAG_PACKETS_RECEIVE), 1));
+    // send/pps
+    netStats.add(new NetStat(id.withTag(TAG_PACKETS_SEND), 9));
+  }
+
+  public void update(String interfaceData, long secondInterval) {
+    String[] netInfo = interfaceData.trim().split("\\s+");
+    netStats.forEach(netStat -> netStat.update(netInfo, secondInterval));
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public List<NetStat> getNetStats() {
+    return netStats;
+  }
+}
\ No newline at end of file
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/net/NetStat.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/net/NetStat.java
new file mode 100644
index 0000000..ed6bbe0
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/net/NetStat.java
@@ -0,0 +1,63 @@
+/*
+ * 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.net;
+
+import com.netflix.spectator.api.Id;
+
+public class NetStat {
+  private final int index;
+
+  private Id id;
+
+  // send/recv bytes/packets
+  private long lastValue;
+
+  // Bps/pps
+  private double rate;
+
+
+  public NetStat(Id id, int index) {
+    this.id = id;
+    this.index = index;
+  }
+
+  public void clearRate() {
+    rate = 0;
+  }
+
+  public void update(String[] netInfo, long secondInterval) {
+    long currentValue = Long.parseLong(netInfo[index]);
+    rate = (double) (currentValue - lastValue) / secondInterval;
+    lastValue = currentValue;
+  }
+
+  public long getLastValue() {
+    return lastValue;
+  }
+
+  public double getRate() {
+    return rate;
+  }
+
+  public int getIndex() {
+    return index;
+  }
+
+  public Id getId() {
+    return id;
+  }
+}
\ No newline at end of file
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 32a2efa..10635b6 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
@@ -165,12 +165,16 @@ public class DefaultLogPublisher implements MetricsInitializer {
   }
 
   private void printCpuLog(StringBuilder sb, MeasurementNode osNode) {
-    MeasurementNode cpuNode = osNode.findChild(OsMeter.OS_TYPE_CPU);
-    if (cpuNode == null || cpuNode.getMeasurements().isEmpty()) {
+    MeasurementNode cpuNode = osNode.findChild(OsMeter.OS_TYPE_ALL_CPU);
+    MeasurementNode processNode = osNode.findChild(OsMeter.OS_TYPE_PROCESS_CPU);
+    if (cpuNode == null || cpuNode.getMeasurements().isEmpty() ||
+        processNode == null || processNode.getMeasurements().isEmpty()) {
       return;
     }
-    double allRate = cpuNode.findChild(CpuMeter.TAG_All.value()).summary();
-    double processRate = cpuNode.findChild(CpuMeter.TAG_CURRENT.value()).summary();
+
+    double allRate = cpuNode.summary();
+    double processRate = processNode.summary();
+
     appendLine(sb, "  cpu:");
     appendLine(sb, "    all: %.2f%%    process: %.2f%%", 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 5a808d6..8f2f60f 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
@@ -30,8 +30,8 @@ import org.apache.servicecomb.foundation.common.utils.ReflectUtils;
 import org.apache.servicecomb.foundation.metrics.registry.GlobalRegistry;
 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.NetMeter.InterfaceInfo;
 import org.apache.servicecomb.metrics.core.meter.os.OsMeter;
+import org.apache.servicecomb.metrics.core.meter.os.net.InterfaceUsage;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -63,7 +63,7 @@ public class TestOsMeterInitializer {
   }
 
   @Test
-  public void init(@Mocked Runtime runtime,@Mocked RuntimeMXBean mxBean) {
+  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");
@@ -105,30 +105,38 @@ public class TestOsMeterInitializer {
     Assert.assertNotNull(osMeter.getNetMeter());
     CpuMeter cpuMeter = osMeter.getCpuMeter();
     NetMeter netMeter = osMeter.getNetMeter();
-    Assert.assertEquals(0.0, cpuMeter.getPCpuInfo().getRate(), 0.0);
-    Assert.assertEquals("6666", cpuMeter.getPid());
-    Assert.assertEquals(4L, cpuMeter.getPCpuInfo().getLastTime());
-    Assert.assertEquals(0.0, cpuMeter.getACpuInfo().getRate(), 0.0);
+    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(8L, cpuMeter.getLastTotalTime());
-    Assert.assertEquals(1L, cpuMeter.getACpuInfo().getLastTime());
-    Assert.assertEquals(2, cpuMeter.getCpuNum());
-    Assert.assertEquals("/proc/stat", cpuMeter.getACpuInfo().getFilePath());
+    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, InterfaceInfo> interfaceInfoMap = netMeter.getInterfaceInfoMap();
+    Map<String, InterfaceUsage> interfaceInfoMap = netMeter.getInterfaceUsageMap();
     Assert.assertEquals(1, interfaceInfoMap.size());
-    InterfaceInfo eth0 = interfaceInfoMap.get("eth0");
-    Assert.assertEquals(0L, eth0.getRecvPartInterface().getLastBytes());
-    Assert.assertEquals(0L, eth0.getRecvPartInterface().getLastPackets());
-    Assert.assertEquals(0, eth0.getRecvPartInterface().getRate(), 0.0);
-    Assert.assertEquals(0, eth0.getRecvPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(0, eth0.getRecvPartInterface().getIndex());
-
-    Assert.assertEquals(0L, eth0.getSendPartInterface().getLastBytes());
-    Assert.assertEquals(0L, eth0.getSendPartInterface().getLastPackets());
-    Assert.assertEquals(0, eth0.getSendPartInterface().getRate(), 0.0);
-    Assert.assertEquals(0, eth0.getSendPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(8, eth0.getSendPartInterface().getIndex());
+    InterfaceUsage eth0 = interfaceInfoMap.get("eth0");
+    Assert.assertEquals(4, eth0.getNetStats().size());
+    // recv Bps
+    Assert.assertEquals(0L, eth0.getNetStats().get(0).getLastValue());
+    Assert.assertEquals(0, eth0.getNetStats().get(0).getRate(), 0.0);
+    Assert.assertEquals(0, eth0.getNetStats().get(0).getIndex());
+    // send Bps
+    Assert.assertEquals(0L, eth0.getNetStats().get(1).getLastValue());
+    Assert.assertEquals(0, eth0.getNetStats().get(1).getRate(), 0.0);
+    Assert.assertEquals(8, eth0.getNetStats().get(1).getIndex());
+
+    // recv pps
+    Assert.assertEquals(0L, eth0.getNetStats().get(2).getLastValue());
+    Assert.assertEquals(0, eth0.getNetStats().get(2).getRate(), 0.0);
+    Assert.assertEquals(1, eth0.getNetStats().get(2).getIndex());
+
+    // send pps
+    Assert.assertEquals(0L, eth0.getNetStats().get(3).getLastValue());
+    Assert.assertEquals(0, eth0.getNetStats().get(3).getRate(), 0.0);
+    Assert.assertEquals(9, eth0.getNetStats().get(3).getIndex());
   }
 
   @Test
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 13cd545..5b28191 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
@@ -69,31 +69,26 @@ public class TestCpuMeter {
       }
     };
     CpuMeter cpuMeter = new CpuMeter(id);
-    Assert.assertEquals(0.0, cpuMeter.getACpuInfo().getRate(), 0.0);
-    Assert.assertEquals(0.0, cpuMeter.getPCpuInfo().getRate(), 0.0);
+    Assert.assertEquals(0.0, cpuMeter.getAllCpuUsage().getUsage(), 0.0);
+    Assert.assertEquals(0.0, cpuMeter.getProcessCpuUsage().getUsage(), 0.0);
 
-    Assert.assertEquals("6666", cpuMeter.getPid());
-    Assert.assertEquals(4L, cpuMeter.getPCpuInfo().getLastTime());
-    Assert.assertEquals(8, cpuMeter.getLastTotalTime());
-    Assert.assertEquals(1, cpuMeter.getACpuInfo().getLastTime());
-    Assert.assertEquals(2, cpuMeter.getCpuNum());
-    Assert.assertEquals("/proc/stat", cpuMeter.getACpuInfo().getFilePath());
-    Assert.assertTrue(cpuMeter.getACpuInfo().isHasTotal());
+    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/6666/stat", cpuMeter.getPCpuInfo().getFilePath());
-    Assert.assertFalse(cpuMeter.getPCpuInfo().isHasTotal());
+    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");
-    cpuMeter.refreshCpu();
-    Assert.assertEquals(1.0, cpuMeter.getPCpuInfo().getRate(), 0.0);
-    Assert.assertEquals(1.75, cpuMeter.getACpuInfo().getRate(), 0.0);
-
-    Assert.assertEquals(16, cpuMeter.getLastTotalTime());
-    Assert.assertEquals(8, cpuMeter.getPCpuInfo().getLastTime());
-    Assert.assertEquals(2, cpuMeter.getACpuInfo().getLastTime());
-
-    Assert.assertEquals(2, cpuMeter.getCpuNum());
-    Assert.assertEquals("6666", cpuMeter.getPid());
+    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());
   }
 
   @Test
@@ -128,30 +123,27 @@ public class TestCpuMeter {
       }
     };
     CpuMeter cpuMeter = new CpuMeter(id);
-    Assert.assertEquals(0.0, cpuMeter.getPCpuInfo().getRate(), 0.0);
-    Assert.assertEquals("6666", cpuMeter.getPid());
-    Assert.assertEquals(4L, cpuMeter.getPCpuInfo().getLastTime());
-    Assert.assertEquals(0.0, cpuMeter.getACpuInfo().getRate(), 0.0);
-
-    Assert.assertEquals(8L, cpuMeter.getLastTotalTime());
-    Assert.assertEquals(1L, cpuMeter.getACpuInfo().getLastTime());
-    Assert.assertEquals(2, cpuMeter.getCpuNum());
-    Assert.assertEquals("/proc/stat", cpuMeter.getACpuInfo().getFilePath());
-    Assert.assertTrue(cpuMeter.getACpuInfo().isHasTotal());
-
-    Assert.assertEquals("/proc/6666/stat", cpuMeter.getPCpuInfo().getFilePath());
-    Assert.assertFalse(cpuMeter.getPCpuInfo().isHasTotal());
-    list.add(0, "cpu  1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1");
-    cpuMeter.refreshCpu();
+    Assert.assertEquals(0.0, cpuMeter.getAllCpuUsage().getUsage(), 0.0);
+    Assert.assertEquals(0.0, cpuMeter.getProcessCpuUsage().getUsage(), 0.0);
 
-    Assert.assertEquals(0.0, cpuMeter.getPCpuInfo().getRate(), 0.0);
-    Assert.assertEquals("6666", cpuMeter.getPid());
-    Assert.assertEquals(4L, cpuMeter.getPCpuInfo().getLastTime());
+    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");
+    cpuMeter.update();
 
-    Assert.assertEquals(0.0, cpuMeter.getACpuInfo().getRate(), 0.0);
-    Assert.assertEquals(8, cpuMeter.getLastTotalTime());
-    Assert.assertEquals(1, cpuMeter.getACpuInfo().getLastTime());
+    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
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestNetMeter.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestNetMeter.java
index 50cd80d..b692c7a 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestNetMeter.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestNetMeter.java
@@ -23,7 +23,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.servicecomb.metrics.core.meter.os.NetMeter.InterfaceInfo;
+import org.apache.servicecomb.metrics.core.meter.os.net.InterfaceUsage;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -51,24 +51,32 @@ public class TestNetMeter {
     list.remove(2);
     list.add("eth0: 1 1    0    0    0     0          0          1         1 1    1      0     0     0    0    0");
     netMeter.refreshNet(1);
-    Map<String, InterfaceInfo> meterInterfaceInfoMap = netMeter.getInterfaceInfoMap();
+    Map<String, InterfaceUsage> meterInterfaceInfoMap = netMeter.getInterfaceUsageMap();
     Assert.assertTrue(meterInterfaceInfoMap.containsKey("eth0"));
 
-    InterfaceInfo eth0 = meterInterfaceInfoMap.get("eth0");
+    InterfaceUsage eth0 = meterInterfaceInfoMap.get("eth0");
 
     Assert.assertEquals("eth0", eth0.getName());
 
-    Assert.assertEquals(1L, eth0.getRecvPartInterface().getLastBytes());
-    Assert.assertEquals(1L, eth0.getRecvPartInterface().getLastPackets());
-    Assert.assertEquals(1, eth0.getRecvPartInterface().getRate(), 0.0);
-    Assert.assertEquals(1, eth0.getRecvPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(0, eth0.getRecvPartInterface().getIndex());
-
-    Assert.assertEquals(1L, eth0.getSendPartInterface().getLastBytes());
-    Assert.assertEquals(1L, eth0.getSendPartInterface().getLastPackets());
-    Assert.assertEquals(1, eth0.getSendPartInterface().getRate(), 0.0);
-    Assert.assertEquals(1, eth0.getSendPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(8, eth0.getSendPartInterface().getIndex());
+    Assert.assertEquals(4, eth0.getNetStats().size());
+    // recv Bps
+    Assert.assertEquals(1L, eth0.getNetStats().get(0).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(0).getRate(), 0.0);
+    Assert.assertEquals(0, eth0.getNetStats().get(0).getIndex());
+    // send Bps
+    Assert.assertEquals(1L, eth0.getNetStats().get(1).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(1).getRate(), 0.0);
+    Assert.assertEquals(8, eth0.getNetStats().get(1).getIndex());
+
+    // recv pps
+    Assert.assertEquals(1L, eth0.getNetStats().get(2).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(2).getRate(), 0.0);
+    Assert.assertEquals(1, eth0.getNetStats().get(2).getIndex());
+
+    // send pps
+    Assert.assertEquals(1L, eth0.getNetStats().get(3).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(3).getRate(), 0.0);
+    Assert.assertEquals(9, eth0.getNetStats().get(3).getIndex());
   }
 
 
@@ -85,41 +93,57 @@ public class TestNetMeter {
       }
     };
     NetMeter netMeter = new NetMeter(id);
-    Map<String, InterfaceInfo> netMap = netMeter.getInterfaceInfoMap();
+    Map<String, InterfaceUsage> netMap = netMeter.getInterfaceUsageMap();
     Assert.assertEquals(1, netMap.size());
     list.remove(2);
     list.add("eth0: 1 1    0    0    0     0          0          1         1 1    1      0     0     0    0    0");
     list.add("lo: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0");
     netMeter.refreshNet(1);
     Assert.assertEquals(2, netMap.size());
-    InterfaceInfo eth0 = netMap.get("eth0");
+    InterfaceUsage eth0 = netMap.get("eth0");
     Assert.assertEquals("eth0", eth0.getName());
-    Assert.assertEquals(1L, eth0.getRecvPartInterface().getLastBytes());
-    Assert.assertEquals(1L, eth0.getRecvPartInterface().getLastPackets());
-    Assert.assertEquals(1, eth0.getRecvPartInterface().getRate(), 0.0);
-    Assert.assertEquals(1, eth0.getRecvPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(0, eth0.getRecvPartInterface().getIndex());
-
-    Assert.assertEquals(1L, eth0.getSendPartInterface().getLastBytes());
-    Assert.assertEquals(1L, eth0.getSendPartInterface().getLastPackets());
-    Assert.assertEquals(1, eth0.getSendPartInterface().getRate(), 0.0);
-    Assert.assertEquals(1, eth0.getSendPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(8, eth0.getSendPartInterface().getIndex());
-
-    InterfaceInfo lo = netMap.get("lo");
+    Assert.assertEquals(4, eth0.getNetStats().size());
+    // recv Bps
+    Assert.assertEquals(1L, eth0.getNetStats().get(0).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(0).getRate(), 0.0);
+    Assert.assertEquals(0, eth0.getNetStats().get(0).getIndex());
+    // send Bps
+    Assert.assertEquals(1L, eth0.getNetStats().get(1).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(1).getRate(), 0.0);
+    Assert.assertEquals(8, eth0.getNetStats().get(1).getIndex());
+
+    // recv pps
+    Assert.assertEquals(1L, eth0.getNetStats().get(2).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(2).getRate(), 0.0);
+    Assert.assertEquals(1, eth0.getNetStats().get(2).getIndex());
+
+    // send pps
+    Assert.assertEquals(1L, eth0.getNetStats().get(3).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(3).getRate(), 0.0);
+    Assert.assertEquals(9, eth0.getNetStats().get(3).getIndex());
+
+    InterfaceUsage lo = netMap.get("lo");
     Assert.assertEquals("lo", lo.getName());
 
-    Assert.assertEquals(0L, lo.getRecvPartInterface().getLastBytes());
-    Assert.assertEquals(0L, lo.getRecvPartInterface().getLastPackets());
-    Assert.assertEquals(0, lo.getRecvPartInterface().getRate(), 0.0);
-    Assert.assertEquals(0, lo.getRecvPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(0, lo.getRecvPartInterface().getIndex());
-
-    Assert.assertEquals(0L, lo.getSendPartInterface().getLastBytes());
-    Assert.assertEquals(0L, lo.getSendPartInterface().getLastPackets());
-    Assert.assertEquals(0, lo.getSendPartInterface().getRate(), 0.0);
-    Assert.assertEquals(0, lo.getSendPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(8, lo.getSendPartInterface().getIndex());
+    Assert.assertEquals(4, lo.getNetStats().size());
+    // recv Bps
+    Assert.assertEquals(0L, lo.getNetStats().get(0).getLastValue());
+    Assert.assertEquals(0, lo.getNetStats().get(0).getRate(), 0.0);
+    Assert.assertEquals(0, lo.getNetStats().get(0).getIndex());
+    // send Bps
+    Assert.assertEquals(0L, lo.getNetStats().get(1).getLastValue());
+    Assert.assertEquals(0, lo.getNetStats().get(1).getRate(), 0.0);
+    Assert.assertEquals(8, lo.getNetStats().get(1).getIndex());
+
+    // recv pps
+    Assert.assertEquals(0L, lo.getNetStats().get(2).getLastValue());
+    Assert.assertEquals(0, lo.getNetStats().get(2).getRate(), 0.0);
+    Assert.assertEquals(1, lo.getNetStats().get(2).getIndex());
+
+    // send pps
+    Assert.assertEquals(0L, lo.getNetStats().get(3).getLastValue());
+    Assert.assertEquals(0, lo.getNetStats().get(3).getRate(), 0.0);
+    Assert.assertEquals(9, lo.getNetStats().get(3).getIndex());
   }
 
 
@@ -137,35 +161,51 @@ public class TestNetMeter {
       }
     };
     NetMeter netMeter = new NetMeter(id);
-    Map<String, InterfaceInfo> netMap = netMeter.getInterfaceInfoMap();
+    Map<String, InterfaceUsage> netMap = netMeter.getInterfaceUsageMap();
     Assert.assertEquals(2, netMap.size());
-    InterfaceInfo lo = netMap.get("lo");
-    InterfaceInfo eth0 = netMap.get("eth0");
+    InterfaceUsage lo = netMap.get("lo");
+    InterfaceUsage eth0 = netMap.get("eth0");
     Assert.assertEquals("lo", lo.getName());
-    Assert.assertEquals(0L, lo.getRecvPartInterface().getLastBytes());
-    Assert.assertEquals(0L, lo.getRecvPartInterface().getLastPackets());
-    Assert.assertEquals(0, lo.getRecvPartInterface().getRate(), 0.0);
-    Assert.assertEquals(0, lo.getRecvPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(0, lo.getRecvPartInterface().getIndex());
-
-    Assert.assertEquals(0L, lo.getSendPartInterface().getLastBytes());
-    Assert.assertEquals(0L, lo.getSendPartInterface().getLastPackets());
-    Assert.assertEquals(0, lo.getSendPartInterface().getRate(), 0.0);
-    Assert.assertEquals(0, lo.getSendPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(8, lo.getSendPartInterface().getIndex());
+    Assert.assertEquals(4, lo.getNetStats().size());
+    // recv Bps
+    Assert.assertEquals(0L, lo.getNetStats().get(0).getLastValue());
+    Assert.assertEquals(0, lo.getNetStats().get(0).getRate(), 0.0);
+    Assert.assertEquals(0, lo.getNetStats().get(0).getIndex());
+    // send Bps
+    Assert.assertEquals(0L, lo.getNetStats().get(1).getLastValue());
+    Assert.assertEquals(0, lo.getNetStats().get(1).getRate(), 0.0);
+    Assert.assertEquals(8, lo.getNetStats().get(1).getIndex());
+
+    // recv pps
+    Assert.assertEquals(0L, lo.getNetStats().get(2).getLastValue());
+    Assert.assertEquals(0, lo.getNetStats().get(2).getRate(), 0.0);
+    Assert.assertEquals(1, lo.getNetStats().get(2).getIndex());
+
+    // send pps
+    Assert.assertEquals(0L, lo.getNetStats().get(3).getLastValue());
+    Assert.assertEquals(0, lo.getNetStats().get(3).getRate(), 0.0);
+    Assert.assertEquals(9, lo.getNetStats().get(3).getIndex());
 
     Assert.assertEquals("eth0", eth0.getName());
-    Assert.assertEquals(0L, eth0.getRecvPartInterface().getLastBytes());
-    Assert.assertEquals(0L, eth0.getRecvPartInterface().getLastPackets());
-    Assert.assertEquals(0, eth0.getRecvPartInterface().getRate(), 0.0);
-    Assert.assertEquals(0, eth0.getRecvPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(0, eth0.getRecvPartInterface().getIndex());
-
-    Assert.assertEquals(0L, eth0.getSendPartInterface().getLastBytes());
-    Assert.assertEquals(0L, eth0.getSendPartInterface().getLastPackets());
-    Assert.assertEquals(0, eth0.getSendPartInterface().getRate(), 0.0);
-    Assert.assertEquals(0, eth0.getSendPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(8, eth0.getSendPartInterface().getIndex());
+    Assert.assertEquals(4, eth0.getNetStats().size());
+    // recv Bps
+    Assert.assertEquals(0L, eth0.getNetStats().get(0).getLastValue());
+    Assert.assertEquals(0, eth0.getNetStats().get(0).getRate(), 0.0);
+    Assert.assertEquals(0, eth0.getNetStats().get(0).getIndex());
+    // send Bps
+    Assert.assertEquals(0L, eth0.getNetStats().get(1).getLastValue());
+    Assert.assertEquals(0, eth0.getNetStats().get(1).getRate(), 0.0);
+    Assert.assertEquals(8, eth0.getNetStats().get(1).getIndex());
+
+    // recv pps
+    Assert.assertEquals(0L, eth0.getNetStats().get(2).getLastValue());
+    Assert.assertEquals(0, eth0.getNetStats().get(2).getRate(), 0.0);
+    Assert.assertEquals(1, eth0.getNetStats().get(2).getIndex());
+
+    // send pps
+    Assert.assertEquals(0L, eth0.getNetStats().get(3).getLastValue());
+    Assert.assertEquals(0, eth0.getNetStats().get(3).getRate(), 0.0);
+    Assert.assertEquals(9, eth0.getNetStats().get(3).getIndex());
     list.remove(2);
     list.remove(2);
     list.add("eth0: 1 1    0    0    0     0          0          1         1 1    1      0     0     0    0    0");
@@ -173,17 +213,25 @@ public class TestNetMeter {
     Assert.assertNull(netMap.get("lo"));
     Assert.assertEquals(1, netMap.size());
     Assert.assertEquals("eth0", eth0.getName());
-    Assert.assertEquals(1L, eth0.getRecvPartInterface().getLastBytes());
-    Assert.assertEquals(1L, eth0.getRecvPartInterface().getLastPackets());
-    Assert.assertEquals(1, eth0.getRecvPartInterface().getRate(), 0.0);
-    Assert.assertEquals(1, eth0.getRecvPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(0, eth0.getRecvPartInterface().getIndex());
-
-    Assert.assertEquals(1L, eth0.getSendPartInterface().getLastBytes());
-    Assert.assertEquals(1L, eth0.getSendPartInterface().getLastPackets());
-    Assert.assertEquals(1, eth0.getSendPartInterface().getRate(), 0.0);
-    Assert.assertEquals(1, eth0.getSendPartInterface().getPacketsRate(), 0.0);
-    Assert.assertEquals(8, eth0.getSendPartInterface().getIndex());
+    Assert.assertEquals(4, eth0.getNetStats().size());
+    // recv Bps
+    Assert.assertEquals(1L, eth0.getNetStats().get(0).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(0).getRate(), 0.0);
+    Assert.assertEquals(0, eth0.getNetStats().get(0).getIndex());
+    // send Bps
+    Assert.assertEquals(1L, eth0.getNetStats().get(1).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(1).getRate(), 0.0);
+    Assert.assertEquals(8, eth0.getNetStats().get(1).getIndex());
+
+    // recv pps
+    Assert.assertEquals(1L, eth0.getNetStats().get(2).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(2).getRate(), 0.0);
+    Assert.assertEquals(1, eth0.getNetStats().get(2).getIndex());
+
+    // send pps
+    Assert.assertEquals(1L, eth0.getNetStats().get(3).getLastValue());
+    Assert.assertEquals(1, eth0.getNetStats().get(3).getRate(), 0.0);
+    Assert.assertEquals(9, eth0.getNetStats().get(3).getIndex());
   }
 
 
@@ -201,17 +249,17 @@ public class TestNetMeter {
     };
     NetMeter netMeter = new NetMeter(id);
     list.remove(2);
-    list.add("eth0: 1 1    0    0    0     0          0          1         1 1    1      0     0     0    0    0");
+    list.add("eth0: 3 1    0    0    0     0          0          1         3 1    1      0     0     0    0    0");
     List<Measurement> measurements = new ArrayList<>();
     netMeter.calcMeasurements(measurements, 0L, 1);
     Assert.assertEquals(4, measurements.size());
-    Measurement send = measurements.get(0);
-    Measurement sendPackets = measurements.get(1);
     Measurement receive = measurements.get(0);
-    Measurement receivePackets = measurements.get(1);
-    Assert.assertEquals(1.0, send.value(), 0.0);
+    Measurement send = measurements.get(1);
+    Measurement receivePackets = measurements.get(2);
+    Measurement sendPackets = measurements.get(3);
+    Assert.assertEquals(3.0, send.value(), 0.0);
     Assert.assertEquals(1.0, sendPackets.value(), 0.0);
-    Assert.assertEquals(1.0, receive.value(), 0.0);
+    Assert.assertEquals(3.0, receive.value(), 0.0);
     Assert.assertEquals(1.0, receivePackets.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 95e00db..20d743c 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
@@ -180,7 +180,6 @@ public class TestDefaultLogPublisher {
     model.getThreadPools().put("test", new ThreadPoolPublishModel());
     Measurement measurement = new Measurement(null, 0L, 1.0);
 
-    MeasurementNode measurementNodeCpu = new MeasurementNode("cpu", new HashMap<>());
     MeasurementNode measurementNodeCpuAll = new MeasurementNode("allProcess", new HashMap<>());
     MeasurementNode measurementNodeCpuProcess = new MeasurementNode("currentProcess", new HashMap<>());
     MeasurementNode measurementNodeSend = new MeasurementNode("send", new HashMap<>());
@@ -198,23 +197,20 @@ public class TestDefaultLogPublisher {
     measurementNodeRecvPacket.getMeasurements().add(measurement);
     measurementNodeSendPacket.getMeasurements().add(measurement);
 
-    measurementNodeCpu.getChildren().put("allProcess", measurementNodeCpuAll);
-    measurementNodeCpu.getChildren().put("currentProcess", measurementNodeCpuProcess);
     measurementNodeEth0.getChildren().put("send", measurementNodeSend);
     measurementNodeEth0.getChildren().put("receive", measurementNodeRecv);
     measurementNodeEth0.getChildren().put("receivePackets", measurementNodeRecvPacket);
     measurementNodeEth0.getChildren().put("sendPackets", measurementNodeSendPacket);
 
     measurementNodeNet.getChildren().put("eth0", measurementNodeEth0);
-    measurementNodeOs.getChildren().put("cpu", measurementNodeCpu);
+    measurementNodeOs.getChildren().put("cpu", measurementNodeCpuAll);
+    measurementNodeOs.getChildren().put("processCpu", measurementNodeCpuProcess);
     measurementNodeOs.getChildren().put("net", measurementNodeNet);
 
     measurementNodeOs.getMeasurements().add(measurement);
     measurementNodeNet.getMeasurements().add(measurement);
-    measurementNodeCpu.getMeasurements().add(measurement);
     measurementNodeEth0.getMeasurements().add(measurement);
 
-
     new MockUp<PublishModelFactory>() {
       @Mock
       DefaultPublishModel createDefaultPublishModel() {