You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ma...@apache.org on 2023/03/11 13:20:59 UTC
[iotdb] branch IOTDB-5663 updated: implement LinuxNetMetricManager
This is an automated email from the ASF dual-hosted git repository.
marklau99 pushed a commit to branch IOTDB-5663
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/IOTDB-5663 by this push:
new 8092301cea implement LinuxNetMetricManager
8092301cea is described below
commit 8092301ceab3f989b538b1267fdf512f65801bfc
Author: LiuXuxin <li...@outlook.com>
AuthorDate: Sat Mar 11 21:20:51 2023 +0800
implement LinuxNetMetricManager
---
.../metricsets/net/LinuxNetMetricManager.java | 178 ++++++++++++++++++++-
1 file changed, 177 insertions(+), 1 deletion(-)
diff --git a/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/LinuxNetMetricManager.java b/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/LinuxNetMetricManager.java
index 0c9c3da024..800e39c685 100644
--- a/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/LinuxNetMetricManager.java
+++ b/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/LinuxNetMetricManager.java
@@ -19,4 +19,180 @@
package org.apache.iotdb.metrics.metricsets.net;
-public class LinuxNetMetricManager implements INetMetricManager {}
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class LinuxNetMetricManager implements INetMetricManager {
+ private final Logger log = LoggerFactory.getLogger(LinuxNetMetricManager.class);
+
+ @SuppressWarnings("squid:S1075")
+ private static final String IFACE_ID_PATH = "/sys/class/net/";
+
+ @SuppressWarnings("squid:S1075")
+ private static final String NET_STATUS_PATH = "/proc/net/dev";
+
+ private static final String BYTES = "bytes";
+ private static final String PACKETS = "packets";
+ private static final long UPDATE_INTERVAL = 10_000L;
+
+ private static final int IFACE_NAME_INDEX = 0;
+ // initialized after reading status file
+ private static int RECEIVED_BYTES_INDEX = 0;
+ private static int TRANSMITTED_BYTES_INDEX = 0;
+ private static int RECEIVED_PACKETS_INDEX = 0;
+ private static int TRANSMITTED_PACKETS_INDEX = 0;
+ private Set<String> iFaceSet;
+
+ private final Map<String, Long> receivedBytesMapForIface;
+ private final Map<String, Long> transmittedBytesMapForIface;
+ private final Map<String, Long> receivedPacketsMapForIface;
+ private final Map<String, Long> transmittedPacketsMapForIface;
+
+ public LinuxNetMetricManager() {
+ collectIfaces();
+ // leave one entry to avoid hashmap resizing
+ receivedBytesMapForIface = new HashMap<>(iFaceSet.size() + 1, 1);
+ transmittedBytesMapForIface = new HashMap<>(iFaceSet.size() + 1, 1);
+ receivedPacketsMapForIface = new HashMap<>(iFaceSet.size() + 1, 1);
+ transmittedPacketsMapForIface = new HashMap<>(iFaceSet.size() + 1, 1);
+ collectNetStatusIndex();
+ }
+
+ private long lastUpdateTime = 0L;
+
+ @Override
+ public Set<String> getIfaceSet() {
+ checkUpdate();
+ return iFaceSet;
+ }
+
+ @Override
+ public Map<String, Long> getReceivedByte() {
+ checkUpdate();
+ return receivedBytesMapForIface;
+ }
+
+ @Override
+ public Map<String, Long> getTransmittedBytes() {
+ checkUpdate();
+ return transmittedBytesMapForIface;
+ }
+
+ @Override
+ public Map<String, Long> getReceivedPackets() {
+ checkUpdate();
+ return receivedPacketsMapForIface;
+ }
+
+ @Override
+ public Map<String, Long> getTransmittedPackets() {
+ checkUpdate();
+ return transmittedPacketsMapForIface;
+ }
+
+ private void checkUpdate() {
+ if (System.currentTimeMillis() - lastUpdateTime >= UPDATE_INTERVAL) {
+ updateNetStatus();
+ }
+ }
+
+ private void collectIfaces() {
+ File iFaceIdFolder = new File(IFACE_ID_PATH);
+ if (!iFaceIdFolder.exists()) {
+ iFaceSet = Collections.emptySet();
+ log.warn("Cannot find {}", IFACE_ID_PATH);
+ return;
+ }
+ iFaceSet =
+ new ArrayList<>(Arrays.asList(Objects.requireNonNull(iFaceIdFolder.listFiles())))
+ .stream().map(File::getName).collect(Collectors.toSet());
+ }
+
+ private void collectNetStatusIndex() {
+ File netStatusFile = new File(NET_STATUS_PATH);
+ if (!netStatusFile.exists()) {
+ log.warn("Cannot find {}", NET_STATUS_PATH);
+ return;
+ }
+ try (FileInputStream inputStream = new FileInputStream(netStatusFile)) {
+ Scanner scanner = new Scanner(inputStream);
+ // skip the first line
+ scanner.nextLine();
+ String headerLine = scanner.nextLine();
+ String[] seperatedHeaderLine = headerLine.split("\\|");
+ String[] receiveStatusHeader = seperatedHeaderLine[1].split("\\s+");
+ String[] transmitStatusHeader = seperatedHeaderLine[2].split("\\s+");
+ for (int i = 0, length = receiveStatusHeader.length; i < length; ++i) {
+ if (receiveStatusHeader[i].equals(BYTES)) {
+ RECEIVED_BYTES_INDEX = i + 1;
+ } else if (receiveStatusHeader[i].equals(PACKETS)) {
+ RECEIVED_PACKETS_INDEX = i + 1;
+ }
+ }
+ for (int i = 0, length = transmitStatusHeader.length; i < length; ++i) {
+ if (transmitStatusHeader[i].equals(BYTES)) {
+ TRANSMITTED_BYTES_INDEX = i + length + 1;
+ } else if (transmitStatusHeader[i].equals(PACKETS)) {
+ TRANSMITTED_PACKETS_INDEX = i + length + 1;
+ }
+ }
+ } catch (IOException e) {
+ log.error("Meets exception when reading {}", NET_STATUS_PATH, e);
+ }
+ }
+
+ private void updateNetStatus() {
+ lastUpdateTime = System.currentTimeMillis();
+ File netStatusFile = new File(NET_STATUS_PATH);
+ if (!netStatusFile.exists()) {
+ return;
+ }
+ try (FileInputStream inputStream = new FileInputStream(netStatusFile)) {
+ Scanner scanner = new Scanner(inputStream);
+ // skip the starting two lines
+ // because they are the meta info
+ scanner.nextLine();
+ scanner.nextLine();
+
+ // reading the actual status info for iface
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ // we wrap the string array as array list to execute the removing step
+ List<String> statusInfoAsList = new ArrayList<>(Arrays.asList(line.split("\\s")));
+ // remove all empty string
+ statusInfoAsList.removeIf(x -> x.equals(""));
+
+ String iface = statusInfoAsList.get(IFACE_NAME_INDEX);
+ // since the read iface format is "IFACE:"
+ // we need to remove the last letter
+ iface = iface.substring(0, iface.length() - 1);
+
+ long receivedBytes = Long.parseLong(statusInfoAsList.get(RECEIVED_BYTES_INDEX));
+ long transmittedBytes = Long.parseLong(statusInfoAsList.get(TRANSMITTED_BYTES_INDEX));
+ long receivedPackets = Long.parseLong(statusInfoAsList.get(RECEIVED_PACKETS_INDEX));
+ long transmittedPackets = Long.parseLong(statusInfoAsList.get(TRANSMITTED_PACKETS_INDEX));
+
+ receivedBytesMapForIface.put(iface, receivedBytes);
+ transmittedBytesMapForIface.put(iface, transmittedBytes);
+ receivedPacketsMapForIface.put(iface, receivedPackets);
+ transmittedPacketsMapForIface.put(iface, transmittedPackets);
+ }
+ } catch (IOException e) {
+ log.error("Meets error when reading {} for net status", NET_STATUS_PATH, e);
+ }
+ }
+}