Sebagai seorang sysadmin, salah satu tugas rutin adalah mengirimkan laporan kepada end user. Selama periode waktu tertentu, klien saya hanya meminta laporan penggunaan disk server setiap bulannya. Cukup sederhana, saya langsung buat sebuah skrip Bash yang menjalankan perintah df -h
, lalu mengirimkannya lewat email. Berikut adalah contoh script existing yang saya gunakan:
#!/bin/bash dari="from:admin@excellent.co.id" tujuan="to:staff@excellent.co.id" salinan="cc:support@colamen.id,manager@excellent.co.id" subject="Subject: [REPORT BULANAN]: Penggunaan Disk Server Zimbra Excellent (mail.excellent.co.id.id)" file_disk="/tmp/disk.txt" file_status="/tmp/status.txt" body_email="/tmp/body.txt" file_report="/tmp/report.txt" df -h > $file_disk echo "Hi Team Excellent, Berikut adalah report penggunaan disk VPS mail.excellent.co.id: $(cat $file_disk) Terima Kasih" > $body_email echo "$dari" > $file_report echo "$tujuan" >> $file_report echo "$salinan" >> $file_report echo "$subject" >> $file_report echo "$(cat $body_email)" >> $file_report cat $file_report | /opt/zimbra/common/sbin/sendmail -f $dari -t
Saya define script ini di crontab sistem operasi Linux yang digunakan email server dan akan berjalan secara otomatis tanggal 1 setiap bulannya. Semuanya berjalan lancar, sampai akhirnya end user meminta agar laporan yang dikirimkan tidak hanya berupa teks biasa, melainkan berbentuk gambar atau screenshot dari terminal. Alasannya mungkin agar terlihat sebagai bukti yang valid.
Secara teknis, sebenarnya saya bisa saja SSH ke server setiap bulan lalu menjalankan perintah df -h
, lalu mengambil screenshot secara manual. Namun, hal ini akan memakan waktu dan mengganggu alur kerja saya, apalagi saya juga harus compose emailnya secara manual lalu upload screenshotnya, ditambah lagi jika ada beberapa end user dengan request yang sama. Akhirnya, saya mulai mencari cara untuk mengotomatisasi proses ini dan saya menemukan PhantomJS, sebuah headless browser yang bisa mengambil screenshot dari halaman web.
Ternyata prosesnya tidak semudah yang saya bayangkan. Ada beberapa kendala yang harus disesuaikan. Langkah pertama adalah melakukan instalasi PhantomJS.
# cd /srv # wget -c https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 # tar -xvjf phantomjs-2.1.1-linux-x86_64.tar.bz2 # mv phantomjs-2.1.1-linux-x86_64 /usr/local/share/ # ln -s /usr/local/share/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/sbin/ # phantomjs -v 2.1.1
Setelah melakukan instalasi PhantomJS saya membuat skrip JavaScript yang akan dijalankan oleh PhantomJS. Skrip PhantomJS akan file yang berisi output dari perintah df -h
dan mengubahnya menjadi gambar.
var diskFile = '/tmp/disk.txt'; var dfOutput = fs.read(diskFile); var page = require('webpage').create(); page.content = '<html><body><pre>' + dfOutput + '</pre></body></html>'; page.render(outputFile, {format: 'png', quality: '100'});
Hasilnya? Gambarnya ada tapi dengan latar belakangnya transparan, saya gamau, saya maunya backgroundnya putih saja supaya real seperti kita screenshot terminal. Solusinya, saya tambahkan sedikit CSS untuk memberikan warna latar belakang putih.
..... page.content = '<html><head><style>body { background-color: #ffffff; }</style></head><body><pre>' + dfOutput + '</pre></body></html>'; .....
Setelah gambar laporan disk berhasil, end user juga meminta gambar laporan untuk penggunaan CPU & RAM juga. Akhirnya saya menyesuaikan skrip PhantomJS untuk generate dua gambar sekaligus, gambar pertama merupakan penggunaan disk lalu gambar kedua merupakan penggunaan CPU & RAM. Tantangan berikutnya adalah mengirimkan dua attachment dalam satu email menggunakan tools di Linux.
Saya beralih dari sendmail
ke mutt
karena “katanya” lebih mudah untuk melampirkan file hehe. Namun, ada beberapa kendala lagi:
- Muncul pesan
No configuration file
: Ini sebenarnya hanya peringatan, cukup tambahkan2>/dev/null
di akhir perintahmutt
untuk ignore pesan ini. - Namun, email juga terkirim dari
root@hostname.domain.com
padahal saya maunya dariadmin@excellent.co.id
. Meskipun saya sudah mengatur alamat pengirim dimutt
, email tetap terkirim dariroot@hostname.domain.com
karena skrip dijalankan oleh userroot
di Linux.
Setelah saya explore lagi, sendmail sebenarnya bisa digunakan untuk mengirimkan email dengan multiple attachment, tapi kita harus decode dulu file gambarnya lalu masukan ke header email dalam format base64. Awalnya, saya mencoba tools uuencode
untuk mengubah gambar menjadi format base64
agar bisa dilampirkan. Sayangnya, perintah ini tidak terpasang secara default. Jadi, saya ganti dengan perintah bawaan Linux base64
dan hasilnya sesuai harapan.
Setelah melalui beberapa percobaan dan perbaikan, inilah skrip PhantomJS yang akhirnya bisa melakukan generate gambar sesuai dengan harapan saya.
var fs = require('fs'); var diskFile = '/tmp/disk.txt'; var outputFile = '/tmp/disk-usage-report.png'; var cpuramFile = '/tmp/cpu-ram.txt'; var outputCpuramFile = '/tmp/cpu-ram-usage-report.png'; var page = require('webpage').create(); var dfOutput = fs.read(diskFile); var cpuramOutput = fs.read(cpuramFile); // Isi konten halaman web dengan output dari df -h page.content = '<html><head><style>body { background-color: #ffffff; }</style></head><body><pre>' + dfOutput + '</pre></body></html>'; page.render(outputFile, {format: 'png', quality: '100'}); // Isi konten halaman web dengan output dari CPU RAM usage page.content = '<html><head><style>body { background-color: #ffffff; }</style></head><body><pre>' + cpuramOutput + '</pre></body></html>'; page.render(outputCpuramFile, {format: 'png', quality: '100'});
Setelah itu saya menyesuaikan script bash dengan proses kerja sebagai berikut:
- Mengambil output
df -h
danmpstat
/free -m
, lalu menyimpannya ke file teks - Menjalankan skrip PhantomJS untuk membuat gambar dari file-file teks tersebut
- Membuat email dengan header dengan isi pesan serta melampirkan gambar yang sudah di-encode dengan
base64
lalu memastikan email dikirim dari alamat yang benaradmin@excellent.co.id
#!/bin/bash dari="admin@excellent.co.id" tujuan="staff@excellent.co.id" salinan="support@colamen.id,manager@excellent.co.id" subject="[REPORT BULANAN]: Penggunaan Disk, CPU & RAM VPS PLN Icon Plus (mail.excellent.co.id)" file_disk="/tmp/disk.txt" file_cpuram="/tmp/cpu-ram.txt" body_email="/tmp/body.txt" file_report="/tmp/report.txt" file_disk_report="/tmp/disk-usage-report.png" file_cpu_ram_report="/tmp/cpu-ram-usage-report.png" df -h > $file_disk mpstat -P ALL > $file_cpuram free -m >> $file_cpuram phantomjs /opt/excellent/capture-disk-cpu-ram-usage.js echo "Hi Team Excellent, Berikut kami lampirkan capture penggunaan disk, RAM & CPU VPS mail.excellent.co.id. Apabila ada hal yang kurang jelas mohon informasikan kembali pada kami. Terima Kasih" > $body_email # --- Buat Email dengan Lampiran menggunakan uuencode --- ( # Header email echo "From: $dari" echo "To: $tujuan" echo "Cc: $salinan" echo "Subject: $subject" echo "Mime-Version: 1.0" echo "Content-Type: multipart/mixed; boundary=\"_BOUNDARY\"" echo "" echo "--_BOUNDARY" echo "Content-Type: text/plain; charset=\"us-ascii\"" echo "" # Isi teks email cat "$body_email" # Lampiran pertama (Disk Report) echo "--_BOUNDARY" echo "Content-Type: image/png" echo "Content-Transfer-Encoding: base64" echo "Content-Disposition: attachment; filename=\"$file_disk_report\"" echo "" base64 "$file_disk_report" echo "" # Lampiran kedua (CPU & RAM Report) echo "--_BOUNDARY" echo "Content-Type: image/png" echo "Content-Transfer-Encoding: base64" echo "Content-Disposition: attachment; filename=\"$file_cpu_ram_report\"" echo "" base64 "$file_cpu_ram_report" echo "" # Tutup email echo "--_BOUNDARY--" ) | /opt/zimbra/common/sbin/sendmail -t -i -f "$dari"
Saat ini script tersebut sudah saya aktifkan di crontab supaya bisa melakukan generate lalu mengirimkannya ke email secara otomatis setiap bulannya.