Keluhan paling umum soal server — “kok lambat ya?” — tidak bisa dijawab dengan menebak-nebak. CPU adalah sumber daya yang paling sering diperebutkan: satu proses encoding video bisa membuat terminal terasa patah-patah, dan satu query database yang buruk bisa membuat seluruh layanan sesak. Pada chapter ini kita belajar membaca metrik-metrik CPU, memakai top sebagai kamera langsung, memahami mpstat untuk pemakaian per core, lalu melatih keterampilan praktis: mem-parsing output alat monitoring dengan awk — fondasi untuk alarm otomatis.

Empat Metrik CPU yang Perlu Dipantau #

Pemantauan CPU selalu kembali ke empat pertanyaan berikut:

MetrikPertanyaan yang dijawab
Utilization (%us, %sy)berapa lama core benar-benar sibuk menghitung, dan untuk siapa — program (us) atau kernel (sy)
Iowait (%wa)apakah ada core yang menganggur justru karena menunggu disk
Context switchseberapa sering kernel mencabut core dari satu proses lalu memberikannya ke proses lain
Load averageberapa banyak pekerjaan yang sedang mengantri

Dua metrik pertama terlihat mirip tetapi menuntut reaksi yang berlawanan. Utilization tinggi berarti core benar-benar bekerja; bila angka ini terus menyentuh 100%, sistem memang kekurangan daya komputasi. Sebaliknya, iowait tinggi berarti core menganggur sambil menunggu — ada proses yang ingin berjalan tetapi datanya belum datang dari disk. Menambah core pada kasus iowait hanya menambah penunggu baru; obat yang tepat adalah mempercepat disk atau mengurangi I/O. Karena itu kolom %wa selalu layak dicurigai lebih dulu sebelum menyimpulkan “CPU kewalahan”.

Context switch — kernel mencabut core dari satu proses lalu memberikannya ke proses lain — wajar dalam jumlah kecil; angka cs pada vmstat yang sangat tinggi menandakan banyak proses berebut core secara agresif.

top: Kamera Langsung Pemakaian CPU #

Perintah top sudah kita pakai di Chapter ps, top, dan htop untuk mengurutkan proses. Sekarang kita bedah baris ketiganya — baris %Cpu(s) — yang merangkum keadaan seluruh core. Berikut contoh tampilan top pada mesin yang sedang memproses video:

text
top - 14:23:01 up 5 days,  3:12,  2 users,  load average: 1.20, 0.98, 0.75
Tasks:  95 total,   2 running,  93 sleeping,   0 stopped,   0 zombie
%Cpu(s): 12.5 us,  3.2 sy,  0.0 ni, 82.1 id,  2.1 wa,  0.0 hi,  0.1 si,  0.0 st
MiB Mem :  15903.6 total,    8412.3 free,    2100.1 used,    5391.2 buff/cache

Tiap pasangan angka-label menjelaskan ke mana waktu core pergi dalam satu periode sampling:

KolomArti
uskode program user (aplikasi, skrip, database)
sykode kernel (syscall, driver, manajemen memori)
niprogram yang dijalankan dengan prioritas diturunkan lewat nilai nice positif (dibahas di Chapter nice dan renice )
idbenar-benar menganggur, tidak ada pekerjaan
wamenganggur karena menunggu I/O
hi, simelayani interupsi perangkat dan softirq jaringan
stwaktu yang “dicuri” hypervisor pada mesin virtual

Pada tampilan di atas, id 82.1 menunjukkan mayoritas waktu core menganggur, sementara wa 2.1 masih wajar. Saat top berjalan, tombol 1 memecah baris ini menjadi satu baris per core, P mengurutkan proses berdasarkan %CPU, dan q keluar. Daftar lengkap kolom dan tombolnya terdokumentasi di top(1) .

mpstat: Memecah Pemakaian Per Core #

Rata-rata seluruh core bisa menyesatkan. Sebuah aplikasi single-threaded yang sibuk hanya membebani satu core penuh; pada mesin 4 core, rata-rata sistem hanya menunjukkan sekitar 25% padahal satu core sudah jenuh. Alat mpstat dari paket sysstat menjawab ini dengan melaporkan satu baris per core. Mesin latihan kita tidak memasang paket itu, jadi berikut contoh tampilan tipikal mpstat 2 1 (sampling 2 detik, sekali):

text
Linux 6.1.0-18-amd64 (server-kantor)  14/05/26  _x86_64_  (4 CPU)

