CLI AI

Какой процесс съедает канал — без nethogs

2026-08-25

ss -tnp показывает все соединения вместе с процессами, которые их держат, а ss -ti добавляет счётчики байтов по каждому сокету. Вместе это даёт трафик в привязке к процессу без установки чего бы то ни было — а это важно на чужом сервере, внутри контейнера и везде, где нет root, чтобы доставить пакет.

1. Кто подключён и чей это процесс

clai
$ clai покажи установленные соединения вместе с процессами→ ss -tnp 'sport = :8099 or dport = :8099'State Recv-Q Send-Q  Local Address:Port  Peer Address:Port Process                              ESTAB 0      4190912     127.0.0.1:8099     127.0.0.1:52080 users:(("python3",pid=1120102,fd=4))ESTAB 324447 0           127.0.0.1:52080    127.0.0.1:8099  users:(("curl",pid=1120130,fd=4))

Колонка Process сразу даёт имя и pid. Send-Q в четыре мегабайта на отдающей стороне — это данные, которые приложение уже записало, а сеть ещё не забрала: надёжный признак, что именно этот сокет и забивает канал.

2. Сколько байт прошло через один сокет

clai
$ clai покажи, сколько байт передано по этому соединению→ ss -tin 'dport = :8099' | grep -oE 'bytes_sent:[0-9]+|bytes_received:[0-9]+'bytes_sent:85bytes_received:8579963

Вот ради чего всё это. -i добавляет внутреннюю статистику TCP, а в ней есть счётчики байтов по сокету. Это и есть «трафик по процессам» без nethogs: предыдущая команда уже связала сокет с pid.

3. Общие счётчики интерфейса

clai
$ clai покажи счётчики трафика интерфейса lo→ grep -E '^\s*lo:' /proc/net/dev | awk '{print "rx_bytes="$2, "tx_bytes="$10}'rx_bytes=581097986 tx_bytes=581097986

/proc/net/dev есть в любой системе Linux, включая контейнеры. Это счётчики с момента загрузки, поэтому сами по себе они ничего не значат — смысл появляется в разнице между двумя замерами.

4. Скорость за одну секунду

clai
$ clai посчитай скорость передачи на lo за одну секунду→ a=$(awk '/^ *lo:/{print $10}' /proc/net/dev); sleep 1; b=$(awk '/^ *lo:/{print $10}' /proc/net/dev); echo "$(( (b-a)/1024 )) KB/s"4764 KB/s

Два замера с паузой в секунду — весь принцип, на котором работает любой измеритель скорости. Замените lo на eth0 или enp5s0.

5. Топ процессов по числу соединений

clai
$ clai покажи, у каких процессов больше всего соединений→ ss -tnp | awk 'NR>1 {match($0,/"[^"]+"/); if (RSTART) print substr($0,RSTART+1,RLENGTH-2)}' | sort | uniq -c | sort -rn | head -5

Число соединений — это не трафик, но хороший первый срез: процесс с сотней сокетов виден сразу. Дальше по подозреваемому смотрим счётчики байтов из шага 2.

6. Наблюдать в динамике

clai
$ clai обновляй список соединений каждую секунду→ watch -n1 "ss -tnp state established"

У ss нет собственного режима повтора, его выдаёт watch. Это бедный родственник iftop, зато доступный на любой машине, куда вы когда-либо зайдёте.

Gotchas

  • Число соединений — не пропускная способность. Один сокет может тянуть гигабайты, а сотня простаивающих keep-alive соединений не двигает ничего. Соединения помогают найти подозреваемого, счётчики из ss -ti — это доказательство.
  • Без root видны только свои процессы. Колонка Process заполняется для чужих сокетов только под sudo. Пустое поле рядом с чужим соединением означает «не ваш процесс», а не «процесса нет».
  • Счётчики интерфейса включают всё, что происходит на машине. В /proc/net/dev попадают и обновления пакетов, и агенты мониторинга, и соседние контейнеры. За точным ответом идите к сокету, а не к интерфейсу.

Related questions

Когда nethogs всё-таки стоит поставить? Когда нужен постоянный и удобный мониторинг по процессам. Разовую диагностику ss закрывает полностью, а вот часами смотреть в него неудобно.

Как увидеть трафик контейнера? Его счётчики живут в собственном сетевом пространстве имён: docker exec <имя> cat /proc/net/dev покажет трафик ровно этого контейнера.

Как отличить забитый канал от медленного приложения? Растущая Send-Q при неизменной скорости означает, что приложение пишет быстрее, чем сеть успевает забирать. Пустая Send-Q при низкой скорости указывает на приложение или на удалённую сторону.

See also

CliAI собирает эти фильтры ss из обычной фразы, чтобы не держать синтаксис в голове. Поставить одной строкой.