Saya memiliki aplikasi yang harus mencatat setiap transaksi. Setiap pesan log memerah karena kita harus memiliki catatan tentang apa yang terjadi sebelum terjadi kerusakan. Rekan-rekan saya dan saya ingin tahu tentang cara mencapai efek kinerja buffering sambil menjamin bahwa pesan log telah meninggalkan proses.
Yang kami temukan adalah:
- membuat FIFO yang dapat digunakan aplikasi untuk menulis, dan
- mengarahkan isi FIFO itu ke file biasa via
cat
.
Yaitu, apa yang biasanya:
app --logfile logfile.txt
sekarang:
mkfifo logfifo
cat logfifo &> logfile.txt &
app --logfile logfifo
Apakah ada gotcha untuk pendekatan ini? Ini berfungsi ketika kami mengujinya, tetapi kami ingin memastikan bahwa pesan akan menemukan jalannya ke file pengalihan bahkan jika aplikasi asli macet.
(Kami tidak memiliki kode sumber ke aplikasi, jadi solusi pemrograman tidak mungkin. Selain itu, aplikasi tidak akan menulis stdout
, jadi mengirim langsung ke perintah yang berbeda tidak mungkin. Jadi syslog
tidak mungkin .)
Pembaruan: Saya telah menambahkan hadiah. Jawaban yang diterima akan tidak melibatkan logger
untuk alasan sederhana bahwa logger
adalah tidak apa yang saya bertanya tentang. Seperti yang dinyatakan dalam pertanyaan awal, saya hanya mencari gotcha dalam menggunakan FIFO.
Jawaban:
Perhatikan bahwa fifo biasanya diperlukan dalam pemrograman di mana jumlah yang ditulis dapat melebihi jumlah yang dibacakan.
Dengan demikian fifo tidak akan berfungsi sepenuhnya lancar seperti yang Anda harapkan tetapi akan menyelesaikan masalah utama Anda saat memperkenalkan yang lain.
Ada tiga kemungkinan peringatan.
Ini berarti bahwa masalah Anda (meniru I / O buffer pada penulisan yang tidak buffer) akan diselesaikan. Itu karena 'batas' baru pada FIFO Anda akan berlaku menjadi kecepatan utilitas apa pun yang menulis apa yang ada di pipa ke disk (yang mungkin akan buffered I / O).
Namun demikian, penulis menjadi tergantung pada fungsi pembaca log Anda. Jika pembaca berhenti membaca dengan tiba-tiba, penulis akan memblokir. Jika pembaca tiba-tiba keluar (misalkan Anda kehabisan ruang disk pada target Anda) penulis akan SIGPIPE dan mungkin keluar.
Hal lain yang perlu disebutkan adalah jika server panik dan kernel berhenti merespons Anda mungkin kehilangan hingga 64 ribu data yang ada di buffer itu.
Cara lain untuk memperbaikinya adalah dengan menulis log ke tmpfs (/ dev / shm di linux) dan mengekor output ke lokasi disk tetap. Ada batasan yang kurang membatasi pada alokasi memori melakukan ini (bukan 64K, biasanya 2G!) Tetapi mungkin tidak bekerja untuk Anda jika penulis tidak memiliki cara dinamis untuk membuka kembali file log (Anda harus membersihkan log dari tmpfs secara berkala). Jika server panik dalam metode ini, Anda bisa kehilangan BANYAK lebih banyak data.
sumber
/dev/shm
. Kami telah mempertimbangkan itu juga, meskipun itu telah menyelinap untuk digunakantail -f
.Apa yang terjadi ketika
cat logfifo
proses Anda mati, seseorang membunuhnya secara tidak sengaja, atau seseorang secara tidak sengaja menunjuk ke lokasi yang salah?Pengalaman saya adalah bahwa
app
akan dengan cepat memblokir dan menggantung. Saya sudah mencoba ini dengan Tomcat, Apache dan beberapa aplikasi homebuilt kecil, dan mengalami masalah yang sama. Saya tidak pernah menyelidiki terlalu jauh, karenalogger
atau pengalihan I / O sederhana melakukan apa yang saya inginkan. Saya biasanya tidak membutuhkan kelengkapan pencatatan, yang ingin Anda kejar. Dan seperti yang Anda katakan, Anda tidak ingin logger.Ada beberapa diskusi tentang masalah ini di Linux non-blocking fifo (on demand logging) .
sumber
Pilihan Anda dibatasi oleh aplikasi, tetapi apa yang telah Anda uji akan berhasil.
Kami melakukan sesuatu yang mirip dengan pernis dan varnishncsa dengan get log di suatu tempat yang berguna bagi kami. Kami memiliki fifo dan hanya membacanya dengan syslog-ng dan mengirimkannya ke tempat yang kami butuhkan. Kami menangani sekitar 50GB dan belum menemukan masalah dengan pendekatan ini sejauh ini
sumber
Lingkungan adalah CentOS dan aplikasi menulis ke file ...
Alih-alih mengirim ke file biasa, saya akan mengirim output ke syslog dan memastikan bahwa pesan syslog sedang dikirim ke server pusat dan juga secara lokal.
Anda harus dapat menggunakan skrip shell seperti ini:
Anda juga dapat mengambil input (ke
logger
) daricat
atau daritail -f
ke dalam pipa:Satu-satunya masalah adalah bahwa ia tidak membedakan berdasarkan pentingnya pesan log (semuanya PEMBERITAHUAN ) tetapi setidaknya itu akan dicatat dan juga dikirim di-host ke server pusat.
Konfigurasi syslog tergantung pada server mana yang Anda gunakan. Ada
rsyslog
dansyslog-ng
(keduanya sangat mampu).EDIT : Direvisi setelah mendapatkan informasi lebih lanjut dari poster.
sumber
stdout
. OSnya adalah CentOS (saya telah menandai pertanyaan sebagai linux , tapi saya rasa itu mudah untuk dilewatkan). Semua pesan sama pentingnya, sehingga tidak ada perbedaan antara pemberitahuan dan kesalahan dalam aplikasi ini.Slow query detected
danDatabase halted
?Anda menulis:
Apakah Anda mencoba masuk ke "file"
/dev/stdout
? Itu mungkin memungkinkan Anda untuk melakukan sesuatu seperti:sumber
Tidak ada gunanya menulis ke fifo dan kemudian meminta proses lain menulisnya ke file. Cukup tulis langsung ke file secara normal dan begitu
write()
pengembaliannya, ada di tangan kernel; masih akan menulisnya ke disk jika aplikasi macet.sumber
fsync()
untuk menunggu setiap penulisan mencapai disk, dan Anda TIDAK ingin itu terjadi (mempertaruhkan kerugian jika terjadi crash sistem)?write()
kembali, aplikasi dapat crash semua suka - data akan sampai ke disk selama kernel tidak crash.