14:23:01     CPU    %usr   %sys   %iowait  %idle
14:23:03     all   12.50   3.20     2.10    82.10
14:23:03       0   45.20   1.00     0.30    53.50
14:23:03       1    2.10   0.80     7.90    89.20
14:23:03       2    1.40   0.90     0.20    97.50
14:23:03       3    1.30   0.70     0.00    98.00

Baris all cocok untuk ringkasan, tetapi baris per CPU yang justru menarik: core 0 setengah waktunya melayani program user (%usr 45.20) — kandidat kuat aplikasi single-threaded yang sibuk — sementara core 1 banyak menghabiskan waktu menunggu I/O (%iowait 7.90). Kedua gejala itu hilang bila kita hanya membaca baris rata-rata. Makna tiap kolomnya dirinci di mpstat(1) . Untuk pemakaian harian, htop menampilkan grafik batang per core yang mudah dibaca sekilas, sedangkan atop mencatat pemakaian per proses ke dalam file sehingga cocok untuk analisis setelah kejadian.

/proc/loadavg: Beban Tanpa Alat Apa Pun #

Semua alat di atas akhirnya membaca sumber yang sama: procfs. File /proc/loadavg merangkum antrean kerja sistem dalam lima field — misalnya 1.20 0.98 0.75 1/206 31645 — dan tersedia di semua instalasi Linux tanpa perlu memasang paket apa pun.

Tiga field pertama adalah load average periode 1, 5, dan 15 menit — angka antrean yang dibahas tuntas di Chapter Uptime dan Load Average . Field keempat (1/206) berarti satu proses sedang berjalan dari total 206 proses hidup; field kelima adalah PID proses yang terakhir dibuat kernel. Karena isinya berubah setiap detik dan berbeda antar mesin, nilai di atas cukup kita pahami polanya — spesifikasi lengkap kelima field ada di proc(5) .

Latihan Parsing: Membaca Output top dengan awk #

Output top diperbarui terus-menerus dan angkanya berbeda di setiap mesin, sehingga latihan parsing paling aman dilakukan pada salinan statis yang formatnya sama persis dengan output asli. Kita buat fixture top-output.txt lalu mengajukan tiga pertanyaan pada data itu: apa ringkasan %Cpu(s), berapa rata-rata kolom %CPU semua proses, dan proses mana yang menghabiskan lebih dari 5%:

bash
cat > top-output.txt <<'AKHIR'
top - 14:23:01 up 5 days,  3:12,  2 users,  load average: 1.20, 0.98, 0.75
Tasks:  95 total,   2 running,  93 sleeping,   0 stopped,   0 zombie
%Cpu(s): 12.5 us,  3.2 sy,  0.0 ni, 82.1 id,  2.1 wa,  0.0 hi,  0.1 si,  0.0 st
MiB Mem :  15903.6 total,    8412.3 free,    2100.1 used,    5391.2 buff/cache
MiB Swap:   1023.9 total,    1023.9 free,      0.0 used.  13803.5 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   2481 budi      20   0  325104  24160   9840 R  45.2   0.1   0:01.23 ffmpeg
   1902 budi      20   0  864312 310412  12480 S  25.8   1.9  12:45.10 chromium
   1120 root      20   0  105210   4210   3300 S   3.1   0.0   0:12.03 systemd
    990 www-data  20   0  142600  51200  18040 S   1.9   0.3   1:02.47 nginx
   3310 budi      20   0   15340   3900   3200 R   0.4   0.0   0:00.09 top
AKHIR

awk '/^%Cpu/ {
  printf "ringkasan: user %s%% | kernel %s%% | idle %s%% | iowait %s%%\n", $2, $4, $8, $10
}' top-output.txt

awk '$1 ~ /^[0-9]+$/ {
  n++
  jumlah += $9
}
END {
  printf "proses terpantau: %d | rata-rata %%CPU: %.1f\n", n, jumlah/n
}' top-output.txt

awk '$1 ~ /^[0-9]+$/ && $9 > 5 {
  printf "proses panas: pid %-5s %-9s %s%%\n", $1, $12, $9
}' top-output.txt

Output yang Dihasilkan:

text
ringkasan: user 12.5% | kernel 3.2% | idle 82.1% | iowait 2.1%
proses terpantau: 5 | rata-rata %CPU: 15.3
proses panas: pid 2481  ffmpeg    45.2%
proses panas: pid 1902  chromium  25.8%

Mari kita telaah tiga potongan awk di atas:

  1. **Baris 16–18 (awk '/^%Cpu/ ...')**: pola /^%Cpu/hanya cocok dengan baris ringkasan CPU. Pada baris itu, field$2adalah angka di depan labelus, $4di depansy, $8di depanid, dan $10di depanwa— posisi field pada formattopmemang selalu beraturan seperti ini.printf` kemudian merangkai keempat angka dengan labelnya masing-masing.
  2. **Baris 20–26 (awk '$1 ~ /^[0-9]+$/ ...')**: pola $1 ~ /^[0-9]+$/ hanya meloloskan baris yang kolom pertamanya PID (angka murni), sehingga baris judul dan header tabel otomatis terlewati. Blok aksi menghitung banyaknya baris (n) dan menjumlahkan kolom kesembilan ($9, yaitu %CPU), lalu blok END` mencetak rata-ratanya.
  3. **Baris 28–30 (awk '$1 ~ /^[0-9]+$/ && $9 > 5 ...')**: pola gabungan menambah syarat $9 > 5, jadi hanya proses dengan pemakaian di atas 5% yang dicetak. Kolom $12(namaCOMMAND`) ikut ditampilkan supaya kita langsung tahu pelakunya tanpa membaca tabel mentahnya.

Pola “saring baris, jumlahkan kolom, cetak ringkasan” inilah yang dipakai berulang-ulang di semua alat monitoring berbasis teks. Di produksi, cukup ganti top-output.txt dengan hasil top -bn1 yang disimpan berkala oleh cron atau systemd timer.

Skrip Mini: Alarm Beban dari loadavg #

Field pertama /proc/loadavg bisa dipakai sebagai alarm sederhana: bandingkan angka itu dengan jumlah core, lalu nyatakan status. Kita latih pada dua fixture yang meniru isi file asli — satu sistem santai, satu sistem sesak:

bash
printf '1.20 0.98 0.75 1/206 31645\n' > loadavg-santai.txt
printf '6.40 5.10 4.20 3/206 90123\n' > loadavg-sibuk.txt

cat > cek-beban.sh <<'SKRIP'
#!/bin/bash
# cek-beban.sh <file-loadavg> <jumlah-core>
load1=$(awk '{print $1}' "$1")
rasio=$(awk -v l="$load1" -v c="$2" 'BEGIN { printf "%.2f", l/c }')
printf "load 1 menit: %-5s core: %s rasio: %-5s -> " "$load1" "$2" "$rasio"

if awk -v r="$rasio" 'BEGIN { exit !(r < 0.7) }'; then
    echo "SEHAT"
elif awk -v r="$rasio" 'BEGIN { exit !(r < 1.0) }'; then
    echo "WASPADA"
else
    echo "KRITIS"
fi
SKRIP

bash cek-beban.sh loadavg-santai.txt 4
bash cek-beban.sh loadavg-sibuk.txt 4

Output yang Dihasilkan:

text
load 1 menit: 1.20  core: 4 rasio: 0.30  -> SEHAT
load 1 menit: 6.40  core: 4 rasio: 1.60  -> KRITIS

Bedah skrip di atas:

  1. Baris 7 (load1=$(awk ...)): mengambil field pertama fixture — persis cara yang sama untuk membaca /proc/loadavg di mesin nyata, cukup ganti argumen filenya.
  2. Baris 8 (rasio=$(awk ...)): membagi load dengan jumlah core di dalam awk agar pembulatan dua desimal terjadi di satu tempat. Rasio 0.30 berarti sistem hanya memakai 30% kapasitas antrean.
  3. Baris 11–17 (if awk ... fi): trik exit !(kondisi) membuat awk menjadi penguji aritmetika yang mengembalikan status sukses/gagal — pola yang aman dipakai di bash untuk perbandingan pecahan, karena [ bawaan shell tidak bisa membandingkan angka desimal.
  4. Baris 20–21: dua fixture diuji dengan jumlah core yang sama. Load 1.20 pada 4 core menghasilkan rasio 0.30 (SEHAT), sedangkan load 6.40 menghasilkan 1.60 — antrean sudah 60% lebih panjang dari kapasitas core, status KRITIS.

Di mesin nyata, nproc mengisi argumen kedua secara otomatis: bash cek-beban.sh /proc/loadavg "$(nproc)". Interpretasi rasio terhadap jumlah core — dan alasan load bisa tinggi tanpa CPU penuh — kita bedah tuntas di Chapter Uptime dan Load Average .

CPU hanya satu dari empat sumber daya yang diperebutkan proses. Sumber daya berikutnya lebih pendek batasnya dan konsekuensinya lebih keras: ketika memori habis, kernel tidak sekadar memperlambat proses — kernel membunuhnya. Kita beralih ke pemantauan memori pada Chapter Memory Monitoring .