Užitečné nástroje pro sledování výkonu Linuxu

31. října 2022

Snad každý, kdo provozuje Linux občas potřebuje zjistit, co se mu v systému děje.

Podívejte se nejprve na pár užitečných příkazů, které se můžou hodit:

  • ethtool – nástroj na konfiguraci a sledování síťového hardware a driveru
  • free – vypíše volnou a spotřebovanou paměť
  • htop – interaktivní prohlížeč procesů
  • iftop – zobrazí využití šířky pásma jednotlivými hostiteli
  • iotop – zobrazí vstupně/výstupní operace
  • ip – příkaz pro zobrazení a nastavení routingů, síťových zařízení a rozhraní
  • iptraf – interaktivní IP LAN monitor
  • lsof – vypíše otevřené soubory
  • ltrace – trasuje volání knihoven
  • netstat – vypíše síťová spojení, routovací tabulky, statistiky rozhraní a další
  • ps – vypíše aktuální procesy
  • pstree – vypíše strom procesů
  • slabtop – vypisuje v reálném čase informace o slab cache kernelu
  • ss – vypíše statistiku skocketů podobně jako
  • netstat strace – trasuje systémová volání a signály
  • tcpdump – paketový analyzér
  • top – vypíše procesy
  • vmstat – report využití virtuální paměti

Všechny příkazy v jednom článku popsat nelze. Ukažme si alespoň něco. Například situaci, kdy se o VPS stará někdo, kdo není k dispozici a nemůže nám podat informace o tom, co kde a jak je na serveru nastavené.

V takovém případě spustím pstree, abych se podíval co tam běží:

vyboh:~# pstree
systemd─┬─VGAuthService
├─acpid
├─agetty
├─apache2─┬─2*[apache2───51*[{apache2}]] │ └─2*[cronolog] ├─atd
├─cdbad
├─cron
├─cwebd
├─dbus-daemon
├─inetd
├─litespeed─┬─litespeed───node───6*[{node}] │ └─4*[litespeed] ├─mariadbd───43*[{mariadbd}] ├─master─┬─anvil
│ ├─pickup
│ ├─qmgr
│ └─tlsmgr
├─memcached───9*[{memcached}] ├─mosquitto
├─php-fpm5.6───2*[php-fpm5.6] ├─php-fpm7.4───2*[php-fpm7.4] ├─php-fpm8.0───2*[php-fpm8.0] ├─php-fpm8.1───2*[php-fpm8.1] ├─pure-ftpd-mysql
├─redis-server───4*[{redis-server}] ├─rsyslogd───3*[{rsyslogd}] ├─snmpd───icm_remote_serv
├─squid───squid─┬─log_file_daemon
│ └─pinger
├─sshd─┬─sshd───sshd───bash───sudo───su───bash───pstree
│ └─sshd───sshd
├─systemd───(sd-pam)
├─systemd-journal
├─systemd-logind
├─systemd-timesyn───{systemd-timesyn}
├─systemd-udevd
└─vmtoolsd───{vmtoolsd}
vyboh:~#

Dejme tomu, že je problém s LiteSpeed a já naprosto netuším, kde to má logy.

Takže si vypíšeme procesy litespeed:

