---
tags: [linux, tooling]
verified: 2026-09-02
---

# Linux — мониторинг и отладка

## Обзор

Диагностика 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

```bash
# Базовая навигация
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). Ключевые файлы для диагностики:

```bash
# 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» — набор команд для быстрой первичной оценки:

```bash
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).

```bash
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(). Мощный инструмент для отладки: что открывает процесс, почему падает, на чём блокируется.

```bash
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.

```bash
# 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. Незаменимы для определения, «где процесс проводит время».

```bash
# Генерация
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.

```bash
# Готовые инструменты 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 для ядра).

```bash
# Одноразовые скрипты
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`.

## Практика: типичные сценарии

```bash
# Сценарий: система тормозит, непонятно почему
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](https://www.brendangregg.com/linuxperf.html) — карты инструментов, методологии, статьи
- [USE Method](https://www.brendangregg.com/usemethod.html) — методология USE
- [BPF Performance Tools (book)](https://www.brendangregg.com/bpf-performance-tools-book.html) — 150+ eBPF инструментов
- [Systems Performance, 2nd Ed.](https://www.brendangregg.com/systems-performance-2nd-edition-book.html) — фундаментальная книга по performance
- [Linux Performance Analysis in 60s](https://netflixtechblog.com/linux-performance-analysis-in-60-000-milliseconds-accc10403c55) — Netflix Tech Blog
- [eBPF Tracing Tools](https://www.brendangregg.com/ebpf.html) — обзор eBPF
- [bpftrace: язык](https://github.com/bpftrace/bpftrace/blob/master/docs/language.md) — куда переехало содержимое прежнего Reference Guide
- [BCC tools](https://github.com/iovisor/bcc) — готовые инструменты
- [perf Examples](https://www.brendangregg.com/perf.html) — примеры использования perf
- [journalctl — ArchWiki](https://wiki.archlinux.org/title/Systemd/Journal) — руководство по journalctl
- FreeBSD Handbook: [DTrace](https://docs.freebsd.org/en/books/handbook/dtrace/) — для сравнения

---

## Связанные заметки

- [Linux — средства диагностики производительности](./linux-perf-tools.md) — карта инструментов по слоям системы
- [Linux — справочник команд: фреймворки трассировки](./linux-tldr-tracing.md) — ftrace, perf, bpftrace на практике
- [Linux — ядро: сборка, модули, параметры](./linux-kernel.md) — что именно наблюдают трассировщики
- [FreeBSD — мониторинг и отладка](./freebsd-monitoring-debugging.md) — DTrace и базовые утилиты FreeBSD, для сравнения
- [Linux — сводный cheatsheet](./linux-map-cheatsheet.md) — быстрая справка по диагностике
- [Linux — время и синхронизация](./linux-time-sync.md) — согласованные часы как условие того, что логи разных машин вообще сопоставимы
- [Наблюдаемость: Prometheus, node_exporter, Grafana, Loki](./observability-stack.md) — постоянный сбор вместо разовой диагностики: что происходило в три часа ночи
- [Стеки: ядра, прерываний, пользовательские](./os-stacks.md) — откуда берутся трассы стека и что означает «stack guard page was hit»
