Средства трассировки в ядре Linux достигли уровня DTrace
Брендан Грег (Brendan Gregg), один из разработчиков DTrace, считает, что с добавлением в ядро Linux 4.9 хронометрированных выборок (timed sampling), средства для анализа производительности на базе BPF достигли уровня функциональности DTrace. По мнению Брендана Грега, это очень важное достижение и в Linux теперь доступны полноценные средства для анализа производительности приложения и ядра с использованием готовой для промышленного применения системы, создающей минимальную фоновую нагрузку и позволяющей использовать такие расширенные возможности как гистограммы задержек и счётчики частоты.
Отмечается, что несмотря на то, что BPF не предоставляет высокоуровневый язык как в DTrace, доступные фронтэнды сглаживают эту особенность и достаточны для создания различных инструментов, некоторые из которых построены по мотивам старого DTraceToolkit. Для конечного пользователя трассировка с использованием инструментов на базе BPF и написание однострочных сценариев окажется не сложнее DTrace. Но для разработки новых инструментов на базе BPF пока требуется заметно больше усилий — предоставляемый в DTrace яызык D, похожий на AWK, значительно проще для написания сценариев трассировки, чем предлагаемые для BPF средства написания обработчиков на языках C, Python и Lua с внешними библиотеками.
Основные возможности системы трассировки ядра Linux (по состоянию на 4.9rc1):
- Динамическая трассировка на уровне ядра (BPF для kprobes);
- Динамическая трассировка пространства пользователя (BPF для uprobes);
- Статическая трассировка на уровне ядра (BPF для tracepoints);
- Обработка событий с сохранением хронометража (BPF с perf_event_open);
- События PMC (BPF с perf_event_open);
- Фильтрация (через программы BPF);
- Отладочный вывод (bpf_trace_printk ());
- Вывод в привязке к отдельным событиям (bpf_perf_event_output ());
- Использование переменных (глобальные и привязанные к потокам переменные, реализуемые через BPF maps);
- Ассоциативные массивы (через BPF maps);
- Подсчёт частоты выполнения операций (через BPF maps);
- Гистограммы (квадратичные, линейные и произвольные через BPF maps)
- Учёт времени выполнения операций и разницы во времени (через bpf_ktime_get_ns () и программы BPF);
- Трассировка стека ядра (BPF stackmap);
- Трассировка стека пользовательских процессов (BPF stackmap);
- Переопределение кольцевых буфров (perf_event_attr.write_backward).
Примеры использования некоторых утилит из набра bcc для решения задач трассировки:
- Отслеживание новых процессов:
# execsnoop PCOMM PID RET ARGS bash 15887 0 /usr/bin/man ls preconv 15894 0 /usr/bin/preconv -e UTF-8 man 15896 0 /usr/bin/tbl man 15897 0 /usr/bin/nroff -mandoc -rLL=169n -rLT=169n -Tutf8 man 15898 0 /usr/bin/pager -s nroff 15900 0 /usr/bin/locale charmap nroff 15901 0 /usr/bin/groff -mtty-char -Tutf8 -mandoc -rLL=169n -rLT=169n groff 15902 0 /usr/bin/troff -mtty-char -mandoc -rLL=169n -rLT=169n -Tutf8 groff 15903 0 /usr/bin/grotty
- Гистограмма задержек ввода/вывода:
# biolatency -m Tracing block device I/O... Hit Ctrl-C to end. ^C msecs : count distribution 0 -> 1 : 96 |************************************ | 2 -> 3 : 25 |********* | 4 -> 7 : 29 |*********** | 8 -> 15 : 62 |*********************** | 16 -> 31 : 100 |**************************************| 32 -> 63 : 62 |*********************** | 64 -> 127 : 18 |****** |
- Отслеживание типовых операций в ФС ext4, выполняемых дольше 5 мс:
# ext4slower 5 Tracing ext4 operations slower than 5 ms TIME COMM PID T BYTES OFF_KB LAT(ms) FILENAME 21:49:45 supervise 3570 W 18 0 5.48 status.new 21:49:48 supervise 12770 R 128 0 7.55 run 21:49:48 run 12770 R 497 0 16.46 nsswitch.conf 21:49:48 run 12770 R 1680 0 17.42 netflix_environment.sh 21:49:48 run 12770 R 1079 0 9.53 service_functions.sh 21:49:48 run 12772 R 128 0 17.74 svstat 21:49:48 svstat 12772 R 18 0 8.67 status 21:49:48 run 12774 R 128 0 15.76 stat 21:49:48 run 12777 R 128 0 7.89 grep 21:49:48 run 12776 R 128 0 8.25 ps 21:49:48 run 12780 R 128 0 11.07 xargs 21:49:48 ps 12776 R 832 0 12.02 libprocps.so.4.0.0 21:49:48 run 12779 R 128 0 13.21 cut [...]
- Отслеживание новых активных соединений по TCP (connect ()):
# tcpconnect PID COMM IP SADDR DADDR DPORT 1479 telnet 4 127.0.0.1 127.0.0.1 23 1469 curl 4 10.201.219.236 54.245.105.25 80 1469 curl 4 10.201.219.236 54.67.101.145 80 1991 telnet 6 ::1 ::1 23 2015 ssh 6 fe80::2000:bff:fe82:3ac fe80::2000:bff:fe82:3ac 22
- Отслеживание отзывчивости DNS при обработке библиотечных вызовов getaddrinfo ()/gethostbyname ():
# gethostlatency TIME PID COMM LATms HOST 06:10:24 28011 wget 90.00 www.iovisor.org 06:10:28 28127 wget 0.00 www.iovisor.org 06:10:41 28404 wget 9.00 www.netflix.com 06:10:48 28544 curl 35.00 www.netflix.com.au 06:11:10 29054 curl 31.00 www.plumgrid.com 06:11:16 29195 curl 3.00 www.facebook.com 06:11:25 29404 curl 72.00 foo 06:11:28 29475 curl 1.00 foo
- Суммарные данные о типах операций VFS, обновляемые ежесекундно:
# vfsstat TIME READ/s WRITE/s CREATE/s OPEN/s FSYNC/s 18:35:32: 231 12 4 98 0 18:35:33: 274 13 4 106 0 18:35:34: 586 86 4 251 0 18:35:35: 241 15 4 99 0
- Определение вызовов, ожидающих выполнения (off-CPU) в ядре и пространстве пользователя для заданного PID:
# offcputime -d -p 24347 Tracing off-CPU time (us) of PID 24347 by user + kernel stack... Hit Ctrl-C to end. ^C [...] ffffffff810a9581 finish_task_switch ffffffff8185d385 schedule ffffffff81085672 do_wait ffffffff8108687b sys_wait4 ffffffff81861bf6 entry_SYSCALL_64_fastpath -- 00007f6733a6b64a waitpid - bash (24347) 4952 ffffffff810a9581 finish_task_switch ffffffff8185d385 schedule ffffffff81860c48 schedule_timeout ffffffff810c5672 wait_woken ffffffff8150715a n_tty_read ffffffff815010f2 tty_read ffffffff8122cd67 __vfs_read ffffffff8122df65 vfs_read ffffffff8122f465 sys_read ffffffff81861bf6 entry_SYSCALL_64_fastpath -- 00007f6733a969b0 read - bash (24347) 1450908
- Отслеживание задержек при выполнении запросов MySQL:
# mysqld_qslower `pgrep -n mysqld` Tracing MySQL server queries for PID 14371 slower than 1 ms... TIME(s) PID MS QUERY 0.000000 18608 130.751 SELECT * FROM words WHERE word REGEXP '^bre.*n$' 2.921535 18608 130.590 SELECT * FROM words WHERE word REGEXP '^alex.*$' 4.603549 18608 24.164 SELECT COUNT(*) FROM words 9.733847 18608 130.936 SELECT count(*) AS count FROM words WHERE word REGEXP '^bre.*n$' 17.864776 18608 130.298 SELECT * FROM words WHERE word REGEXP '^bre.*n$' ORDER BY word
- Использование утилиты multi-tool для слежения за запросами входа в систему, обрабатываемыми через PAM:
# trace 'pam:pam_start "%s: %s", arg1, arg2' TIME PID COMM FUNC - 17:49:45 5558 sshd pam_start sshd: root 17:49:47 5662 sudo pam_start sudo: root 17:49:49 5727 login pam_start login: bgregg
Полный текст статьи читайте на OpenNet