vyboh:~# ps ax | grep litespeed
704 ? S 0:34 openlitespeed (lshttpd - main)
710 ? S 0:05 openlitespeed (lscgid)
722 ? S 1:22 openlitespeed (lshttpd - #01)
723 ? S 1:21 openlitespeed (lshttpd - #02)
724 ? S 1:22 openlitespeed (lshttpd - #03)
725 ? S 1:22 openlitespeed (lshttpd - #04)
1866725 pts/0 S+ 0:00 grep litespeed
vyboh:~#

No a teď už se jenom podíváme co má otevřený proces 704 a vyhledáme v tom výraz log:


vyboh:~# lsof -p 704 | grep log
litespeed 704 root 3w REG 8,1 960874 14511 /usr/local/lsws/logs/stderr.log
litespeed 704 root 30w REG 8,1 7369852 29739201 /usr/local/lsws/admin/logs/access.log
litespeed 704 root 31w REG 8,1 8983673 13982 /usr/local/lsws/logs/access.log
vyboh:~#

Samozřejmě se můžeme také podívat, co ten proces 704 dělá:


vyboh:~# strace -p 704
strace: Process 704 attached
restart_syscall(<... resuming interrupted read ...>) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
poll([{fd=32, events=POLLIN}, {fd=5, events=POLLIN}, {fd=7, events=POLLIN}], 3, 1000) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---
rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call)
stat("/tmp/lshttpd/lshttpd.pid", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
kill(710, 0) = 0
lstat("/usr/local/lsws/logs/access.log", {st_mode=S_IFREG|0640, st_size=8983863, ...}) = 0
lstat("/usr/local/lsws/logs/error.log", {st_mode=S_IFREG|0644, st_size=8858113, ...}) = 0
lstat("/usr/local/lsws/logs/stderr.log", {st_mode=S_IFREG|0644, st_size=960874, ...}) = 0
lstat("/usr/local/lsws/admin/logs/access.log", {st_mode=S_IFREG|0644, st_size=7369852, ...}) = 0
lstat("/usr/local/lsws/admin/logs/error.log", {st_mode=S_IFREG|0644, st_size=3087, ...}) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
poll([{fd=32, events=POLLIN}, {fd=5, events=POLLIN}, {fd=7, events=POLLIN}], 3, 1000) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---
rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call)
stat("/tmp/lshttpd/lshttpd.pid", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
kill(710, 0) = 0
lstat("/usr/local/lsws/logs/access.log", {st_mode=S_IFREG|0640, st_size=8983863, ...}) = 0
lstat("/usr/local/lsws/logs/error.log", {st_mode=S_IFREG|0644, st_size=8858113, ...}) = 0
lstat("/usr/local/lsws/logs/stderr.log", {st_mode=S_IFREG|0644, st_size=960874, ...}) = 0
lstat("/usr/local/lsws/admin/logs/access.log", {st_mode=S_IFREG|0644, st_size=7369852, ...}) = 0
lstat("/usr/local/lsws/admin/logs/error.log", {st_mode=S_IFREG|0644, st_size=3087, ...}) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
poll([{fd=32, events=POLLIN}, {fd=5, events=POLLIN}, {fd=7, events=POLLIN}], 3, 1000) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---
rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call)
stat("/tmp/lshttpd/lshttpd.pid", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
kill(710, 0) = 0
lstat("/usr/local/lsws/logs/access.log", {st_mode=S_IFREG|0640, st_size=8983863, ...}) = 0
lstat("/usr/local/lsws/logs/error.log", {st_mode=S_IFREG|0644, st_size=8858113, ...}) = 0
lstat("/usr/local/lsws/logs/stderr.log", {st_mode=S_IFREG|0644, st_size=960874, ...}) = 0
lstat("/usr/local/lsws/admin/logs/access.log", {st_mode=S_IFREG|0644, st_size=7369852, ...}) = 0
lstat("/usr/local/lsws/admin/logs/error.log", {st_mode=S_IFREG|0644, st_size=3087, ...}) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, 0x7ffc35211d70) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, ^Cstrace: Process 704 detached
<detached ...>
vyboh:~#

Pokud stále hledáme logy, jsou tam také vidět. Podívejme se také, jak to vypadá z pohledu knihoven:


vyboh:~# ltrace -p 704
--- SIGALRM (Alarm clock) ---
time(0) = 1666793113
getenv("OLS_PID_FILE") = "/tmp/lshttpd/lshttpd.pid"
__xstat(1, "/tmp/lshttpd/lshttpd.pid", 0x7ffc35215d20) = 0
strlen("lscgid") = 6
strcmp("lscgid", "lscgid") = 0
kill(710, 0) = 0
__lxstat(1, "/usr/local/lsws/logs/access.log", 0x7ffc35215cd0) = 0
__lxstat(1, "/usr/local/lsws/logs/error.log", 0x7ffc35215cd0) = 0
__lxstat(1, "/usr/local/lsws/logs/stderr.log", 0x7ffc35215cf0) = 0
__lxstat(1, "/usr/local/lsws/admin/logs/acces"..., 0x7ffc35215ca0) = 0
__lxstat(1, "/usr/local/lsws/admin/logs/error"..., 0x7ffc35215cb0) = 0
nanosleep(0x7ffc35211d70, 0x7ffc35211d70, 0, 0x7f3830d57050) = 0
nanosleep(0x7ffc35211d70, 0x7ffc35211d70, 0, 0x7f3831803050) = 0
nanosleep(0x7ffc35211d70, 0x7ffc35211d70, 0, 0x7f3831886050) = 0
nanosleep(0x7ffc35211d70, 0x7ffc35211d70, 0, 0x7f383188e060) = 0
poll(0x7ffc35215e90, 3, 1000, 0x7f38319725ca <no return ...>
--- SIGALRM (Alarm clock) ---
<... poll resumed> ) = 0xffffffff
time(0) = 1666793114
getenv("OLS_PID_FILE") = "/tmp/lshttpd/lshttpd.pid"
__xstat(1, "/tmp/lshttpd/lshttpd.pid", 0x7ffc35215d20) = 0
strlen("lscgid") = 6
strcmp("lscgid", "lscgid") = 0
kill(710, 0) = 0
__lxstat(1, "/usr/local/lsws/logs/access.log", 0x7ffc35215cd0) = 0
__lxstat(1, "/usr/local/lsws/logs/error.log", 0x7ffc35215cd0) = 0
__lxstat(1, "/usr/local/lsws/logs/stderr.log", 0x7ffc35215cf0) = 0
__lxstat(1, "/usr/local/lsws/admin/logs/acces"..., 0x7ffc35215ca0) = 0
__lxstat(1, "/usr/local/lsws/admin/logs/error"..., 0x7ffc35215cb0) = 0
nanosleep(0x7ffc35211d70, 0x7ffc35211d70, 0, 0x7f3830d57050) = 0
nanosleep(0x7ffc35211d70, 0x7ffc35211d70, 0, 0x7f3831803050) = 0
nanosleep(0x7ffc35211d70, 0x7ffc35211d70, 0, 0x7f3831886050) = 0
nanosleep(0x7ffc35211d70, 0x7ffc35211d70, 0, 0x7f383188e060) = 0
poll(0x7ffc35215e90, 3, 1000, 0x7f38319725ca <no return ...>
--- SIGALRM (Alarm clock) ---
<... poll resumed> ) = 0xffffffff
time(0) = 1666793115
getenv("OLS_PID_FILE") = "/tmp/lshttpd/lshttpd.pid"
__xstat(1, "/tmp/lshttpd/lshttpd.pid", 0x7ffc35215d20) = 0
strlen("lscgid") = 6
strcmp("lscgid", "lscgid") = 0
kill(710, 0) = 0
__lxstat(1, "/usr/local/lsws/logs/access.log", 0x7ffc35215cd0) = 0
__lxstat(1, "/usr/local/lsws/logs/error.log", 0x7ffc35215cd0) = 0
__lxstat(1, "/usr/local/lsws/logs/stderr.log", 0x7ffc35215cf0) = 0
__lxstat(1, "/usr/local/lsws/admin/logs/acces"..., 0x7ffc35215ca0) = 0
__lxstat(1, "/usr/local/lsws/admin/logs/error"..., 0x7ffc35215cb0) = 0
nanosleep(0x7ffc35211d70, 0x7ffc35211d70, 0, 0x7f3830d57050^Cvyboh:~#

Tak a teď se například podíváme na jakých portech nám to běží:

vyboh:~# netstat -nap | head
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 217.198.116.182:443 0.0.0.0:* LISTEN 772/apache2
tcp 0 0 217.198.116.182:1883 0.0.0.0:* LISTEN 686/mosquitto
tcp 0 0 0.0.0.0:7080 0.0.0.0:* LISTEN 704/openlitespeed (
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 986/mariadbd
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 638/redis-server 12
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 616/memcached
tcp 0 0 217.198.116.182:80 0.0.0.0:* LISTEN 772/apache2
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 1170/pure-ftpd (SER
vyboh:~# netstat -nap | grep openlitespeed
tcp 0 0 0.0.0.0:7080 0.0.0.0:* LISTEN 704/openlitespeed (
tcp6 0 0 :::8443 :::* LISTEN 704/openlitespeed (
tcp6 0 0 :::8443 :::* LISTEN 704/openlitespeed (
tcp6 0 0 :::8443 :::* LISTEN 704/openlitespeed (
tcp6 0 0 :::8443 :::* LISTEN 704/openlitespeed (
tcp6 0 0 :::8080 :::* LISTEN 704/openlitespeed (
tcp6 0 0 :::8080 :::* LISTEN 704/openlitespeed (
tcp6 0 0 :::8080 :::* LISTEN 704/openlitespeed (
tcp6 0 0 :::8080 :::* LISTEN 704/openlitespeed (
udp 0 0 0.0.0.0:7080 0.0.0.0:* 704/openlitespeed (
udp6 0 0 :::40009 :::* 724/openlitespeed (
udp6 0 0 :::37032 :::* 723/openlitespeed (
udp6 0 0 :::40482 :::* 725/openlitespeed (
udp6 0 0 :::54906 :::* 722/openlitespeed (
unix 2 [ ACC ] STREAM LISTENING 22448 704/openlitespeed ( /usr/local/lsws/cgid/cgid.sock
unix 2 [ ACC ] STREAM LISTENING 22486 722/openlitespeed ( /tmp/lshttpd/cernalistina.eu:_node_.sock
unix 2 [ ACC ] STREAM LISTENING 22492 722/openlitespeed ( /tmp/lshttpd/lsphp.sock
unix 2 [ ACC ] STREAM LISTENING 22438 704/openlitespeed ( /usr/local/lsws/admin/tmp/admin.sock.7435
unix 3 [ ] DGRAM 22481 704/openlitespeed (
unix 3 [ ] STREAM CONNECTED 22443 704/openlitespeed (
unix 3 [ ] DGRAM 22480 704/openlitespeed (
unix 3 [ ] STREAM CONNECTED 22444 704/openlitespeed (
vyboh:~#

Na závěr snad už jenom jednu ukázku toho, jak pomocí tcpdump zobrazit v reálném čase příkazy posílané MySQL serveru naslouchajícím na eth0 (příklad není můj, ale občas se to hodí).

vyboh:~# tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | perl -e '
while(<>) { chomp; next if /^[^ ]+[ ]*$/;
if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER)/i) {
if (defined $q) { print "$q\n"; }
$q=$_;
} else {
$_ =~ s/^[ \t]+//; $q.=" $_";
}
}'
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 byte

Ceny energií stoupají, my nabízíme efektivní řešení.

Přejděte do cloudu a ušetřete!

PORADIT S VÝBĚREM

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *