Server Linux menyediakan fitur-fitur yang sederhana tetapi sangat bermanfaat untuk melakukan monitoring terhadap server. Dalam tutorial ini menggunakan Ubuntu, MySQL, PHP-FPM dan Apache2. Eksekusi query MySQL dapat dimonitor dengan MySQL Workbench.
Daftar Isi
Monitoring MySQL, PHP-FPM dan Apache2
watch, ps, cat, grep, wc, free, head, tail, top dan awk dapat digunakan untuk melakukan monitoring penggunaan CPU, thread dan Memory aplikasi PHP-FPM dan Apache2 secara live dalam satu layar. MySQL Workbench dapat digunakan untuk monitoring slow query.
— Monitoring Apache2, PHP FPM dan MySQL
Monitoring MySQL
Gunakan MySQL Workbench
- Buka menu Administration > Client Connections
- Centang pada Hide Sleeping Connections. Hilangkan centang pada Don’t load full thread info
- Klik kanan pada baris yang berjalan lebih dari 5 detik, kemudian pilih Copy Info
Penyelesaian Slow Query
Setting Moodle Untuk Administrator atau Programmer
Monitoring PHP-FPM dan Apache2
Syntax
watch "echo 'MySQL: '; echo -n 'All: '; ps -C mysqld -T --no-headers | wc -l; echo ''; echo 'PHP: '; echo -n 'All: '; ps -C php-fpmx.x -T --no-headers | wc -l; cat /etc/php/x.x/fpm/php-fpm.conf | grep 'process.max = ' | grep -vE '; '; php_=\$(( \$(ps -C php-fpmx.x -T --no-headers | wc -l) * 100 / \$(cat /etc/php/x.x/fpm/php-fpm.conf | grep 'process.max = ' | grep -vE '; ' | awk '{print \$3}') )); php_=\${php_%.*}; echo -n '<div id="php">'; for i in \$(seq 1 \$((\$php_ / 4))); do echo -n '='; done; for i in \$(seq 1 \$((25 - (\$php_ / 4)))); do echo -n '_'; done; echo -n '</div>'; echo ''; echo -n 'User johndoe: '; ps -C php-fpmx.x -T --no-headers -o user | grep johndoe | wc -l; echo ''; echo 'APACHE: '; ps -C apache2 -T --no-headers | wc -l; cat /etc/apache2/mods-enabled/mpm_event.conf | grep 'MaxRequestWorkers' | grep -vE '#'; apache_=\$(( \$(ps -C apache2 -T --no-headers | wc -l) * 100 / \$(cat /etc/apache2/mods-enabled/mpm_event.conf | grep 'MaxRequestWorkers' | grep -vE '#' | awk '{print \$2}') )); apache_=\${apache_%.*}; echo -n '<div id="apa">'; for i in \$(seq 1 \$((\$apache_ / 4))); do echo -n '='; done; for i in \$(seq 1 \$((25 - (\$apache_ / 4)))); do echo -n '_'; done; echo -n '</div>'; echo ''; echo ''; echo 'Memory (available >0.5G)'; free -hm | awk '{print \$7}' | head -2 | tail -1; mem_=\$(( \$(free -m | awk '{print \$3}' | head -2 | tail -1) * 100 / \$(free -m | awk '{print \$2}' | head -2 | tail -1) )); mem_=\${mem_%.*}; bufcac_=\$(( \$(free -m | awk '{print \$6}' | head -2 | tail -1) * 100 / \$(free -m | awk '{print \$2}' | head -2 | tail -1) )); bufcac_=\${bufcac_%.*}; echo -n '<div id="mem">'; for i in \$(seq 1 \$((\$mem_ / 4))); do echo -n '='; done; for i in \$(seq 1 \$((\$bufcac_ / 4))); do echo -n 'b'; done; for i in \$(seq 1 \$((25 - (\$mem_ / 4) - (\$bufcac_ / 4)))); do echo -n '_'; done; echo -n '</div>'; echo ''; echo 'b: buffer/cache'; echo ''; echo 'Memory (swap =0)'; free -hm | awk '{print \$3}' | head -3 | tail -1; echo''; bmon -p 'eth*' -b -o format:fmt='\$(element:name) \$(attr:rxrate:bytes) \$(attr:txrate:bytes) \$(attr:rxrate:packets) \$(attr:txrate:packets) ' -o format:quitafter=2 | awk '{print \$6\" rx/tx \"\$7/1024\"/\"\$8/1024\" Kbps \"\$9\"/\"\$10\" pps\"}'; echo ''; echo '%CPU (<100.0)'; cpu_=\$(printf %.f \$(top -bn2 | grep '%Cpu' | tail -1 | awk '{print 100-\$8}';)); echo \$cpu_; echo -n '<div id="cpu">'; for i in \$(seq 1 \$((\${cpu_%.*} / 4))); do echo -n '='; done; for i in \$(seq 1 \$((25 - (\${cpu_%.*} / 4)))); do echo -n '_'; done; echo -n '</div>'"
Output
MySQL:
All: 135
PHP:
All: 50
process.max = 750
=------------------------
User johndoe: 41
APACHE:
193
MaxRequestWorkers 1000
====---------------------
Memory (available >0.5G)
5,9G
==bbbbbbbb---------------
b: buffer/cache
Memory (swap =0)
0B
eth0 | v 489.42/46.4539 ^ Kbps | v 387.97/216.98 ^ pps
%CPU (<100.0)
24
======-------------------
Penjelasan
watch <command>
digunakan untuk menjalankan perintah secara berulang setiap 2 detik apabila menggunakan setting standar. Oleh karena itu, data monitoring di atas berubah setiap 2 detik.
Perintah watch <command>
menjalankan perintah sh -c <command>
.
ps <option>
digunakan untuk menampilkan proses terkini. -T
digunakan untuk menampilkan thread yang berjalan. -C
digunakan untuk menampilkan proses tertentu. --no-headers
digunakan untuk menampilkan daftar proses tanpa menampikan header.
Untuk menampilkan berapa thread yang berjalan, digunakan opsi -T
dan --no-headers
.
wc -l
digunakan untuk menampilkan jumlah baris.
Di bawah ini adalah contoh dari penerapan ps
dan wc
. Perintah terakhir adalah perintah yang digunakan untuk menampilkan berapa jumlah thread yang berjalan pada suatu proses.
$ ps -C php-fpm7.0 -T
PID SPID TTY TIME CMD
9306 9306 ? 00:00:23 php-fpm7.0
9311 9311 ? 00:00:00 php-fpm7.0
9312 9312 ? 00:06:22 php-fpm7.0
$ ps -C php-fpm7.0 -T | wc -l
4
$ ps -C php-fpm7.0 -T --no-headers
9306 9306 ? 00:00:23 php-fpm7.0
9311 9311 ? 00:00:00 php-fpm7.0
9312 9312 ? 00:06:22 php-fpm7.0
$ ps -C php-fpm7.0 -T --no-headers | wc -l
3
cat
digunakan untuk menampilkan gabungan dari isi file dan teks.
grep <pattern>
digunakan untuk menampilkan baris yang cocok dengan pattern. Opsi -vE <pattern>
pada grep digunakan untuk mengecualikan pattern agar tidak ditampilkan.
$ echo "; sample 1" > /home/johndoe/sample.txt
$ echo "sample 2" >> /home/johndoe/sample.txt
$ echo "sampel 3" >> /home/johndoe/sample.txt
$ cat /home/johndoe/sample.txt
; sample 1
sample 2
sampel 3
$ cat /home/johndoe/sample.txt | grep sample
; sample 1
sample 2
$ cat /home/johndoe/sample.txt | grep sample | grep -vE "; "
sample 2
Bagaimana jika ingin menampilkan proses dari user tertentu?
Gunakan grep <pattern>
setelah ps
dengan opsi -o
. Opsi -eo
pada ps
digunakan untuk menampilkan kolom tertentu.
Perhatikan contoh di bawah ini
$ ps -C php-fpm7.0 -T -o user
USER
www-data
www-data
johndoe
johndoe
johndoe
$ ps -C php-fpm7.0 -T -o user --no-headers
www-data
www-data
johndoe
johndoe
johndoe
$ ps -C php-fpm7.0 -T -o user --no-headers | grep johndoe
johndoe
johndoe
johndoe
$ ps -C php-fpm7.0 -T -o user --no-headers | grep johndoe | wc -l
3
free <option>
digunakan untuk menampilkan penggunaan memori di dalam sistem. Opsi -h
digunakan agar mudah dibaca. Opsi -m
digunakan agar ditampilkan dalam satuan mebibyte.
awk '{print $<column>}'
digunakan untuk menampilkan data pada kolom tertentu. head -<row>
digunakan untuk menampilkan beberapa baris teratas. tail -<row>
digunakan untuk menampilkan beberapa baris terbawah.
$ free -hm
total used free shared buff/cache available
Mem: 31G 11G 477M 470M 19G 19G
Swap: 11G 0B 11G
$ free -hm | awk "{print $4}"
shared
470M
11G
$ free -hm | awk "{print $4}" | head -2
shared
470M
$ free -hm | awk "{print $4}" | head -2 | tail -1
470M
bmon
digunakan untuk menampilkan informasi tentang jaringan (bandwidth monitor), membutuhkan waktu 1 detik. Gunakan ifconfig
untuk mendapatkan informasi kartu jaringan yang tersedia.
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 2000
...
$ bmon -p 'eth0' -b -o format:fmt='$(element:name) $(attr:rxrate:bytes) $(attr:txrate:bytes) $(attr:rxrate:packets) $(attr:txrate:packets) ' -o format:quitafter=2
eth0 0.00 0.00 0.00 0.00 eth0 73134.35 3379.69 69.99 41.00
$ bmon -p 'eth0' -b -o format:fmt='$(element:name) $(attr:rxrate:bytes) $(attr:txrate:bytes) $(attr:rxrate:packets) $(attr:txrate:packets) ' -o format:quitafter=2 | awk '{print $6" | v "$7/1024"/"$8/1024" ^ Kbps | v "$9"/"$10" ^ pps"}'
eth0 | v 489.42/46.4539 ^ Kbps | v 387.97/216.98 ^ pps
top -bn2
digunakan untuk menampilkan gambaran proses yang berjalan di sistem tidak dalam real time agar teks dapat diproses. Membutuhkan waktu 2 detik
printf %.f
atau ${variable%.*}
berfungsi untuk menghilangkan desimal.
for
digunakan untuk looping
$ a=100.1
$ echo $a
100.1
$ echo $((${a%.*} / 4))
25
$ for i in {1..4}; do echo -n '='; done; echo ''
====
$ for i in 1 2 3 4 5; do echo -n '='; done; echo ''
=====
$ for i in $(seq 1 $((${a%.*} / 4))); do echo -n '='; done; echo ''
=========================
Monitoring HTML
Cari informasi path dari web utama di server.
<VirtualHost *:443>
#ServerName example.com
<Directory "/var/www/html">
#... setting webutama
</Directory>
#...
</VirtualHost>
Buat folder monitoring dan file log. Ubah pemilik sesuai dengan user dan group dari sub-domain yang digunakan.
mkdir /var/www/html/monitoring
echo "" > /var/www/html/monitoring/log.html
chown <userweb>:<groupweb> -R /var/www/html/monitoring/
chmod 555 /var/www/html/monitoring/
chmod a+rx,u+w,og-w /var/www/html/monitoring/log.html
Buat sebuah file javascript (log.js) yang berada satu folder dengan /var/www/html/monitoring/log.html
//file: log.js
$(function() {
function levelof(element) {
var pct = data["l"+element] / data["n"+element]
if (pct >= thr[0]) {
$("#"+element).css("color", "red")
$("#"+element).css("font-weight", "bolder")
return 2;
}
else if (pct >= thr[1]) {
$("#"+element).css("color", "blue")
$("#"+element).css("font-weight", "bolder")
return 1;
}
else {
return 0;
}
}
function levelupdate() {
if (clvl > lvl) lvl = clvl
}
function beep() {
switch(lvl) {
case 2: document.getElementById("danger").play(); break;
case 1: document.getElementById("warning").play(); break;
default: document.getElementById("normal").play();
}
}
var thr = [.9, .7]; //thrhold: danger, warning
var lvl = 0; //0:normal, 1:warning, 2:danger
var clvl = lvl;
var php = $("#php").get(0).innerText
var apa = $("#apa").get(0).innerText
var mem = $("#mem").get(0).innerText
var cpu = $("#cpu").get(0).innerText
var data = {
nphp: php.length,
napa: apa.length,
nmem: mem.length,
ncpu: cpu.length,
lphp: (php.match(/=/igm)||[]).length,
lapa: (apa.match(/=/igm)||[]).length,
lmem: (mem.match(/=/igm)||[]).length,
lcpu: (cpu.match(/=/igm)||[]).length
}
clvl = levelof("php")
levelupdate()
clvl = levelof("apa")
levelupdate()
clvl = levelof("mem")
levelupdate()
clvl = levelof("cpu")
levelupdate()
beep()
var newDiv = document.createElement("small");
newDiv.innerHTML = "normal: 1 sonar beep | <span style='color: blue; font-weight: bolder'>warning (>="+(thr[1]*100)+"%): 3 car horn beep</span> | <span style='color: red; font-weight: bolder'>danger (>="+(thr[0]*100)+"%): 9 sos beep</span>";
document.body.appendChild(newDiv)
});
Buat berkas monitoring per 10 detik sebanyak 6 kali sebagai root, nano /root/monitoring.sh
#!/bin/bash
#file /root/monitoring.sh
for run in {1..6}; do
sh -c "echo '<meta http-equiv="refresh" content="20">'; echo '<pre>'; date; <command> echo '</pre>'; echo -n '<audio id="normal" src="https://bptsi.unisayogya.ac.id/wp-content/uploads/2024/12/beep.mp3" preload="auto"></audio><audio id="warning" src="https://bptsi.unisayogya.ac.id/wp-content/uploads/2024/12/beep-beep.mp3" preload="auto"></audio><audio id="danger" src="https://bptsi.unisayogya.ac.id/wp-content/uploads/2024/12/beep-beep-beep.mp3" preload="auto"></audio><script src="https://code.jquery.com/jquery-1.9.1.min.js"></script><script src="log.js"></script>';" > /root/tmplog.html && cat /root/tmplog.html > /var/webservice/service/monitoring/log.html;
#1 detik untuk bmon, 2 detik untuk top
sleep 6;
done
Buat cronjob setiap 1 menit
*/1 * * * * /bin/bash /root/monitoring.sh
Contoh hasil
Tune Up Performa
Move On MPM Prefork ke MPM Event, Sebuah Catatan
Demikian, semoga bermanfaat. [bst]