Обзор
Диагностика Linux-систем строится на трёх уровнях инструментов: counters/statistics (то, что уже собрано ядром — /proc, /sys, vmstat, iostat), tracing (запись отдельных событий — strace, perf, eBPF), profiling (статистическая выборка для определения hotspots — perf record, flame graphs). Brendan Gregg формализовал это в USE Method: для каждого ресурса (CPU, память, диск, сеть) проверить Utilization, Saturation, Errors. Этот метод даёт структурированный подход вместо хаотичного «посмотреть top и надеяться».
В FreeBSD аналогичная иерархия: procstat, systat, vmstat (counters) → truss, DTrace (tracing) → pmcstat (profiling). DTrace — оригинальный dynamic tracer (Solaris/FreeBSD), повлиявший на создание eBPF в Linux.
journald и логирование
Архитектура
systemd-journald — структурированное логирование, интегрированное с systemd (см. статью 2). Журнал хранится в бинарном формате в /var/log/journal/ (persistent) или /run/log/journal/ (volatile, до перезагрузки). Исторически выбор между ними определялся значением Storage=auto — то есть тем, существует ли каталог /var/log/journal; начиная с systemd 259 значение по умолчанию — Storage=persistent, так что журнал переживает перезагрузку без всякой дополнительной настройки. В отличие от текстового syslog, journald индексирует метаданные (unit, PID, UID, priority, boot ID), что позволяет эффективную фильтрацию.
journalctl
# Базовая навигация
journalctl -b # логи текущей загрузки
journalctl -b -1 # предыдущая загрузка
journalctl --list-boots # список загрузок
# Фильтрация
journalctl -u nginx.service # конкретный unit
journalctl -u nginx -u php-fpm # несколько units
journalctl -p err # по приоритету (emerg..debug)
journalctl -p warning..err # диапазон приоритетов
journalctl --since "2025-02-27 10:00" --until "2025-02-27 12:00"
journalctl _UID=1000 # по UID
journalctl _COMM=sshd # по имени процесса
journalctl -k # только kernel messages (аналог dmesg)
# Следование и вывод
journalctl -f # follow (аналог tail -f)
journalctl -f -u nginx # follow конкретного unit
journalctl -o json-pretty # JSON-вывод (все метаданные)
journalctl -o short-iso # ISO timestamps
journalctl --no-pager # без пагинации
# Обслуживание
journalctl --disk-usage # размер журнала
journalctl --vacuum-size=500M # ограничить по размеру
journalctl --vacuum-time=30d # удалить старше 30 дней
# Постоянные лимиты: /etc/systemd/journald.conf → SystemMaxUse=500M
journald vs syslog
/dev/log — это вход самого journald, сокет, куда пишут программы через libc-функцию syslog(3), а не канал к стороннему демону. Обратная пересылка традиционному syslog-демону управляется ForwardToSyslog= и по умолчанию выключена: из всех Forward* включена только отправка в wall. При ForwardToSyslog=yes копия сообщений немедленно уходит в сокет /run/systemd/journal/syslog. Но обычно syslog-демоны пользуются вторым способом — читают журнальные файлы как обычный клиент журнала, наравне с journalctl; тогда им достаются структурированные метаданные и всё, что накопилось до их запуска, а релевантной настройкой оказывается Storage=, а не ForwardToSyslog=. На серверах с централизованным логированием (ELK, Graylog, Loki) обычно: journald собирает локально, а rsyslog/syslog-ng или Grafana Alloy отправляет в central storage (Promtail, стоявший в этой роли во всех старых руководствах, объявлен end of life 2 марта 2026 года).
dmesg
dmesg — сообщения ядра из ring buffer (/dev/kmsg). С systemd: journalctl -k — эквивалент, но с persistent storage и фильтрацией. dmesg -T — human-readable timestamps (но неточные после suspend). dmesg -w — follow. Многие дистрибутивы закрывают буфер от непривилегированных пользователей: при kernel.dmesg_restrict=1 (значение по умолчанию задаётся ядерной опцией CONFIG_SECURITY_DMESG_RESTRICT) для dmesg требуется CAP_SYSLOG.
/proc и /sys: состояние системы
/proc (procfs) и /sys (sysfs) — виртуальные файловые системы, экспортирующие состояние ядра в userspace (см. статью 1). Ключевые файлы для диагностики:
# CPU
cat /proc/cpuinfo # модель, частота, флаги
cat /proc/stat # counters по CPU (user, system, idle, iowait)
cat /proc/loadavg # load average (1, 5, 15 min) + running/total tasks
# Память
cat /proc/meminfo # детальная разбивка (MemFree, Buffers, Cached, Slab...)
cat /proc/vmstat # VM counters (pgfault, pswpin, pswpout...)
cat /proc/buddyinfo # фрагментация памяти
# Процесс
cat /proc/<PID>/status # статус, память, capabilities, namespaces
cat /proc/<PID>/maps # карта виртуальной памяти
cat /proc/<PID>/fd/ # открытые файловые дескрипторы
cat /proc/<PID>/io # I/O counters
cat /proc/<PID>/stack # kernel stack trace (требует root)
ls -la /proc/<PID>/ns/ # namespaces процесса
# Диск / FS
cat /proc/diskstats # I/O counters по устройствам
cat /proc/mounts # смонтированные ФС
cat /proc/mdstat # состояние software RAID
# Сеть
cat /proc/net/dev # counters по интерфейсам
cat /proc/net/tcp # TCP сокеты (отсюда читает netstat; ss ходит в netlink)
cat /proc/net/snmp # протокольная статистика
Утилиты первого уровня: 60 секунд на диагностику
Brendan Gregg's «Linux Performance Analysis in 60 Seconds» — набор команд для быстрой первичной оценки:
uptime # load average — первый индикатор
dmesg -T | tail # последние kernel messages (OOM, hardware errors)
vmstat 1 5 # CPU, memory, swap, I/O — 5 samples по 1 секунде
mpstat -P ALL 1 3 # per-CPU utilization
pidstat 1 3 # per-process CPU/memory/IO
iostat -xz 1 3 # disk I/O (await, %util)
free -h # память (available — ключевая метрика, не free)
sar -n DEV 1 3 # сетевой throughput по интерфейсам
sar -n TCP,ETCP 1 3 # TCP connections и retransmits
top # интерактивный обзор (или htop)
Разбор ключевых утилит
vmstat — системная сводка: r (runnable processes — > CPU count = saturation), b (blocked on I/O), si/so (swap in/out — должны быть ~0), us/sy/id/wa (user/system/idle/iowait %).
iostat -xz — дисковый I/O: await (средняя латентность в ms — ключевая метрика), %util (utilization — 100% ≠ перегрузка для SSD с параллелизмом, но индикатор для HDD), r_await/w_await (раздельно по чтению/записи).
free -h — available (не free!) — сколько памяти доступно для приложений (включая reclaimable caches). free ≈ 0 — нормально, Linux использует свободную память под кэш.
sar (sysstat) — historical data collector. sar -A — все метрики. Данные хранятся в /var/log/sa/ (апстримный дефолт, он же в RHEL/Fedora) или /var/log/sysstat/ (Debian/Ubuntu); собирают их sa1/sa2 — из cron либо из systemd-таймеров sysstat-collect.timer (каждые несколько минут) и sysstat-summary.timer (суточная сводка). Незаменим для ретроспективного анализа: «что происходило вчера в 3 AM».
ss vs netstat
ss (socket statistics) — замена netstat, читает напрямую из kernel netlink (быстрее, чем netstat через /proc/net/tcp).
ss -tlnp # listening TCP sockets + процессы
ss -tanp # все TCP connections + процессы
ss -s # сводка по протоколам
ss state established '( dport = 443 )' # фильтр по состоянию и порту
ss -ti # TCP internal info (cwnd, rtt, retrans)
strace и ltrace: трассировка вызовов
strace перехватывает system calls процесса через ptrace(). Мощный инструмент для отладки: что открывает процесс, почему падает, на чём блокируется.
strace -p <PID> # подключиться к работающему процессу
strace -f -e trace=openat,read,write command # фильтр syscalls + follow forks
strace -c command # summary: count, time, errors по syscall
strace -e trace=network command # только сетевые syscalls
strace -T command # время каждого syscall
strace -yy command # показать paths для fd и socket details
Имена syscall'ов в фильтре берутся буквально, и это ловушка: glibc начиная с 2.26 реализует open() через syscall openat, поэтому -e trace=open на современной системе не покажет ничего. Нужен либо openat, либо класс -e trace=%file, который ловит все вызовы с именем файла в аргументах.
Overhead strace: ptrace — stop-the-world на каждом syscall. Для нагруженных процессов overhead 100-1000x. Не использовать в production на hot path. Альтернативы: perf trace (sampling, меньший overhead), bpftrace (kernel-level, минимальный overhead).
ltrace — трассировка вызовов shared libraries (аналог strace, но для libc/etc). Менее полезен в эпоху eBPF, но иногда удобен для быстрой отладки.
perf: профилирование
perf (perf_events) — встроенный в ядро профилировщик. Использует hardware performance counters (PMC), software events (context switches, page faults), tracepoints.
# CPU profiling
perf record -g -F 99 -p <PID> -- sleep 30 # sampling at 99 Hz, 30 секунд, с call graphs
perf report # интерактивный отчёт
perf report --stdio # текстовый отчёт
# Быстрый stat
perf stat command # hardware counters: cycles, instructions, IPC, cache misses
perf stat -e cache-misses,cache-references command # конкретные events
# Tracepoints
perf trace # strace-like (но через perf, меньший overhead)
perf trace -e 'syscalls:sys_enter_open*' # конкретный tracepoint
perf list # все доступные events
# Scheduling analysis
perf sched record -- sleep 5
perf sched latency # scheduling latency по процессам
Flame Graphs
Flame graph (Brendan Gregg, 2011) — визуализация стека вызовов, где ширина каждого фрейма пропорциональна времени CPU. Незаменимы для определения, «где процесс проводит время».
# Генерация
perf record -g -F 99 -p <PID> -- sleep 30
perf script > out.perf
# Используя FlameGraph tools (github.com/brendangregg/FlameGraph):
stackcollapse-perf.pl out.perf | flamegraph.pl > flame.svg
Flame graph читается снизу вверх: нижние фреймы — точка входа, верхние — leaf functions. Широкие башни — hotspots. Для off-CPU analysis (где процесс ждёт, а не работает) — off-CPU flame graphs через eBPF.
eBPF: динамическая трассировка
Архитектура
eBPF (extended Berkeley Packet Filter) — виртуальная машина в ядре, позволяющая безопасно запускать пользовательский код на kernel events. BPF-программы верифицируются при загрузке (гарантия отсутствия бесконечных циклов, out-of-bounds доступов), JIT-компилируются в native code.
eBPF может подключаться к: kprobes (любая kernel function), uprobes (любая userspace function), tracepoints (статические точки в ядре), perf events, LSM hooks (см. статью 7), XDP (сетевые пакеты на уровне драйвера — см. статью 3).
Фронтенды
BCC (BPF Compiler Collection) — набор 100+ готовых инструментов на Python + BPF C. Установка: apt install bpfcc-tools / dnf install bcc-tools. В том же репозитории живёт каталог libbpf-tools — часть тех же утилит, переписанная на C поверх libbpf: BPF-код собирается заранее и переносится между ядрами через BTF/CO-RE, поэтому на целевой машине не нужны ни Clang/LLVM, ни заголовки ядра, а готовый бинарник тянет за собой только libc, libelf и libz. Взамен требуется ядро, собранное с BTF.
# Готовые инструменты BCC
opensnoop-bpfcc # трассировка open() в реальном времени
execsnoop-bpfcc # трассировка exec() (новые процессы)
biolatency-bpfcc # гистограмма латентности block I/O
tcpconnect-bpfcc # трассировка TCP connect()
tcpretrans-bpfcc # TCP retransmits
runqlat-bpfcc # scheduler run queue latency
cachestat-bpfcc # hit/miss ratio page cache
ext4slower-bpfcc 10 # ext4 операции медленнее 10ms
fileslower-bpfcc 1 # файловые операции медленнее 1ms
profile-bpfcc -F 99 30 # CPU profiling (альтернатива perf record)
bpftrace — высокоуровневый язык для одноразовых скриптов (аналог DTrace / awk для ядра).
# Одноразовые скрипты
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args.filename)); }'
bpftrace -e 'tracepoint:block:block_rq_complete { @bytes = hist(args.nr_sector * 512); }'
bpftrace -e 'profile:hz:99 { @[kstack] = count(); }' # CPU profiling
bpftrace -e 'tracepoint:sched:sched_process_exec { printf("exec %s by %s\n", str(args.filename), comm); }'
# Полезные one-liners
bpftrace -e 'kprobe:vfs_read { @reads[comm] = count(); }' # кто читает файлы
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' # syscalls по процессам
eBPF vs strace/perf
strace: ptrace-based, останавливает процесс на каждом syscall, overhead 100-1000x, не для production. perf: sampling-based (низкий overhead) или tracepoint-based (точный, overhead ~10-30%), хорош для CPU profiling. eBPF: kernel-level, JIT-compiled, programmable, минимальный overhead (обычно <5%), production-safe. Может трассировать kernel functions, userspace functions, сетевые пакеты, filesystem operations — всё в одном фреймворке.
USE Method
USE (Utilization, Saturation, Errors) — методология Brendan Gregg для систематической проверки ресурсов:
CPU: Utilization — mpstat -P ALL (per-CPU %usr+%sys), Saturation — vmstat колонка r (> CPU count), runqlat-bpfcc, Errors — perf stat (machine check errors, но редко).
Memory: Utilization — free -h (available), Saturation — vmstat (si/so — swap activity), sar -B (pgscank/s — scanning для reclaim), Errors — dmesg | grep -i oom, /proc/vmstat (oom_kill).
Disk I/O: Utilization — iostat -xz (%util), Saturation — iostat (aqu-sz — queue depth; в прежних версиях sysstat колонка называлась avgqu-sz), Errors — smartctl -a /dev/sda, dmesg (I/O errors), btrfs device stats (для Btrfs).
Network: Utilization — sar -n DEV (rxkB/s, txkB/s vs link speed), ip -s link, Saturation — ss -ti (retrans), netstat -s (drops), nstat (подробнее), Errors — ip -s link (errors, dropped), ethtool -S.
Практика: типичные сценарии
# Сценарий: система тормозит, непонятно почему
uptime # load average высокий?
vmstat 1 5 # r > CPU count? wa > 0? si/so > 0?
# Если wa > 0 → disk bottleneck:
iostat -xz 1 3 # какой диск, await высокий?
iotop -oP # какие процессы генерируют I/O?
# Если r > CPU count → CPU saturation:
mpstat -P ALL 1 3 # какие CPU загружены?
pidstat 1 3 # какие процессы?
# Если si/so > 0 → swapping:
free -h # available мало?
ps aux --sort=-%mem | head # кто потребляет память?
# Сценарий: процесс падает
journalctl -u myservice -p err -b # ошибки в логах
coredumpctl list # core dumps (если systemd-coredump)
coredumpctl debug <PID> # открыть в gdb
strace -f -o trace.log command # трассировка syscalls
# Сценарий: сеть медленная
ss -s # общая статистика
ss -ti dst <IP> # TCP info для конкретного соединения
tcpretrans-bpfcc # retransmits в реальном времени
ping -c 10 <host> # базовая latency
mtr <host> # traceroute + статистика
Нюансы и trade-off'ы
«CPU utilization is wrong». Brendan Gregg показал, что %CPU может быть misleading: процесс показывает 100% CPU, но бо́льшую часть времени ждёт memory stalls (cache misses). perf stat покажет IPC (Instructions Per Cycle) < 1.0 — индикатор memory-bound workload. Реальную утилизацию показывает IPC в контексте конкретного процессора.
Load average в Linux: особенность. В отличие от других UNIX (где load = runnable processes), Linux считает и uninterruptible sleep (D state) — процессы, ожидающие I/O. Поэтому load average > CPU count не обязательно означает CPU saturation — может быть I/O bottleneck. vmstat (r vs b) разделяет CPU и I/O wait.
free vs available memory. free показывает «Free: 200MB» на сервере с 64GB. Паника? Нет: Linux использует свободную память под page cache. Available (с ядра 3.14, /proc/meminfo MemAvailable) — реальное количество памяти, доступной приложениям без swapping. Это free + reclaimable caches/buffers.
eBPF overhead. Хотя eBPF production-safe, overhead зависит от частоты events. Трассировка каждого syscall на нагруженном сервере (~100K/sec) добавит заметную нагрузку. Трассировка редких events (TCP retransmits, OOM kills) — практически нулевой overhead. Правило: тестируйте overhead на staging перед production.
perf и символы. perf record использует frame pointers для call graphs. Многие приложения компилируются с -fomit-frame-pointer (gcc default с -O2). Результат — broken stack traces. Решения: -fno-omit-frame-pointer (пересборка), DWARF unwind (perf record --call-graph dwarf) или LBR (perf record --call-graph lbr) — аппаратный Last Branch Record не требует никаких флагов компиляции, но, по документации perf, доступен на новых процессорах Intel и снимает только пользовательскую часть стека. Само положение дел здесь улучшилось: Fedora 38 вернула -fno-omit-frame-pointer в дефолтные флаги сборки, Ubuntu сделала то же с 24.04 LTS (для 64-битных архитектур, ценой 1-2% производительности), так что на свежих дистрибутивах штатные пакеты снова дают корректные fp-стеки.
Observability gap: ядро vs приложение. Kernel-level инструменты (perf, eBPF) видят syscalls и kernel structures, но не внутреннюю логику приложения. Application-level observability (OpenTelemetry, USDT probes) дополняет картину. eBPF uprobes могут трассировать userspace functions, но требуют символьной информации (debug symbols).
Сравнение с FreeBSD
DTrace. FreeBSD имеет нативный DTrace (перенесён из Solaris). DTrace — пионер dynamic tracing: безопасный, production-safe, с D-языком для скриптов. eBPF/bpftrace — духовный наследник DTrace для Linux. Функционально они сравнимы в 2025, но экосистема eBPF инструментов значительно больше (150+ BCC tools vs десятки DTrace scripts).
truss vs strace. truss — FreeBSD аналог strace (syscall tracing). Также ptrace-based, аналогичный overhead. truss -f -o trace.log command.
procstat. FreeBSD procstat объединяет функциональность нескольких Linux инструментов: procstat -f <PID> (открытые файлы, как /proc/PID/fd), procstat -k <PID> (kernel stack, как /proc/PID/stack), procstat -s <PID> (сигналы), procstat -v <PID> (virtual memory map, как /proc/PID/maps).
systat. Интерактивный real-time мониторинг (curses), встроенный в base system. Режимы: vmstat, iostat, netstat, tcp, ifstat. В Linux аналоги — отдельные утилиты (vmstat, iostat, sar).
SIGINFO. FreeBSD (и macOS) поддерживают SIGINFO (Ctrl+T): отправка сигнала текущему foreground-процессу, который выводит свой прогресс. dd, cp, fetch реагируют на SIGINFO. В Linux аналога нет — приходится использовать kill -USR1 (для dd) или pv (pipe viewer). Мелочь, но заметно в повседневной работе.
Отсутствие /proc по умолчанию. FreeBSD не монтирует procfs по умолчанию (хотя может). Вместо этого — sysctl и procstat как primary API. В Linux /proc — фундамент, без которого не работает практически ничего (ps, top, free все читают /proc).
Источники
- Brendan Gregg — Linux Performance — карты инструментов, методологии, статьи
- USE Method — методология USE
- BPF Performance Tools (book) — 150+ eBPF инструментов
- Systems Performance, 2nd Ed. — фундаментальная книга по performance
- Linux Performance Analysis in 60s — Netflix Tech Blog
- eBPF Tracing Tools — обзор eBPF
- bpftrace: язык — куда переехало содержимое прежнего Reference Guide
- BCC tools — готовые инструменты
- perf Examples — примеры использования perf
- journalctl — ArchWiki — руководство по journalctl
- FreeBSD Handbook: DTrace — для сравнения
Связанные заметки
- Linux — средства диагностики производительности — карта инструментов по слоям системы
- Linux — справочник команд: фреймворки трассировки — ftrace, perf, bpftrace на практике
- Linux — ядро: сборка, модули, параметры — что именно наблюдают трассировщики
- FreeBSD — мониторинг и отладка — DTrace и базовые утилиты FreeBSD, для сравнения
- Linux — сводный cheatsheet — быстрая справка по диагностике
- Linux — время и синхронизация — согласованные часы как условие того, что логи разных машин вообще сопоставимы
- Наблюдаемость: Prometheus, node_exporter, Grafana, Loki — постоянный сбор вместо разовой диагностики: что происходило в три часа ночи
- Стеки: ядра, прерываний, пользовательские — откуда берутся трассы стека и что означает «stack guard page was hit»
Из библиотеки института уносят только знания. Читателей здесь не считают: посещение не регистрируется, отметок в издании не остаётся, счётчиков нет ни у одного издания фонда.
Издание пополняется и пересверяется. Текст доступен на условиях CC BY-SA 4.0 — унесённое можно передавать дальше на тех же условиях.