Я написал whotop в августе, после вечера, когда порт 4310 оказался занят и я убил не тот процесс node. 19 августа я выложил пакет в npm. Главное, что обещает README: whotop говорит, что значение недоступно и почему, вместо уверенной догадки. Рядом с каждой ролью стоит правило, по которому она назначена.
Это обещание я проверял на раннерах CI и на фикстурах, которые записал сам. Ни разу я не взял настоящий вечер своей машины и не задал ей построчно тот единственный вопрос, ради которого инструмент существует. Несколько дней назад я писал про ночной лог своего ноутбука. В том же логе есть ответ: 96 снимков whotop ls --all --json, версия 0.4.1, Windows, без прав администратора. Я взял снимок 29 сентября в 01:59, когда мои агентские сессии только что закончили работу. Смотрел только на процессы, которые держат TCP-порт на прослушивание.
Таких 33 из 484 процессов. Роль whotop дал 21 из них: Postgres и 20 процессам node, которые он называет dev-серверами. Остальные 12 whotop пометил как unknown. 11 из них вообще не показали командную строку.
С портами всё в порядке
На Windows whotop одним вызовом PowerShell получает таблицу процессов вместе с таблицей сокетов. Pid владельца каждого сокета снят в тот же момент, что и список процессов. По README, порт, приписанный не тому процессу, это та ошибка, которой этот инструмент допускать нельзя. За эту ночь я не нашёл в логе ничего, что противоречило бы колонке портов.
Этот пример я не планировал. 5 процессов на ноутбуке были запущены как astro preview --port 4321, в разное время за 2 дня. Я их так и не остановил. 4321 держит только один из них, pid 23620. Остальные 4 по таблице сокетов сидят на 4322, 4323, 4324 и 4325. Ещё 5 запущены с --port 4326 в первые 20 минут после полуночи и сидят на портах с 4326 по 4330. У 8 процессов порт в командной строке не тот, который они держат.
Это снова мой августовский вечер. Если искать 4321 в командных строках, будет 5 кандидатов и 4 из них не те. whotop port 4321 даёт один pid.
11 строк ссылаются на улику, которой нет
Все 11 процессов astro, эти 10 и ещё один с --port 4331, подписаны как vite. Рядом с каждым напечатана причина “known dev server in the command line (vite)”. Слова “vite” нет ни в одной из этих 11 командных строк. Там запущен astro.js preview.
Я полез в код. Правило срабатывает потому, что входной скрипт это astro. Это верно. Но ярлык и причину собирает одна вспомогательная функция, которая ищет в командной строке первый токен dev-сервера. Если не находит ни одного, она всё равно возвращает первый токен из списка. Первым в списке стоит vite. Роль верная. Но слово в ярлыке и в причине берётся из значения по умолчанию. В README написано, что классификация, которую нельзя проверить, это та же догадка, только вежливее. Здесь командная строка лежала в логе, так что проверить я мог.
Каталоги только выведены
На Windows whotop не читает рабочий каталог чужого процесса. Чтобы его узнать, пришлось бы читать память процесса, поэтому он берёт самый длинный абсолютный путь из командной строки и помечает его (inferred). Для 11 строк astro это каталог проекта. Похоже на правду, хотя по логу я и этого проверить не могу.
Ещё для 7 строк он не говорит ничего полезного. 6 процессов http-server и 1 serve запущены из кэша npx, поэтому единственный путь в их командной строке ведёт в этот кэш. whotop обрезает его перед node_modules и выдаёт каталог кэша. У 6 строк http-server получается один и тот же каталог. По нему их не различить. Один из этих процессов держит 4310, тот самый порт из августовского вечера.
Одна строка неверна из-за ошибки в разборе пути. У сервера ts-node-dev на порту 4400 в командной строке 2 пути: файл хука в D:/Temp и за ним путь проекта. Моё регулярное выражение для поиска путей допускает пробелы внутри пути. Первое совпадение перескакивает через пробел и забирает с собой букву диска второго пути. Второй путь whotop не видит вовсе. В строке стоит D:/Temp. Я воспроизвёл это на опубликованном пакете: без пути хука та же команда даёт каталог проекта.
Из 20 строк node у 8 каталог формально помечен как выведенный и ничем не помогает, когда я собираюсь что-то убить. Ещё 3 строки получили вместо ярлыка только имя файла скрипта, но там причина честно говорит, что больше ничего не совпало. В README эта проблема с каталогом описана на примере claude.exe, у которого каталог установки выглядел как рабочий каталог. Тот случай я исправил в августе, а других искать не стал.
Имена служб остаются на одном экране
В этом снимке 163 из 484 процессов скрыли командную строку. Реестр служб, который whotop читает без прав администратора, назвал 115 из них. Предупреждение в каждом снимке так и говорит. Но я поискал во всём ночном логе хоть одно имя службы и не нашёл. Имена привязываются к процессу, но печатает их только интерактивный экран. whotop ls, whotop port и вывод JSON их выбрасывают.
Я воспроизвёл это на подготовленных данных: svchost.exe держит порт 135 и запускает службу RpcSs. В интерактивном экране это svchost.exe [RpcSs]. whotop port 135 показывает unknown и советует запустить оболочку с правами администратора. whotop ls RpcSs ничего не находит. На моём ноутбуке 4 из 12 неизвестных процессов, слушающих порт, были svchost, а этот процесс для того и нужен, чтобы запускать в себе службы. Какие это были службы, лог сказать не может: JSON уже выбросил имена.
Чего я не проверял
Настоящий рабочий каталог ни одного из этих процессов я по логу проверить не могу. Я не запускал whotop с правами администратора, поэтому не знаю, скольких из 11 молчащих процессов whotop назвал бы с правами администратора. Порты 139, 445 и 5357 принадлежат pid 4, System. whotop там просто пишет unknown. Ещё в снимке 25 сокетов без процесса-владельца, их не показывает ни одна строка.
Это один ноутбук и один снимок, но за ночь числа почти не меняются. В 81 из 96 снимков 32 или 33 процесса, слушающих порт, из них 21 с ролью. 11 ярлыков vite есть в 91 снимке, а 7 каталогов npx во всех 96.
Ни одна из 3 проблем не исправлена в 0.4.1, версии, которая сейчас лежит в npm.