インターフェイス固有の統計を取得するには、既に提案されている方法がうまく機能します。
代わりに、2 番目のリクエストの解決策を提案します。
また、どのプログラムがその帯域幅を使用していたかを知ることも非常に役立ちますが、これまでのところ、それを行うことができるものは見たことがありません.
すでに示唆されているように、nethogsはプロセス固有の統計情報を出力します。私の知る限りでは、これらの値に簡単/proc
にアクセスする方法はありません。
pid PID を持つ 1 つのプロセスを考えると、nethogs は最初にプロセスによって開かれたすべてのソケットのリストを取得し、/proc/PID/fd の内容をリストします。
➜ ~ [1] at 23:59:31 [Sat 15] $ ls -la /proc/21841/fd
total 0
dr-x------ 2 marco marco 0 Nov 15 23:41 .
dr-xr-xr-x 8 marco marco 0 Nov 15 23:41 ..
lrwx------ 1 marco marco 64 Nov 15 23:42 0 -> /dev/pts/15
l-wx------ 1 marco marco 64 Nov 15 23:42 1 -> /dev/null
lrwx------ 1 marco marco 64 Nov 15 23:41 2 -> /dev/pts/15
lrwx------ 1 marco marco 64 Nov 15 23:42 4 -> socket:[177472]
ここではソケットが 1 つだけあり、177472 が inode 番号です。ここには、TCPv4、TCPv6、UDP、netlink など、あらゆる種類のソケットがあります。この場合、TCPv4 のみを検討します。
すべての inode 番号が収集されると、各ソケットに一意の識別子、つまり が割り当てられます(IP_SRC, PORT_SRC, IP_DEST, PORT_DEST)
。もちろん、PID とのペアリングも保存されます。タプル(IP_SRC, PORT_SRC, IP_DEST, PORT_DEST)
は読み取りで取得できます/proc/net/tcp
(TCPv4 の場合)。この場合:
➜ ~ [1] at 0:06:05 [Sun 16] $ cat /proc/net/tcp | grep 177472
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
38: 1D00A8C0:1F90 0400A8C0:A093 01 00000000:00000000 00:00000000 00000000 1000 0 177472 1 f6fae080 21 4 0 10 5
アドレスは IP:PORT として表され、IP は 4 バイトの LE 番号として表されます。key->value
次に、キーが(IP_SRC, PORT_SRC, IP_DEST, PORT_DEST)
PID で値が PIDである構造を構築できます。
この時点で、nethogs は libpcap を使用してすべてのネットワーク トラフィックをキャプチャします。(IP_SRC_PACKET, PORT_SRC_PACKET, IP_DEST_PACKET, PORT_DEST_PACKET)
TCP パケットを検出すると、テーブル内のすべての接続に対してタプルを照合しようとします。もちろん、SRC と DEST の交換を試みる必要があります。パケットは着信 (DL) または発信 (UL) の可能性があります。接続を照合すると、接続が属するプロセスの PID を取得し、TCP ペイロードのサイズを TX または RX カウンターに追加します。パケットをキャプチャするたびにバイト数が更新されるため、各プロセスの転送速度を簡単に計算できます。
これは、多少の作業が必要ですが、理論的には pypcap を使用して Python で実装できます。私は何かを実装しようとしましたが、非常に遅く、使用できるようにするにはさらに多くの作業が必要です。接続テーブルを更新せずに、1 つの接続で 1 つの PID だけを監視していましたが、3MB/s を超えると、スクリプトがネットワーク トラフィックに対応できなくなりました。
ご覧のとおり、それほど簡単ではありません。既に利用可能なツールの出力を解析すると、より良い解決策につながり、多くの作業を節約できる可能性があります。