如何测量一个命令使用的网络流量?

如何测量一个命令使用的网络流量?

我经常写:

time npm install

这将给我以下结果:

real    0m22.933s
user    0m24.058s
sys     0m3.346s

我希望获得相同类型的信息,但用于网络消费。

例如,

netmeasure npm install

将返回:

Upload : 499kb
Download : 44MB

对某些程序进行“回归测试”将会很有用。

是否可以使用简单的 UNIX 工具获取此类信息?

我已经尝试过了nethogs,但它是一种非常具有交互性的程序,如果你想知道一个完整的 unix 系统上发生了什么,它可能很有用,但我对测量一个命令的网络消耗感兴趣。我不是在寻找一个交互式程序,而是一个可以帮我生成进程并等到它存在时才显示这些统计数据的程序。

我已经发现https://github.com/jonasdn/nsntrace这看起来像是一个不错的工具,但在 nsntrace 中,我没有连接(请参阅问题https://github.com/jonasdn/nsntrace/issues/22

答案1

我还建议在网络命名空间内运行所需的程序,这正是该nstrace工具所做的,尽管我不明白为什么他们不简单地编写命名空间的设置脚本。

nsntrace工具需要转发,并用于iptables将 veth-pair 连接伪装成主网络命名空间的传出接口。很可能出错了,因为它所做的与您的互联网设置不兼容。尤其是网络命名空间中的名称服务器问题有点棘手。

因此我建议您阅读有关网络命名空间(ip netns)、伪装iptables和 DNS 解析器(/etc/resolv.conf/etc/netns/NAME/resolv.conf)的资料,以便能够找出到底出了什么问题。

下面是我用来设置网络命名空间并在此命名空间“内部”启动 xterm 的脚本,希望它能有所帮助:

#!/bin/bash

# Setup network namespace with veth pair, start xterm in it

# nsterm ns0 veth0 10.0.0 yellow 24

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

NS=${1:-ns0}
DEV=${2:-veth0}
DEV_A=${DEV}a
DEV_B=${DEV}b
ADDR=${3-:10.0.0}
ADDR_A=${ADDR}.254
ADDR_B=${ADDR}.1
MASK=${5:-24}
COL=${4:-yellow}

# echo ns=$NS dev=$DEV col=$COL mask=$MASK

ip netns add $NS
ip link add $DEV_A type veth peer name $DEV_B netns $NS
ip addr add $ADDR_A/$MASK dev $DEV_A
ip link set ${DEV}a up
ip netns exec $NS ip addr add $ADDR_B/$MASK dev $DEV_B
ip netns exec $NS ip link set ${DEV}b up
ip netns exec $NS ip route add default via $ADDR_A dev $DEV_B
ip netns exec $NS su -c "xterm -bg $COL &" YOUR_USERNAME

根据需要进行调整(在您阅读并了解其功能后)。您仍然需要启用转发

echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward

并以任何需要的形式设置伪装。

恐怕我想不出一个更简单的解决方案来测量准确的网络使用情况。

答案2

你可以用一些基本命令得到近似值。可能nstrace更好,但我在我的发行版中找不到它。

您需要做的就是检查应用程序使用的系统调用。想要从网络读取的应用程序需要调用来自recv或 系列的某些东西read。如果您想发送某些东西,则使用writesend系列系统调用。我们的启发式方法将跳过readwrite,因为单行代码很难分析。

因此,我们开始吧:

  1. 将应用程序使用的系统调用保存到文件中:strace myapp 2>syscalls
  2. grep所需的系统调用(在本例中为发送),获取其返回值(符号后的最后一块数字=),并计算其总和。grep "send" syscalls | grep -E --only-matching "= [0-9]+$" | awk '{ print $2 }' | paste -sd+ | bc

我重申:这句话将不是总是给你正确的结果,但大多数时候都应该有效。

相关内容