Memaksimalkan File Log PHP Anda: Panduan Praktis
Diterbitkan: 2022-03-11Dapat dikatakan bahwa log adalah salah satu alat yang paling diremehkan dan kurang dimanfaatkan oleh pengembang php lepas. Terlepas dari banyaknya informasi yang dapat mereka tawarkan, tidak jarang log menjadi tempat terakhir yang dilihat pengembang ketika mencoba menyelesaikan masalah.
Sebenarnya, file log PHP dalam banyak kasus harus menjadi tempat pertama untuk mencari petunjuk ketika masalah terjadi. Seringkali, informasi yang dikandungnya dapat secara signifikan mengurangi jumlah waktu yang dihabiskan untuk mencabuti rambut Anda untuk mencoba melacak kutu busuk.
Tetapi mungkin yang lebih penting, dengan sedikit kreativitas dan pemikiran ke depan, file log Anda dapat dimanfaatkan untuk dijadikan sebagai sumber informasi penggunaan dan analitik yang berharga. Penggunaan file log secara kreatif dapat membantu menjawab pertanyaan seperti: Browser apa yang paling sering digunakan untuk mengunjungi situs saya? Berapa waktu respons rata-rata dari server saya? Berapa persentase permintaan ke root situs? Bagaimana perubahan penggunaan sejak kami menerapkan pembaruan terbaru? Dan masih banyak lagi.
Artikel ini memberikan sejumlah tips tentang cara mengonfigurasi file log Anda, serta cara memproses informasi yang dikandungnya, untuk memaksimalkan manfaat yang mereka berikan.
Meskipun artikel ini secara teknis berfokus pada logging untuk pengembang PHP, banyak informasi yang disajikan di sini cukup agnostik teknologi dan relevan dengan bahasa lain dan tumpukan teknologi juga.
Catatan: Artikel ini mengasumsikan keakraban dasar dengan shell Unix. Bagi mereka yang tidak memiliki pengetahuan ini, sebuah Lampiran disediakan yang memperkenalkan beberapa perintah yang diperlukan untuk mengakses dan membaca file log pada sistem Unix.
Proyek Contoh File Log PHP kami
Sebagai contoh proyek untuk tujuan diskusi dalam artikel ini, kami akan mengambil Symfony Standard sebagai proyek kerja dan kami akan mengaturnya di Debian 7 Wheezy dengan rsyslogd
, nginx
, dan PHP-FPM
.
composer create-project symfony/framework-standard-edition my "2.6.*"
Ini dengan cepat memberi kami proyek pengujian yang berfungsi dengan UI yang bagus.
Kiat untuk Mengonfigurasi File Log Anda
Berikut adalah beberapa petunjuk tentang cara mengonfigurasi file log Anda untuk membantu memaksimalkan nilainya.
Konfigurasi Log Kesalahan
Log kesalahan mewakili bentuk paling dasar dari pencatatan; yaitu, menangkap informasi tambahan dan detail ketika masalah terjadi. Jadi, di dunia yang ideal, Anda ingin tidak ada kesalahan dan log kesalahan Anda kosong. Tetapi ketika masalah benar-benar terjadi (seperti yang selalu terjadi), log kesalahan Anda harus menjadi salah satu perhentian pertama yang Anda buat di jalur debug Anda.
Log kesalahan biasanya cukup mudah dikonfigurasi.
Untuk satu hal, semua pesan kesalahan dan kerusakan dapat dicatat dalam log kesalahan dalam format yang sama persis di mana mereka akan disajikan kepada pengguna. Dengan beberapa konfigurasi sederhana, pengguna akhir tidak perlu melihat jejak kesalahan jelek itu di situs Anda, sementara devops akan tetap dapat memantau sistem dan meninjau pesan kesalahan ini dalam semua detail mengerikan mereka. Berikut cara mengatur logging semacam ini di PHP:
log_errors = On error_reporting = E_ALL error_log = /path/to/my/error/log
Dua baris lain yang penting untuk disertakan dalam file log untuk situs langsung, untuk mencegah tingkat detail kesalahan yang mengerikan agar tidak disajikan kepada pengguna, adalah:
display_errors = Off display_startup_errors = Off
Konfigurasi Sistem Log ( syslog
)
Ada banyak implementasi daemon syslog
yang umumnya kompatibel di dunia open source termasuk:
-
syslogd
dansysklogd
– paling sering terlihat pada sistem keluarga BSD, CentOS, Mac OS X, dan lainnya -
syslog-ng
– default untuk build Gentoo dan SuSE modern -
rsyslogd
– banyak digunakan pada keluarga sistem operasi Debian dan Fedora
(Catatan: Dalam artikel ini, kami akan menggunakan rsyslogd
untuk contoh kami.)
Konfigurasi syslog dasar umumnya cukup untuk menangkap pesan log Anda dalam file log seluruh sistem (biasanya /var/log/syslog
; mungkin juga /var/log/messages
atau /var/log/system.log
tergantung pada distro Anda gunakan).
Log sistem menyediakan beberapa fasilitas log, delapan di antaranya ( LOG_LOCAL0
hingga LOG_LOCAL7
) dicadangkan untuk proyek yang digunakan pengguna. Di sini, misalnya, adalah bagaimana Anda dapat mengatur LOG_LOCAL0
untuk menulis ke 4 file log terpisah, berdasarkan tingkat logging (yaitu, kesalahan, peringatan, info, debug):
# /etc/rsyslog.d/my.conf local0.err /var/log/my/err.log local0.warning /var/log/my/warning.log local0.info -/var/log/my/info.log local0.debug -/var/log/my/debug.log
Sekarang, setiap kali Anda menulis pesan log ke fasilitas LOG_LOCAL0
, pesan kesalahan akan masuk ke /var/log/my/err.log
, pesan peringatan akan masuk ke /var/log/my/warning.log
, dan seterusnya. Namun, perhatikan bahwa daemon syslog memfilter pesan untuk setiap file berdasarkan aturan "level ini dan yang lebih tinggi". Jadi, dalam contoh di atas, semua pesan kesalahan akan muncul di keempat file yang dikonfigurasi, pesan peringatan akan muncul di semua kecuali log kesalahan, pesan info akan muncul di log info dan debug, dan pesan debug hanya akan masuk ke debug.log
.
Satu catatan penting tambahan; Tanda -
sebelum file tingkat info dan debug dalam contoh file konfigurasi di atas menunjukkan bahwa penulisan ke file tersebut harus dilakukan secara asinkron (karena operasi ini tidak memblokir). Ini biasanya baik-baik saja (dan bahkan disarankan di sebagian besar situasi) untuk info dan log debug, tetapi yang terbaik adalah menulis ke log kesalahan (dan kemungkinan besar log peringatan juga) menjadi sinkron.
Untuk mematikan tingkat logging yang kurang penting (misalnya, pada server produksi), Anda cukup mengalihkan pesan terkait ke /dev/null
(yaitu, ke mana-mana):
local0.debug /dev/null # -/var/log/my/debug.log
Salah satu kustomisasi khusus yang berguna, terutama untuk mendukung beberapa parsing file log PHP yang akan kita bahas nanti di artikel ini, adalah dengan menggunakan tab sebagai karakter pembatas dalam pesan log. Ini dapat dengan mudah dilakukan dengan menambahkan file berikut di /etc/rsyslog.d
:
# /etc/rsyslog.d/fixtab.conf $EscapeControlCharactersOnReceive off
Dan terakhir, jangan lupa untuk me-restart daemon syslog setelah Anda membuat perubahan konfigurasi agar dapat diterapkan:
service rsyslog restart
Konfigurasi Log Server
Tidak seperti log aplikasi dan log kesalahan yang dapat Anda gunakan untuk menulis, log server secara eksklusif ditulis oleh daemon server yang sesuai (misalnya, server web, server database, dll.) pada setiap permintaan. Satu-satunya "kontrol" yang Anda miliki atas log ini adalah sejauh server mengizinkan Anda untuk mengonfigurasi fungsionalitas logging-nya. Meskipun ada banyak hal yang harus disaring dalam file-file ini, mereka sering kali merupakan satu-satunya cara untuk mendapatkan pemahaman yang jelas tentang apa yang terjadi "di balik tenda" dengan server Anda.
Mari kita gunakan contoh aplikasi Symfony Standard kita di lingkungan nginx dengan backend penyimpanan MySQL. Berikut konfigurasi host nginx yang akan kita gunakan:
server { server_name my.log-sandbox; root /var/www/my/web; location / { # try to serve file directly, fallback to app.php try_files $uri /app.php$is_args$args; } # DEV # This rule should only be placed on your development environment # In production, don't include this and don't deploy app_dev.php or config.php location ~ ^/(app_dev|config)\.php(/|$) { fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param HTTPS off; } # PROD location ~ ^/app\.php(/|$) { fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param HTTPS off; # Prevents URIs that include the front controller. This will 404: # http://domain.tld/app.php/some-path # Remove the internal directive to allow URIs like this internal; } error_log /var/log/nginx/my_error.log; access_log /var/log/nginx/my_access.log; }
Berkenaan dengan dua direktif terakhir di atas: access_log
mewakili log permintaan umum, sementara error_log
adalah untuk kesalahan, dan, seperti halnya log kesalahan aplikasi, ada baiknya menyiapkan pemantauan ekstra untuk waspada terhadap masalah sehingga Anda dapat bereaksi dengan cepat.
Catatan: Ini adalah file konfigurasi nginx yang sengaja disederhanakan yang disediakan hanya untuk tujuan contoh. Itu hampir tidak memperhatikan keamanan dan kinerja dan tidak boleh digunakan apa adanya di lingkungan "nyata" apa pun.
Inilah yang kita dapatkan di /var/log/nginx/my_access.log
setelah mengetik http://my.log-sandbox/app_dev.php/
di browser dan menekan Enter
.
192.168.56.1 - - [26/Apr/2015:16:13:28 +0300] "GET /app_dev.php/ HTTP/1.1" 200 6715 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" 192.168.56.1 - - [26/Apr/2015:16:13:28 +0300] "GET /bundles/framework/css/body.css HTTP/1.1" 200 6657 "http://my.log-sandbox/app_dev.php/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" 192.168.56.1 - - [26/Apr/2015:16:13:28 +0300] "GET /bundles/framework/css/structure.css HTTP/1.1" 200 1191 "http://my.log-sandbox/app_dev.php/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" 192.168.56.1 - - [26/Apr/2015:16:13:28 +0300] "GET /bundles/acmedemo/css/demo.css HTTP/1.1" 200 2204 "http://my.log-sandbox/app_dev.php/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" 192.168.56.1 - - [26/Apr/2015:16:13:28 +0300] "GET /bundles/acmedemo/images/welcome-quick-tour.gif HTTP/1.1" 200 4770 "http://my.log-sandbox/app_dev.php/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" 192.168.56.1 - - [26/Apr/2015:16:13:28 +0300] "GET /bundles/acmedemo/images/welcome-demo.gif HTTP/1.1" 200 4053 "http://my.log-sandbox/app_dev.php/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" 192.168.56.1 - - [26/Apr/2015:16:13:28 +0300] "GET /bundles/acmedemo/images/welcome-configure.gif HTTP/1.1" 200 3530 "http://my.log-sandbox/app_dev.php/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" 192.168.56.1 - - [26/Apr/2015:16:13:28 +0300] "GET /favicon.ico HTTP/1.1" 200 6518 "http://my.log-sandbox/app_dev.php/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" 192.168.56.1 - - [26/Apr/2015:16:13:30 +0300] "GET /app_dev.php/_wdt/e50d73 HTTP/1.1" 200 13265 "http://my.log-sandbox/app_dev.php/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36"
Ini menunjukkan bahwa, untuk melayani satu halaman, browser benar-benar melakukan 9 panggilan HTTP. 7 di antaranya, bagaimanapun, adalah permintaan untuk konten statis, yang polos dan ringan. Namun, mereka masih mengambil sumber daya jaringan dan inilah yang dapat dioptimalkan dengan menggunakan berbagai sprite dan teknik minifikasi.
Sementara pengoptimalan tersebut akan dibahas di artikel lain, yang relevan di sini adalah kita dapat mencatat permintaan ke konten statis secara terpisah dengan menggunakan arahan location
lain untuk mereka:
location ~ \.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js)$ { access_log /var/log/nginx/my_access-static.log; }
Ingat bahwa location
nginx melakukan pencocokan ekspresi reguler sederhana, sehingga Anda dapat menyertakan ekstensi konten statis sebanyak yang Anda harapkan untuk dikirim ke situs Anda.
Mengurai log seperti itu tidak berbeda dengan mem-parsing log aplikasi.
Log Lain yang Layak Disebut
Dua log PHP lainnya yang layak disebut adalah log debug dan log penyimpanan data.
Log Debug
Hal lain yang nyaman tentang log nginx adalah log debug. Kita dapat mengaktifkannya dengan mengganti baris error_log
dari konfigurasi dengan yang berikut (mengharuskan modul debug nginx diinstal):
error_log /var/log/nginx/my_error.log debug;
Pengaturan yang sama berlaku untuk Apache atau server web lain apa pun yang Anda gunakan.
Dan kebetulan, log debug tidak terkait dengan log kesalahan, meskipun dikonfigurasi dalam direktif error_log
.
Meskipun log debug memang bisa bertele-tele (satu permintaan nginx, misalnya, menghasilkan 127KB data log!), itu masih bisa sangat berguna. Mengarungi file log mungkin rumit dan membosankan, tetapi seringkali dapat dengan cepat memberikan petunjuk dan informasi yang sangat membantu mempercepat proses debugging.
Secara khusus, log debug benar-benar dapat membantu dengan men-debug konfigurasi nginx, terutama bagian yang paling rumit, seperti pencocokan location
dan rantai rewrite
.
Tentu saja, log debug tidak boleh diaktifkan di lingkungan produksi. Jumlah ruang yang mereka gunakan juga dan jumlah informasi yang mereka simpan berarti banyak beban I/O di server Anda, yang dapat menurunkan kinerja keseluruhan sistem secara signifikan.
Log Penyimpanan Data
Jenis lain dari log server (berguna untuk debugging) adalah log penyimpanan data. Di MySQL, Anda dapat mengaktifkannya dengan menambahkan baris berikut:
[mysqld] general_log = 1 general_log_file = /var/log/mysql/query.log
Log ini hanya berisi daftar kueri yang dijalankan oleh sistem saat melayani permintaan basis data dalam urutan kronologis, yang dapat membantu untuk berbagai kebutuhan debugging dan penelusuran. Namun, mereka tidak boleh tetap diaktifkan pada sistem produksi, karena mereka akan menghasilkan beban I/O tambahan yang tidak perlu, yang memengaruhi kinerja.
Menulis ke File Log Anda
PHP sendiri menyediakan fungsi untuk membuka, menulis, dan menutup file log ( masing-masing openlog()
, syslog()
, dan closelog()
).
Ada juga banyak perpustakaan logging untuk pengembang PHP, seperti Monolog (populer di kalangan pengguna Symfony dan Laravel), serta berbagai implementasi kerangka kerja tertentu, seperti kemampuan logging yang dimasukkan ke dalam CakePHP. Umumnya, perpustakaan seperti Monolog tidak hanya membungkus panggilan syslog()
, tetapi juga memungkinkan penggunaan fungsi dan alat backend lainnya.

Berikut adalah contoh sederhana tentang cara menulis ke log:
<?php openlog(uniqid(), LOG_ODELAY, LOG_LOCAL0); syslog(LOG_INFO, 'It works!');
Panggilan kami di sini untuk openlog
:
- mengonfigurasi PHP untuk menambahkan pengidentifikasi unik ke setiap pesan log sistem dalam masa pakai skrip
- menyetelnya untuk menunda pembukaan koneksi syslog hingga panggilan
syslog()
pertama terjadi - menetapkan
LOG_LOCAL0
sebagai fasilitas logging default
Berikut tampilan isi file log setelah menjalankan kode di atas:
# cat /var/log/my/info.log Mar 2 00:23:29 log-sandbox 54f39161a2e55: It works!
Memaksimalkan Nilai File Log PHP Anda
Sekarang setelah kita semua menguasai teori dan dasar-dasarnya, mari kita lihat seberapa banyak yang bisa kita dapatkan dari log yang membuat perubahan sesedikit mungkin pada contoh proyek Symfony Standard kita.
Pertama, mari buat skrip src/log-begin.php
(untuk membuka dan mengkonfigurasi log kita dengan benar) dan src/log-end.php
(untuk mencatat informasi tentang penyelesaian yang berhasil). Perhatikan bahwa, untuk kesederhanaan, kami hanya akan menulis semua pesan ke info log.
# src/log-begin.php <?php define('START_TIME', microtime(true)); openlog(uniqid(), LOG_ODELAY, LOG_LOCAL0); syslog(LOG_INFO, 'BEGIN'); syslog(LOG_INFO, "URI\t{$_SERVER['REQUEST_URI']}"); $browserHash = substr(md5($_SERVER['HTTP_USER_AGENT']), 0, 7); syslog(LOG_INFO, "CLIENT\t{$_SERVER['REMOTE_ADDR']}\t{$browserHash}"); <br /> # src/log-end.php <?php syslog(LOG_INFO, "DISPATCH TIME\t" . round(microtime(true) - START_TIME, 2)); syslog(LOG_INFO, 'END');
Dan mari kita memerlukan skrip ini di app.php
:
<?php require_once(dirname(__DIR__) . '/src/log-begin.php'); syslog(LOG_INFO, "MODE\tPROD"); # original app.php contents require_once(dirname(__DIR__) . '/src/log-end.php');
Untuk lingkungan pengembangan, kami juga ingin meminta skrip ini di app_dev.php
. Kode untuk melakukannya akan sama seperti di atas, kecuali kita akan mengatur MODE
ke DEV
daripada PROD
.
Kami juga ingin melacak pengontrol apa yang dipanggil, jadi mari tambahkan satu baris lagi di Acme\DemoBundle\EventListener\ControllerListener
, tepat di awal metode ControllerListener::onKernelController()
:
syslog(LOG_INFO, "CONTROLLER\t" . get_class($event->getController()[0]));
Perhatikan bahwa total perubahan ini hanya 15 baris kode tambahan, tetapi secara kolektif dapat menghasilkan banyak informasi.
Menganalisis Data di File Log Anda
Sebagai permulaan, mari kita lihat berapa banyak permintaan HTTP yang diperlukan untuk melayani setiap pemuatan halaman.
Berikut info di log untuk satu permintaan, berdasarkan cara kami mengonfigurasi logging kami:
Mar 3 12:04:20 log-sandbox 54f58724b1ccc: BEGIN Mar 3 12:04:20 log-sandbox 54f58724b1ccc: URI /app_dev.php/ Mar 3 12:04:20 log-sandbox 54f58724b1ccc: CLIENT 192.168.56.1 1b101cd Mar 3 12:04:20 log-sandbox 54f58724b1ccc: MODE DEV Mar 3 12:04:23 log-sandbox 54f58724b1ccc: CONTROLLER Acme\DemoBundle\Controller\WelcomeController Mar 3 12:04:25 log-sandbox 54f58724b1ccc: DISPATCH TIME 4.51 Mar 3 12:04:25 log-sandbox 54f58724b1ccc: END Mar 3 12:04:25 log-sandbox 54f5872967dea: BEGIN Mar 3 12:04:25 log-sandbox 54f5872967dea: URI /app_dev.php/_wdt/59b8b6 Mar 3 12:04:25 log-sandbox 54f5872967dea: CLIENT 192.168.56.1 1b101cd Mar 3 12:04:25 log-sandbox 54f5872967dea: MODE DEV Mar 3 12:04:28 log-sandbox 54f5872967dea: CONTROLLER Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController Mar 3 12:04:29 log-sandbox 54f5872967dea: DISPATCH TIME 4.17 Mar 3 12:04:29 log-sandbox 54f5872967dea: END
Jadi sekarang kita tahu bahwa setiap pemuatan halaman sebenarnya dilayani dengan dua permintaan HTTP.
Sebenarnya ada dua poin yang layak disebutkan di sini. Pertama, dua permintaan per pemuatan halaman adalah untuk menggunakan Symfony dalam mode dev (yang telah saya lakukan di seluruh artikel ini). Anda dapat mengidentifikasi panggilan mode dev dengan mencari /app-dev.php/
potongan URL. Kedua, katakanlah setiap pemuatan halaman dilayani dengan dua permintaan berikutnya ke aplikasi Symfony. Seperti yang kita lihat sebelumnya di log akses nginx, sebenarnya ada lebih banyak panggilan HTTP, beberapa di antaranya untuk konten statis.
Oke, sekarang mari menjelajah sedikit di situs demo (untuk membangun data dalam file log) dan mari kita lihat apa lagi yang bisa kita pelajari dari log ini.
Berapa banyak permintaan yang dilayani secara total sejak awal logfile?
# grep -c BEGIN info.log 10
Apakah ada di antara mereka yang gagal (apakah skrip dimatikan tanpa mencapai akhir)?
# grep -c END info.log 10
Kami melihat bahwa jumlah catatan BEGIN
dan END
cocok, jadi ini memberi tahu kami bahwa semua panggilan berhasil. (Jika skrip PHP tidak berhasil diselesaikan, skrip tersebut tidak akan mencapai eksekusi skrip src/log-end.php
.)
Berapa persentase permintaan ke root situs?
# `grep -cE "\s/app_dev.php/$" info.log` 2
Ini memberi tahu kita bahwa ada 2 pemuatan halaman dari root situs. Karena kita sebelumnya mengetahui bahwa (a) ada 2 permintaan ke aplikasi per pemuatan halaman dan (b) ada total 10 permintaan HTTP, persentase permintaan ke root situs adalah 40% (yaitu, 2x2/10).
Kelas pengontrol mana yang bertanggung jawab untuk melayani permintaan ke root situs?
# grep -E "\s/$|\s/app_dev.php/$" info.log | head -n1 Mar 3 12:04:20 log-sandbox 54f58724b1ccc: URI /app_dev.php/ # grep 54f58724b1ccc info.log | grep CONTROLLER Mar 3 12:04:23 log-sandbox 54f58724b1ccc: CONTROLLER Acme\DemoBundle\Controller\WelcomeController
Di sini kami menggunakan ID unik permintaan untuk memeriksa semua pesan log yang terkait dengan permintaan tunggal itu. Dengan demikian kami dapat menentukan bahwa kelas pengontrol yang bertanggung jawab untuk melayani permintaan ke root situs adalah Acme\DemoBundle\Controller\WelcomeController
.
Klien mana dengan IP subnet
192.168.0.0/16
yang telah mengakses situs?
# grep CLIENT info.log | cut -d":" -f4 | cut -f2 | sort | uniq 192.168.56.1
Seperti yang diharapkan dalam kasus uji sederhana ini, hanya komputer host saya yang mengakses situs. Ini tentu saja contoh yang sangat sederhana, tetapi kemampuan yang ditunjukkannya (mampu menganalisis sumber lalu lintas ke situs Anda) jelas cukup kuat dan penting.
Berapa banyak lalu lintas ke situs saya yang berasal dari FireFox?
Memiliki 1b101cd
sebagai hash dari Agen Pengguna Firefox saya, saya dapat menjawab pertanyaan ini sebagai berikut:
# grep -c 1b101cd info.log 8 # grep -c CLIENT info.log 10
Jawaban: 80% (yaitu, 8/10)
Berapa persentase permintaan yang menghasilkan respons lambat?
Untuk tujuan contoh ini, kami akan mendefinisikan "lambat" sebagai membutuhkan lebih dari 5 detik untuk memberikan respons. Demikian:
# grep "DISPATCH TIME" info.log | grep -cE "\s[0-9]{2,}\.|\s[5-9]\." 2
Jawaban: 20% (yaitu, 2/10)
Apakah ada yang pernah memberikan parameter GET?
# grep URI info.log | grep \?
Tidak, standar Symfony hanya menggunakan siput URL, jadi ini juga memberi tahu kita di sini bahwa tidak ada yang mencoba meretas situs.
Ini hanyalah beberapa contoh yang relatif belum sempurna tentang cara file log dapat dimanfaatkan secara kreatif untuk menghasilkan informasi penggunaan yang berharga dan bahkan analitik dasar.
Hal lain yang perlu diingat
Menjaga Hal-Hal Aman
Perhatian lainnya adalah untuk keamanan. Anda mungkin berpikir bahwa permintaan logging adalah ide yang bagus, dalam banyak kasus memang demikian. Namun, penting untuk sangat berhati-hati dalam menghapus informasi pengguna yang berpotensi sensitif sebelum menyimpannya di log.
Memerangi File Log Kembung
Karena file log adalah file teks yang selalu Anda tambahkan informasinya, file tersebut terus bertambah. Karena ini adalah masalah yang terkenal, ada beberapa pendekatan yang cukup standar untuk mengendalikan pertumbuhan file log.
Cara termudah adalah dengan memutar log . Rotasi log berarti:
- Mengganti log secara berkala dengan file kosong baru untuk penulisan lebih lanjut
- Menyimpan file lama untuk sejarah
- Menghapus file yang cukup "berusia" untuk mengosongkan ruang disk
- Memastikan aplikasi dapat menulis ke log tanpa gangguan saat perubahan file ini terjadi
Solusi paling umum untuk ini adalah logrotate
, yang dikirimkan secara pra-instal dengan sebagian besar distribusi *nix. Mari kita lihat file konfigurasi sederhana untuk memutar log kita:
/var/log/my/debug.log /var/log/my/info.log /var/log/my/warning.log /var/log/my/error.log { rotate 7 daily missingok notifempty delaycompress compress sharedscripts postrotate invoke-rc.d rsyslog rotate > /dev/null endscript }
Pendekatan lain yang lebih maju adalah membuat rsyslogd
sendiri menulis pesan ke dalam file, dibuat secara dinamis berdasarkan tanggal dan waktu saat ini. Ini masih memerlukan solusi khusus untuk menghapus file lama, tetapi memungkinkan devops mengelola kerangka waktu untuk setiap file log dengan tepat. Untuk contoh kita:
$template DynaLocal0Err, "/var/log/my/error-%$NOW%-%$HOUR%.log" $template DynaLocal0Info, "/var/log/my/info-%$NOW%-%$HOUR%.log" $template DynaLocal0Warning, "/var/log/my/warning-%$NOW%-%$HOUR%.log" $template DynaLocal0Debug, "/var/log/my/debug-%$NOW%-%$HOUR%.log" local1.err -?DynaLocal0Err local1.info -?DynaLocal0Info local1.warning -?DynaLocal0Warning local1.debug -?DynaLocal0Debug
Dengan cara ini, rsyslog
akan membuat file log individual setiap jam, dan tidak perlu memutarnya dan memulai ulang daemon. Berikut cara file log yang lebih lama dari 5 hari dapat dihapus untuk menyelesaikan solusi ini:
find /var/log/my/ -mtime +5 -print0 | xargs -0 rm
Log Jarak Jauh
Seiring pertumbuhan proyek, penguraian informasi dari log menjadi semakin membutuhkan sumber daya. Ini tidak hanya berarti membuat beban server ekstra; itu juga berarti membuat beban puncak pada CPU dan drive disk pada saat Anda mengurai log, yang dapat menurunkan waktu respons server untuk pengguna (atau dalam kasus terburuk bahkan dapat menurunkan situs).
Untuk mengatasi ini, pertimbangkan untuk menyiapkan server logging terpusat . Yang Anda butuhkan untuk ini adalah kotak lain dengan port UDP 514 (default) terbuka. Untuk membuat rsyslogd
mendengarkan koneksi, tambahkan baris berikut ke file konfigurasinya:
$UDPServerRun 514
Setelah ini, menyiapkan klien semudah:
*.* @HOSTNAME:514
(di mana HOSTNAME
adalah nama host dari server pencatatan jarak jauh Anda).
Kesimpulan
Meskipun artikel ini telah menunjukkan beberapa cara kreatif di mana file log dapat menawarkan informasi yang jauh lebih berharga daripada yang mungkin Anda bayangkan sebelumnya, penting untuk menekankan bahwa kami hanya menggores permukaan dari apa yang mungkin. Luas, cakupan, dan format apa yang dapat Anda catat hampir tidak terbatas. Artinya – jika ada data penggunaan atau analitik yang ingin Anda ekstrak dari log Anda – Anda hanya perlu mencatatnya dengan cara yang akan memudahkan penguraian dan analisis selanjutnya. Selain itu, analisis itu sering dapat dilakukan dengan alat baris perintah Linux standar seperti grep
, sed
, atau awk
.
Memang, file log PHP adalah alat yang paling kuat yang dapat memberikan manfaat yang luar biasa.
Sumber daya
Kode di GitHub: https://github.com/isanosyan/toptal-blog-logs-post-example
Lampiran: Membaca dan Memanipulasi File Log di Unix Shell
Berikut adalah pengantar singkat untuk beberapa alat baris perintah *nix yang lebih umum yang ingin Anda ketahui untuk membaca dan memanipulasi file log Anda.
cat
mungkin yang paling sederhana. Ini mencetak seluruh file ke aliran output. Misalnya, perintah berikut akan mencetaklogfile1
ke konsol:cat logfile1
>
karakter memungkinkan pengguna untuk mengarahkan output, misalnya ke file lain. Membuka aliran target dalam mode tulis (yang berarti menghapus konten target). Berikut cara mengganti isitmpfile
dengan isilogfile1
:cat logfile1 > tmpfile
>>
mengalihkan output dan membuka aliran target dalam mode penambahan. Isi file target saat ini akan dipertahankan, baris baru akan ditambahkan ke bawah. Ini akan menambahkan kontenlogfile1
ketmpfile
:cat logfile1 >> tmpfile
grep
memfilter file dengan beberapa pola dan hanya mencetak baris yang cocok. Perintah di bawah ini hanya akan mencetak barislogfile1
yang berisi pesanBingo
:grep Bingo logfile1
cut
mencetak isi satu kolom (dengan nomor mulai dari 1). Secara default mencari karakter tab sebagai pembatas antar kolom. Misalnya, jika Anda memiliki file yang penuh dengan cap waktu dalam formatYYYY-MM-DD HH:MM:SS
, ini akan memungkinkan Anda untuk mencetak hanya tahun:cut -d"-" -f1 logfile1
head
hanya menampilkan baris pertama filetail
hanya menampilkan baris terakhir dari filesort
mengurutkan baris dalam outputuniq
menyaring garis duplikatwc
menghitung kata (atau baris saat digunakan dengan flag-l
)|
(yaitu, simbol "pipa") memasok output dari satu perintah sebagai input ke perintah berikutnya. Pipa sangat nyaman untuk menggabungkan perintah. Misalnya, inilah cara kami menemukan bulan di tahun 2014 yang terjadi dalam satu set stempel waktu:grep -E "^2014" logfile1 | cut -d"-" -f2 | sort | uniq
Di sini pertama-tama kita mencocokkan baris dengan ekspresi reguler "dimulai dengan 2014", lalu memotong bulan. Terakhir, kami menggunakan kombinasi sort
dan uniq
untuk mencetak kemunculan hanya sekali.