Обзор
FreeBSD включает в base system набор диагностических инструментов, покрывающий всё: от беглого взгляда на загрузку (top, vmstat) до глубокого анализа поведения ядра на лету (DTrace). Многое из того, что в Linux требует установки сторонних пакетов (sysstat, iotop, bpftrace), во FreeBSD доступно из коробки.
Статья организована по уровням погружения: быстрая диагностика → детальный анализ по подсистемам (CPU, RAM, диск, сеть) → логи → DTrace для глубоких расследований. Каждый уровень — ответ на вопрос "что происходит с системой?" с нарастающей детализацией.
Быстрая диагностика: первые 60 секунд
Когда система "тормозит" или ведёт себя странно, начинать с общей картины.
top
top # интерактивный монитор процессов
top -S # включить системные (ядерные) процессы
top -o res # сортировать по resident memory
top -P # показать загрузку по отдельным CPU
top во FreeBSD — base system, не требует установки. Показывает load average, CPU states (user/nice/system/interrupt/idle), память (Active/Inact/Wired/Buf/Free), swap, и список процессов.
Ключевые CPU states: interrupt — время в обработчиках прерываний (высокое значение → проблема с драйвером или hardware); system — ядерное время (высокое → много системных вызовов, возможно I/O bound). idle — свободный CPU. Если idle близок к нулю — система перегружена.
Интерактивные команды: m — переключиться между режимами отображения cpu и io (второй показывает per-process I/O; то же самое даёт ключ -m io), P — CPU per core, S — toggle system processes, o — сменить сортировку, s — изменить интервал обновления.
vmstat
vmstat 1 # обновление каждую секунду
procs memory page disks faults cpu
r b w avm fre flt re pi po fr sr da0 in sy cs us sy id
2 0 0 1.2G 340M 245 0 0 0 0 0 3 412 2841 1205 4 2 94
r — процессы в очереди на исполнение (run queue). Если r стабильно больше числа CPU — процессор перегружен. b — процессы, заблокированные на I/O. w — процессы в swap (swapped out). fre — свободная память. pi/po — страницы swap in/out (ненулевые = система свопит). cs — context switches. in — interrupts. us/sy/id — user/system/idle CPU.
Первая строка vmstat — среднее с момента загрузки, последующие — реальное время. Игнорировать первую строку.
systat
systat(1) — curses-based монитор из base system с множеством режимов:
systat -vmstat 2 # общая статистика, обновление 2 сек
systat -iostat 2 # дисковый I/O
systat -ifstat 2 # сетевые интерфейсы
systat -netstat 2 # сетевые соединения
systat -pigs 2 # процессы-"свиньи" по CPU
systat -zarc 2 # ZFS ARC статистика
systat -ip 2 # IP-трафик
systat -tcp 2 # TCP-статистика
Навигация: vi-стиль. :vmstat — переключить режим. :q — выход. Не q, а именно :q.
systat -zarc особенно полезен для ZFS-систем: показывает hit rate ARC-кэша, размеры, demand vs prefetch. Если ARC hit rate ниже 80-90% — стоит увеличить vfs.zfs.arc.max.
CPU: детальный анализ
Кто ест процессор
top -o cpu # сортировка по CPU в top
ps auxr | head # топ процессов по CPU (однократный срез)
CPU profiling встроенными средствами
# pmcstat — hardware performance counters (base system)
kldload hwpmc # драйвер собран модулем, не в GENERIC
pmcstat -S instructions -T # top-подобный профиль по инструкциям
pmcstat -S unhalted-cycles -O profile.pmc sleep 10 # профиль за 10 секунд
pmcstat(8) использует аппаратные счётчики процессора (PMC — Performance Monitoring Counters). В GENERIC есть только options HWPMC_HOOKS, сам драйвер hwpmc(4) подгружается модулем (sysrc kld_list+=hwpmc, чтобы это переживало перезагрузку). Доступность событий зависит от CPU; машинно-независимых псевдонимов всего восемь — branches, branch-mispredicts, cycles, dc-misses, ic-misses, instructions, interrupts, unhalted-cycles, всё остальное задаётся именами конкретной микроархитектуры. Строчные -s/-p — счётчики, прописные -S/-P — сэмплирование (system-wide и process-mode соответственно). pmc(3) перечисляет доступные события.
Средняя загрузка и scheduling
sysctl vm.loadavg # load average (1, 5, 15 мин)
sysctl kern.cp_time # накопленное CPU time по состояниям
Load average во FreeBSD (как и в Linux) включает и процессы в run queue, и процессы, ожидающие I/O. Высокий LA при низком CPU usage → I/O bottleneck, а не CPU.
Память: кто и сколько
Общая картина
top # раздел Mem: Active, Inact, Wired, Buf, Free
vmstat -s # подробная статистика VM
sysctl hw.physmem # физическая память
sysctl hw.usermem # доступная пользователю
sysctl vm.stats.vm.v_free_count # свободные страницы
Категории памяти FreeBSD: Active — активно используемые страницы; Inact — недавно использованные, кандидаты на вытеснение; Laundry — грязные неактивные страницы, которые нужно записать в swap или на файловую систему, прежде чем освободить (отдельная очередь PQ_LAUNDRY и свой поток-«прачечная»); Wired — запинены в RAM, не могут быть вытеснены (ядро, ZFS ARC); Buf — буферный кэш; Free — свободные.
Wired memory на ZFS-системе часто велика — это ARC. Если Free + Inactive → близко к нулю — система испытывает давление на память.
Swap
swapinfo -h # использование swap
pstat -s # подробнее
Ненулевой swap usage — не обязательно проблема. Неактивные страницы могут быть вытеснены в swap без влияния на производительность. Проблема — активный swapping: vmstat 1 покажет ненулевые pi/po (page in/out).
Кто потребляет память
top -o res # сортировка по resident memory
ps auxm | head # топ по потреблению памяти
Для ZFS:
sysctl kstat.zfs.misc.arcstats.size # текущий ARC
sysctl vfs.zfs.arc.max # максимум ARC
sysctl kstat.zfs.misc.arcstats.hits # попадания в кэш
sysctl kstat.zfs.misc.arcstats.misses # промахи
systat -zarc 2 # интерактивно
Диск: I/O и файловые системы
iostat
iostat -x 2 # расширенная статистика, 2 сек
iostat -d -w 2 # только диски
device r/s w/s kr/s kw/s ms/r ms/w ms/o ms/t qlen %b
da0 12.3 8.7 245.0 156.0 0.8 1.2 0.0 0.9 1 2
ms/r, ms/w — средняя латентность чтения/записи в миллисекундах. Для SSD < 1ms нормально, для HDD — 5-15ms. %b — процент времени, когда диск занят. qlen — длина очереди.
gstat
gstat # GEOM-статистика в реальном времени
gstat -a # только провайдеры, занятые хотя бы на 0.1%
gstat(8) показывает I/O для каждого GEOM-провайдера (диски, партиции, ZFS vdev). Удобнее iostat для быстрой диагностики — интерактивный, обновляется непрерывно.
ZFS I/O
zpool iostat 2 # I/O по пулам
zpool iostat -v 2 # с разбивкой по vdev
Что читает/пишет файлы
fstat # открытые файлы всех процессов
fstat -p <PID> # конкретный процесс
Сеть: трафик, соединения, проблемы
netstat
netstat -i # статистика интерфейсов (ошибки, дропы)
netstat -s # статистика по протоколам (TCP retransmissions!)
netstat -an # все соединения
netstat -an -p tcp | grep ESTABLISHED | wc -l # число активных TCP
netstat -m # mbuf статистика (буферы сетевого стека)
netstat -s | grep retransmit — ретрансмиссии TCP. Растущее число → потери пакетов, проблемы с сетью или перегрузка.
netstat -m — mbuf allocations. Если в строке "requests for mbufs denied (mbufs/clusters/mbuf+clusters)" числа ненулевые — не хватает сетевых буферов, нужно увеличить kern.ipc.nmbclusters в loader.conf.
sockstat
sockstat -l # слушающие сокеты (аналог ss -ln в Linux)
sockstat -4 # только IPv4
sockstat -c # подключённые
tcpdump и pflog
tcpdump -i vtnet0 -n port 80 # трафик на порт 80
tcpdump -i pflog0 -n # трафик, заблокированный/пропущенный PF
tcpdump -r /var/log/pflog # прочитать сохранённый pflog
Пропускная способность в реальном времени
systat -ifstat 2 # throughput по интерфейсам
netstat -I vtnet0 -w 1 # bytes in/out для интерфейса, 1 сек
Логирование
Ключевые лог-файлы
/var/log/messages # общие системные сообщения
/var/log/auth.log # аутентификация (SSH, su, doas)
/var/log/security # security-события
/var/log/cron # cron jobs
/var/log/daemon.log # сообщения демонов (facility daemon)
/var/log/maillog # почта
/var/log/debug.log # debug-сообщения
/var/run/dmesg.boot # dmesg при загрузке (сохраняется)
Оперативный анализ
tail -f /var/log/messages # следить за логами в реальном времени
grep -i error /var/log/messages # искать ошибки
dmesg | tail -30 # последние сообщения ядра
dmesg -a # все сообщения ядра, включая verbose
syslogd
Конфигурация — /etc/syslog.conf. Описана в статье о безопасности (флаг -ss для закрытия сетевого сокета). Для отладки полезно временно увеличить verbosity:
# Добавить в /etc/syslog.conf для отладки конкретного facility
local0.* /var/log/myapp.log
# Перечитать конфиг
service syslogd reload
newsyslog — ротация
newsyslog -nv # dry run: что было бы ротировано и почему
newsyslog -F # принудительно ротировать, не дожидаясь условий
Конфигурация /etc/newsyslog.conf описана в статье о безопасности.
Процессы и системные вызовы
ps — срез процессов
ps auxww # все процессы с полными командными строками
ps -axo pid,ppid,user,%cpu,%mem,vsz,rss,stat,command # кастомный формат
ps -axd # дерево процессов (иерархия)
Столбец STAT: R — running, S — sleeping (interruptible), D — disk wait (uninterruptible), I — idle, Z — zombie, T — stopped. Процессы в D — ждут I/O, не могут быть убиты сигналом.
truss — трассировка системных вызовов
truss -p <PID> # присоединиться к работающему процессу
truss -f command # трассировка с отслеживанием дочерних процессов
truss -c command # подсчёт вызовов (summary)
truss -e command # показывать окружение, передаваемое в execve
truss(1) — FreeBSD-аналог strace из Linux. Входит в base system. Показывает каждый системный вызов процесса с аргументами и возвращаемыми значениями. Незаменим для диагностики "почему программа не запускается" или "что она пытается открыть".
procstat
procstat -f <PID> # открытые файловые дескрипторы
procstat -k <PID> # стек ядра (где заблокирован)
procstat -t <PID> # треды
procstat -s <PID> # сигналы
procstat -v <PID> # виртуальная память (mmap'ы)
procstat(1) — мощная утилита из base system для инспекции процессов. procstat -k особенно полезна: если процесс "висит", покажет, на каком системном вызове он заблокирован.
DTrace: динамическая трассировка
DTrace — фреймворк трассировки из Solaris, портированный в FreeBSD. Позволяет инструментировать работающее ядро и userland-программы на лету, без перезагрузки и без влияния на производительность (пока probe неактивен — overhead нулевой).
В GENERIC-ядре FreeBSD поддержка DTrace включена начиная с FreeBSD 9.2. Ядерный DTrace поддержан полностью, userland-DTrace в документации проекта до сих пор помечен как экспериментальный.
# Загрузить модули DTrace вручную; начиная с 10.0 dtrace(1) делает это сам
kldload dtraceall
# Установить DTrace Toolkit — коллекция готовых скриптов
pkg install dtrace-toolkit
Концепция: probe → predicate → action
DTrace-скрипт состоит из правил вида: при срабатывании probe (если predicate истинен) — выполнить action.
provider:module:function:name
/predicate/
{
action;
}
Практические однострочники
# Кто делает системные вызовы? (топ процессов по числу syscall)
dtrace -n 'syscall:::entry { @[execname] = count(); }'
# Какие файлы открываются?
dtrace -n 'syscall::openat:entry { printf("%s %s", execname, copyinstr(arg1)); }'
# Распределение латентности read() (гистограмма)
dtrace -n 'syscall::read:entry { self->ts = timestamp; }
syscall::read:return /self->ts/ {
@["ns"] = quantize(timestamp - self->ts);
self->ts = 0;
}'
# Кто создаёт новые процессы?
dtrace -n 'proc:::exec-success { printf("%s -> %s", curpsinfo->pr_psargs, args[0]); }'
# Какие процессы вызывают запись на диск? (BIO_WRITE == 2, BIO_READ == 1)
dtrace -n 'io:::start /args[0]->bio_cmd == 2/ { @[execname] = count(); }'
В примере с файлами намеренно стоит openat, а не open*: libc реализует open(2) через openat(AT_FDCWD, ...), поэтому почти все открытия проходят именно через openat, а путь в нём лежит не в arg0 (там дескриптор каталога), а в arg1.
Каждый из этих однострочников безопасен для production — DTrace спроектирован так, что probe без активного consumer не влияет на производительность.
Начиная с FreeBSD 14.1 dtrace(1) умеет отдавать машиночитаемый вывод через libxo(3): dtrace --libxo или -x oformat=json|xml|html (text — обычное человекочитаемое поведение). Полезно, когда результат разбирает не человек, а скрипт. Нюанс: в этом режиме dtrace не печатает ничего, пока явно не вызваны функции печати, — агрегации приходится выводить самому либо добавлять флаг -O, который печатает их все при выходе.
DTrace Toolkit
# После установки sysutils/dtrace-toolkit
/usr/local/share/dtrace-toolkit/
hotkernel # какие функции ядра потребляют CPU
procsystime # системное время по процессам
opensnoop # трассировка open() в реальном времени
execsnoop # трассировка exec() — кто что запускает
rwsnoop # трассировка read/write
iosnoop # I/O операции
tcpsnoop # TCP-соединения
Симлинки в /usr/local/bin порт делает только для dtruss, hotkernel, procsystime, opensnoop и shellsnoop; остальные скрипты запускаются по полному пути из этого каталога. Не всё из тулкита работает на FreeBSD как есть — Handbook предупреждает об этом прямо. Скрипты, специально портированные на FreeBSD, лежат в базовой системе, в /usr/share/dtrace; а, например, tcpsnoop в собственной шапке признаётся, что построен на fbt-пробах конкретной версии ядра Solaris 10, и на FreeBSD его придётся переписывать.
opensnoop и execsnoop — вероятно, два самых практически полезных скрипта. Первый показывает все открытия файлов в системе (помогает найти "какой конфиг ищет программа"), второй — все запуски процессов (помогает понять, что делает cron/rc/скрипт).
Когда DTrace, а когда хватит проще
top/vmstat/iostat — первичная диагностика, достаточно для 80% ситуаций.
truss — когда нужно понять поведение конкретного процесса.
procstat — когда процесс заблокирован и нужно понять на чём.
DTrace — когда нужно ответить на вопрос, который невозможно задать стандартными инструментами: "какие процессы записывают более 1MB за раз?", "какие TCP-соединения имеют латентность выше 100ms?", "какая функция ядра вызывается при определённом условии?".
Диагностика типичных проблем
Система "тормозит" — алгоритм
top— CPU idle? Если близко к 0 → CPU-bound: кто ест CPU (top -o cpu)vmstat 1—pi/poненулевые? → система свопит:top -o res, уменьшить ARCiostat -x 2—%bблизко к 100? → I/O bottleneck:gstat, кто пишет/читаетnetstat -s— ретрансмиссии растут? → сетевые потериdmesg— ошибки hardware?
Процесс "повис"
procstat -k <PID> # стек ядра — на чём заблокирован
truss -p <PID> # какой syscall выполняет
kill -INFO <PID> # некоторые программы покажут состояние (SIGINFO)
kill -INFO (Ctrl+T в терминале) — уникальная BSD-фича. Отправляет SIGINFO процессу, и многие стандартные утилиты (dd, cp, tar, fetch) выводят прогресс. Работает и для пользовательских программ, если они обрабатывают этот сигнал.
Нехватка дискового пространства
df -h # общая картина
du -hxd 1 / # размеры каталогов первого уровня
zfs list -o name,used,usedbysnapshots # ZFS: снепшоты могут занимать место!
# Частая причина: забытые снепшоты
zfs list -t snapshot -o name,used -s used # снепшоты по занимаемому месту
Сервис не запускается
service <name> start # попытка запустить
cat /var/log/messages | grep <name> # что в логах
truss service <name> start # трассировка — что пытается открыть/сделать
sockstat -l | grep <port> # порт уже занят?
Мониторинг для production
Инструменты выше — для интерактивной диагностики. Для long-term мониторинга:
bsnmpd(8) — SNMP-демон из base system. Минималистичный, достаточный для сбора базовых метрик внешним коллектором (Zabbix, Prometheus через SNMP exporter, MRTG).
node_exporter (sysutils/node_exporter) — Prometheus-совместимый экспортёр метрик. Наиболее современный подход для интеграции с Grafana/Prometheus стеком.
collectd (net-mgmt/collectd5) — лёгкий демон сбора метрик с поддержкой множества backends.
periodic(8) — встроенная система ежедневных/еженедельных/ежемесячных проверок. Генерирует отчёты и отправляет email root'у:
# /etc/periodic.conf
daily_status_security_enable="YES"
daily_status_disks_enable="YES"
daily_scrub_zfs_enable="YES"
daily_status_zfs_enable="YES"
daily_status_network_enable="YES"
Эти отчёты — минимальный мониторинг, который должен быть на каждом сервере.
Отличия от Linux
truss → strace. Аналогичная функциональность, разные имена.
procstat → частично /proc/<PID>/*, частично lsof. В FreeBSD /proc минимален (и вообще не монтируется по умолчанию), procstat заменяет его.
gstat → нет прямого аналога. iostat в Linux ближе всего.
systat → нет аналога в base system Linux. Ближайшее — dstat (сторонний пакет), но сам dstat заброшен: репозиторий заархивирован в ноябре 2020 года, а разработка продолжается в форке dool.
DTrace → bpftrace/eBPF. Исторически DTrace появился раньше, bpftrace вдохновлён им. Синтаксис похож, но экосистемы разные.
kill -INFO (SIGINFO) → не существует в Linux. Уникальная BSD-фича.
periodic → аналога в base system Linux нет. Ближайшее — самодельные скрипты в cron или systemd timers.
Brendan Gregg (автор USE Method и DTrace Toolkit) опубликовал USE Method checklist для FreeBSD — систематический подход к диагностике по ресурсам (Utilization, Saturation, Errors). Рекомендую как reference.
Источники
- FreeBSD Handbook, Chapter 28 "DTrace": docs.freebsd.org/en/books/handbook/dtrace/
- FreeBSD Foundation, "An Introduction to Dynamic Tracing": freebsdfoundation.org/resource/an-introduction-to-dynamic-tracing/
- Klara Systems, "FreeBSD vs. Linux – Tracing and Troubleshooting": klarasystems.com/articles/freebsd-vs-linux-tracing-and-troubleshooting/
- Brendan Gregg, "USE Method: FreeBSD Performance Checklist": brendangregg.com/USEmethod/use-freebsd.html
top(1),vmstat(8),iostat(8),systat(1),gstat(8),netstat(1),sockstat(1),truss(1),procstat(1),dtrace(1),pmcstat(8),periodic(8)— man pages
Связанные заметки
- FreeBSD — sysctl и конфигурация ядра — sysctl как основной источник системных счётчиков
- FreeBSD — ZFS — диагностика ARC,
zpool iostat, health пулов - Linux — мониторинг и отладка — journalctl, perf и eBPF, для сравнения с DTrace
- Linux — средства диагностики производительности — карта инструментов по слоям системы
- FreeBSD — сводный cheatsheet — быстрая справка по диагностическим командам
Из библиотеки института уносят только знания. Читателей здесь не считают: посещение не регистрируется, отметок в издании не остаётся, счётчиков нет ни у одного издания фонда.
Издание пополняется и пересверяется. Текст доступен на условиях CC BY-SA 4.0 — унесённое можно передавать дальше на тех же условиях.