This is an automated email from the ASF dual-hosted git repository. haonan pushed a commit to branch new_win_metric in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit b91bff69851e5e658511d2f2ab25b90af9e7b878 Author: HTHou <[email protected]> AuthorDate: Thu Mar 12 16:42:48 2026 +0800 previous work --- .../metrics/file/SystemRelatedFileMetrics.java | 20 ++- .../metricsets/net/WindowsNetMetricManager.java | 184 ++++++++++++++++++++- 2 files changed, 202 insertions(+), 2 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/file/SystemRelatedFileMetrics.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/file/SystemRelatedFileMetrics.java index 3fac0d10a16..aa529fc4672 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/file/SystemRelatedFileMetrics.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/file/SystemRelatedFileMetrics.java @@ -29,6 +29,11 @@ import org.apache.iotdb.metrics.utils.MetricLevel; import org.apache.iotdb.metrics.utils.MetricType; import org.apache.iotdb.metrics.utils.SystemType; +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.ptr.IntByReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,7 +57,9 @@ public class SystemRelatedFileMetrics implements IMetricSet { @Override public void bindTo(AbstractMetricService metricService) { - if ((CONFIG.getSystemType() == SystemType.LINUX || CONFIG.getSystemType() == SystemType.MAC) + if ((CONFIG.getSystemType() == SystemType.LINUX + || CONFIG.getSystemType() == SystemType.MAC + || CONFIG.getSystemType() == SystemType.WINDOWS) && !CONFIG.getPid().isEmpty()) { this.getOpenFileNumberCommand = new String[] {"/bin/sh", "-c", String.format("lsof -p %s | wc -l", CONFIG.getPid())}; @@ -88,6 +95,11 @@ public class SystemRelatedFileMetrics implements IMetricSet { } } fdCount = Long.parseLong(result.toString().trim()); + } else if (CONFIG.getSystemType() == SystemType.WINDOWS) { + WinNT.HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess(); + IntByReference handleCount = new IntByReference(); + boolean success = Kernel32Ext.INSTANCE.GetProcessHandleCount(hProcess, handleCount); + return success ? handleCount.getValue() : 0L; } } catch (IOException e) { LOGGER.warn("Failed to get open file number, because ", e); @@ -106,4 +118,10 @@ public class SystemRelatedFileMetrics implements IMetricSet { "open_file_handlers"); } } + + public interface Kernel32Ext extends Library { + Kernel32Ext INSTANCE = Native.load("kernel32", Kernel32Ext.class); + + boolean GetProcessHandleCount(WinNT.HANDLE hProcess, IntByReference pdwHandleCount); + } } diff --git a/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/WindowsNetMetricManager.java b/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/WindowsNetMetricManager.java index c3ecb4b8d50..965d4387af6 100644 --- a/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/WindowsNetMetricManager.java +++ b/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/WindowsNetMetricManager.java @@ -19,4 +19,186 @@ package org.apache.iotdb.metrics.metricsets.net; -public class WindowsNetMetricManager implements INetMetricManager {} +import org.apache.iotdb.metrics.MetricConstant; +import org.apache.iotdb.metrics.config.MetricConfig; +import org.apache.iotdb.metrics.config.MetricConfigDescriptor; +import org.apache.iotdb.metrics.utils.MetricLevel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class WindowsNetMetricManager implements INetMetricManager { + private static final Logger LOGGER = LoggerFactory.getLogger(WindowsNetMetricManager.class); + + private static final MetricConfig METRIC_CONFIG = + MetricConfigDescriptor.getInstance().getMetricConfig(); + + private long lastUpdateTime = 0L; + + private Set<String> ifaceSet = new HashSet<>(); + + private final Map<String, Long> receivedBytesMapForIface = new HashMap<>(); + + private final Map<String, Long> transmittedBytesMapForIface = new HashMap<>(); + + private final Map<String, Long> receivedPacketsMapForIface = new HashMap<>(); + + private final Map<String, Long> transmittedPacketsMapForIface = new HashMap<>(); + + private int connectionNum = 0; + + public WindowsNetMetricManager() { + checkUpdate(); + } + + @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; + } + + @Override + public int getConnectionNum() { + checkUpdate(); + return connectionNum; + } + + private void checkUpdate() { + if (System.currentTimeMillis() - lastUpdateTime >= MetricConstant.UPDATE_INTERVAL) { + updateNetStatus(); + } + } + + private void updateNetStatus() { + lastUpdateTime = System.currentTimeMillis(); + updateInterfaces(); + updateStatistics(); + if (MetricLevel.higherOrEqual(MetricLevel.NORMAL, METRIC_CONFIG.getMetricLevel())) { + updateConnectionNum(); + } + } + + private void updateInterfaces() { + try { + Process process = + Runtime.getRuntime() + .exec( + "cmd.exe /c chcp 65001 > nul & powershell.exe -Command \"Get-NetAdapter | Select Name | Format-List \""); + BufferedReader reader = + new BufferedReader( + new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)); + String line; + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (line.startsWith("Name :")) { + ifaceSet.add(line.substring("Name : ".length()).trim()); + } + } + int exitCode = process.waitFor(); + if (exitCode != 0) { + LOGGER.error("Failed to get interfaces, exit code: {}", exitCode); + } + } catch (IOException | InterruptedException e) { + LOGGER.error("Error updating interfaces", e); + ifaceSet = Collections.emptySet(); + } + } + + private void updateStatistics() { + try { + Process process = + Runtime.getRuntime() + .exec( + "cmd.exe /c chcp 65001 > nul & powershell.exe -Command \"Get-NetAdapterStatistics | Format-List Name,ReceivedBytes,SentBytes,ReceivedUnicastPackets,SentUnicastPackets \""); + BufferedReader reader = + new BufferedReader( + new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)); + String line; + String currentName = null; + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (line.startsWith("Name ")) { + currentName = line.substring(line.indexOf(": ") + 2).trim(); + } else if (line.startsWith("ReceivedBytes ") && currentName != null) { + long value = Long.parseLong(line.substring(line.indexOf(": ") + 2).trim()); + receivedBytesMapForIface.put(currentName, value); + } else if (line.startsWith("SentBytes ") && currentName != null) { + long value = Long.parseLong(line.substring(line.indexOf(": ") + 2).trim()); + transmittedBytesMapForIface.put(currentName, value); + } else if (line.startsWith("ReceivedUnicastPackets ") && currentName != null) { + long value = Long.parseLong(line.substring(line.indexOf(": ") + 2).trim()); + receivedPacketsMapForIface.put(currentName, value); + } else if (line.startsWith("SentUnicastPackets ") && currentName != null) { + long value = Long.parseLong(line.substring(line.indexOf(": ") + 2).trim()); + transmittedPacketsMapForIface.put(currentName, value); + currentName = null; // Reset after processing an interface + } + } + int exitCode = process.waitFor(); + if (exitCode != 0) { + LOGGER.error("Failed to get statistics, exit code: {}", exitCode); + } + } catch (IOException | InterruptedException | NumberFormatException e) { + LOGGER.error("Error updating statistics", e); + } + } + + private void updateConnectionNum() { + try { + Process process = Runtime.getRuntime().exec("netstat -ano"); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + int count = 0; + String line; + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (!line.isEmpty() && !line.startsWith("Active") && !line.startsWith("Proto")) { + String[] parts = line.split("\\s+"); + if (parts.length >= 5 && parts[parts.length - 1].equals(METRIC_CONFIG.getPid())) { + count++; + } + } + } + this.connectionNum = count; + int exitCode = process.waitFor(); + if (exitCode != 0) { + LOGGER.error("Failed to get connection num, exit code: {}", exitCode); + } + } catch (IOException | InterruptedException e) { + LOGGER.error("Error updating connection num", e); + } + } +}
