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
3cat 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 2Bagaimana 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
470Mbmon 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 ^ ppstop -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.htmlBuat 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;
doneBuat cronjob setiap 1 menit
*/1 * * * * /bin/bash /root/monitoring.shContoh hasil
Tune Up Performa
Move On MPM Prefork ke MPM Event, Sebuah Catatan
Demikian, semoga bermanfaat. [bst]
