Artikel ini terutama memperdalam pengenalan python logging. Lebih penting untuk membahas cara menggunakan logging untuk mengeluarkan log di lingkungan multi -proses, cara memotong file log dengan aman. 1.logging PENDAHULUAN MODUL LOG Modul logging dari python menyediakan modul standar yang fleksibel, sehingga program Python apa pun dapat menggunakan modul bagian ketiga ini untuk mengimplementasikan catatan log ini.python logging dokumen resmi logging Kerangka kerja ini terutama terdiri dari empat bagian: Loggers: antarmuka yang dapat dipanggil secara langsung Handlers: memutuskan untuk mendistribusikan catatan log ke tujuan yang tepat Filters: memberikan penilaian log yang lebih baik Formatters: merumuskan tata letak format dari pencetakan rekaman akhir 2.logging Komposisi loggers loggers adalah antarmuka log yang dapat dihubungi oleh program secara langsung, dan dapat menulis informasi log secara langsung ke logger. logger tidak secara langsung digunakan untuk digunakan, tetapi untuk mendapatkan objek melalui logging.getLogger(name). Faktanya, objek logger adalah satu contoh. sama. Namun sayangnya, logger tidak mendukung multi. <Catatan> loggers objek memiliki hubungan ayah -son. Ketika tidak ada orang tua logger objek, objek ayahnya adalah root.. Misalnya, logging.getLogger("abc.xyz") akan membuat dua objek logger, satu adalah objek ayah abc, yang lainnya adalah xyz sub -object, dan abc tidak memiliki objek indukroot dan abc tidak memiliki objek indukroot dan abc memiliki orangtuaroot6abc memiliki orangtuarootIVJ6. >. Tetapi pada kenyataannya, abc adalah objek yang menahan objek (objek log virtual). Anda tidak dapat handler untuk menangani log. Namun, root bukan target suatu tempat. Jika objek log memutar log, objek induknya akan menerima log pada saat yang sama, sehingga beberapa pengguna akan menemukan objek logger dua kali. Karena ia membuat log logger, dan pada saat yang sama, objek root juga tekan log. Masing -masing logger memiliki tingkat log. logging mendefinisikan level berikut
Ketika a logger menerima informasi log, pertama -tama tentukan apakah memenuhi level, jika diputuskan untuk menangani informasi, informasi tersebut diteruskan ke Handlers untuk diproses. Handlers Handlers Informasi yang dikirim oleh logger dialokasikan secara akurat ke tempat yang tepat. Ambil chestnut dan kirimkan ke konsol atau file atau both atau tempat lain (saluran proses dan sejenisnya). Ini menentukan perilaku masing -masing log. Ini adalah area utama yang perlu dikonfigurasi nanti. Masing -masing Handler juga memiliki level log. Satu logger dapat memiliki beberapa handler artinya logger dapat meneruskan log ke berbagai handler> sesuai dengan tingkat log yang berbeda.. Tentu saja, dapat diteruskan ke beberapa handlers pada tingkat yang sama. Ini secara fleksibel diatur sesuai dengan kebutuhan. Filters Filters memberikan penilaian granular yang lebih baik untuk menentukan apakah log perlu dicetak. Pada prinsipnya, handler mendapat log akan diproses secara seragam sesuai dengan level, tetapi jika handler memiliki Filter. Misalnya, Filter dapat mencegat or untuk memodifikasi atau bahkan memodifikasi level lognya (setelah modifikasi). logger dan handler dapat diinstal filter atau bahkan beberapa filter seri yang menghubungkannya.. Formatters Formatters Menentukan tata letak format dari pencetakan rekaman akhir. Formatter akan menjahit informasi yang dikirimkan ke string tertentu. Secara default. Format Ada beberapa atribut LogRecord yang dapat digunakan, seperti yang ditunjukkan dalam bentuk berikut:
A Handler hanya dapat memiliki satu Formatter Oleh karena itu untuk mencapai beberapa format untuk mencapai beberapa Handler. < 3.logging konfigurasi Konfigurasi sederhana Pertama -tama, ini dijelaskan dalam bab loggers. Kami memiliki objek log default root. Keuntungan dari root log ini adalah bahwa kita dapat secara langsung menggunakan <logging untuk mengkonfigurasi dan memainkan log logs .. Misalnya: logging.basicConfig(level=logging.INFO,filename='logger.log') Jadi konfigurasi sederhana di sini mengacu pada objek log root, kasual. Masing -masing logger adalah contoh tunggal, sehingga dapat dipanggil di mana saja dalam program setelah konfigurasi. Kita hanya perlu memanggil basicConfig untuk membuat konfigurasi sederhana dari objek log root. Sebenarnya, metode ini cukup efektif dan mudah digunakan. Itu membuatnya menjamin bahwa setidaknya satu Handler dapat diproses saat memanggil logger. Konfigurasi sederhana dapat diatur seperti ini: logging.basicConfig(level=logging.INFO, Konfigurasi Kode Metode pengaturan lain yang lebih rinci adalah mengonfigurasi dalam kode, tetapi metode pengaturan ini adalah cara yang paling sedikit untuk digunakan. Bagaimanapun, tidak ada yang mau menulis pengaturan ke kode. Tapi di sini sedikit diperkenalkan, meskipun tidak banyak, Anda dapat menggunakannya bila perlu. (Make up nanti) Konfigurasi File Konfigurasi File konfigurasi logging di python adalah fungsi berdasarkan ConfigParser. Dengan kata lain, format file konfigurasi juga ditulis dengan cara ini. Mari kita taruh file konfigurasi yang lebih umum dan kemudian bicarakan ############################################## Saya percaya bahwa setelah menontonnya sekali, saya juga menemukan aturannya. Saya membagi potongan -potongan besar dengan#. Masing -masing logger atau handler atau formatter memiliki nama key. Ambil logger sebagai contoh, pertama -tama, Anda perlu menambahkan key ke konfigurasi <loggers> untuk mewakili logger ini. Kemudian gunakan <loggers_xxxx> di antara mereka, xxxx untuk key, ini logger, dalam log02 saya mengkonfigurasi level dan a handler beberapa hander. Menurut nama handler ini, go <handlers> untuk menemukan konfigurasi handler spesifik, dan sebagainya. Kemudian dalam kode, lalu muat file konfigurasi: logging.config.fileConfig(log_conf_file) Ada konfigurasi class di handler, dan beberapa pembaca mungkin tidak tahu banyak. Faktanya, ini adalah beberapa kelas handler yang awalnya ditulis dalam logging, Anda dapat menelepon langsung di sini. class Kelas menunjuk ke kategori ini setara dengan pelaksana Handler dari pemrosesan spesifik. Dalam dokumentasi logging, Anda dapat mengetahui bahwa semua kelas Handler di sini adalah thread -safe, semua orang dapat menggunakannya dengan percaya diri. Lalu pertanyaannya adalah, bagaimana jika ada lebih banyak proses?. Di bab berikutnya, saya terutama menulis kelas Handler untuk mencapai penggunaan logging di beberapa lingkungan proses. Kami menulis ulang atau membuat kelas Handler oleh diri kami sendiri, dan kemudian arahkan kelas Handler ke konfigurasi Handler kami <Handler kami. 4.logging menemukan beberapa proses (important) Bagian ini sebenarnya adalah niat asli saya untuk menulis artikel ini. python Karena beberapa alasan historis, kinerja multi -threading pada dasarnya dapat diabaikan. Karena itu. Tapi python logging tidak mendukung banyak proses, jadi saya akan menghadapi banyak masalah. Kali ini saya mengambil masalah TimedRotatingFileHandler sebagai contoh sebagai contoh. Ini Handler peran asli adalah: memotong file log demi hari. (File hari itu adalah xxxx.log file kemarin adalah xxxx.log.2016-06-01). Keuntungan dari ini adalah bahwa seseorang dapat menemukan log sesuai hari, dan yang kedua dapat membuat file log tidak terlalu besar, dan log yang kedaluwarsa dapat dihapus dari hari itu. Tetapi masalahnya datang. Jika Anda menggunakan beberapa proses untuk menampilkan log, hanya ada satu proses untuk beralih. Proses lain akan terus diputar dalam dokumen asli. Mungkin ada proses lain dalam beberapa proses saat beralih. File log terkena hit , maka dia akan menghapusnya tanpa henti, dan kemudian membuat file log baru. Bagaimanapun, saya akan sangat berantakan dan berantakan.. Jadi di sini saya telah memikirkan beberapa cara untuk menyelesaikan masalah beberapa proses logging alasan Sebelum memecahkan, mari kita lihat mengapa ini menyebabkan alasan ini. Posting pertama kode sumber TimedRotatingFileHandler bagian ini adalah operasi yang dibuat selama switching: def doRollover(self): Mari kita amati baris if os.path.exists(dfn). Logikanya di sini adalah bahwa jika file dfn ada, kemudian hapus terlebih dahulu, lalu ganti nama file dfn dfn baseFilename. Kemudian buka file baseFilename dan mulai menulis sesuatu. Maka logikanya di sini sangat jelas Misalkan file log saat ini disebut current.log Nama file adalah current.log.2016-06-01 Tentukan apakah current.log.2016-06-01 ada, jika ada, hapus Nama file log saat ini diganti namanya current.log.2016-06-01 Buka file baru lagi (saya mengamati mode "a" dalam kode sumber, yang dikatakan "w") Jadi dalam hal beberapa proses, suatu proses diaktifkan, dan pegangan proses lain masih current.log.2016-06-01 dan akan terus menulis hal -hal di dalam. Atau mungkin sakelar eksekusi proses, dan proses lainnya akan diganti namanya current.log.2016-06-01 file langsung untuk menghapus secara langsung. Atau ada situasi lain. Ketika satu proses menulis sesuatu, proses lainnya sudah beralih, yang akan menyebabkan situasi yang tidak terduga.. Ada juga satu kasus dua proses memotong file secara bersamaan. Proses pertama adalah mengeksekusi Langkah 3, proses kedua baru saja menyelesaikan langkah kedua, dan kemudian proses pertama telah menyelesaikan ganti nama tetapi belum membuat current.log Proses kedua mulai mengganti nama. Pada saat ini, proses kedua akan salah karena current. Jika proses pertama telah berhasil membuat current.log Proses kedua akan menyimpan file kosong ini sebagai current.log.2016-06-01. Jadi tidak hanya menghapus file log, tetapi juga, proses pertama kali berpikir bahwa itu telah selesai dan divisi tidak akan dipotong lagi, tetapi sebenarnya pegangannya menunjuk ke current.log.2016-06-01. Nah, kelihatannya rumit di sini, pada kenyataannya, karena ketika operasi file dioperasikan, tidak ada kendala pada multi -proses.. Jadi bagaimana menyelesaikan masalah ini dengan elegan?. Saya telah mengusulkan dua rencana, tentu saja, saya akan mengusulkan solusi yang lebih layak di bawah ini untuk semua orang dapat dicoba. Solusi 1 Sebelumnya kami menemukan cacat logis di TimedRotatingFileHandler. Kita hanya perlu sedikit memodifikasi logika: Tentukan apakah file current.log.2016-06-01 ada, jika tidak ada keberadaan, itu akan diganti namanya. (Jika ada proses lain yang telah dipotong, saya tidak perlu memotongnya, ubah saja pegangannya.) Buka current.log dalam mode "a" Sangat sederhana setelah menemukan modifikasi~ talking is cheap show me the code: class SafeRotatingFileHandler(TimedRotatingFileHandler): Jangan berpikir bahwa kode itu begitu lama. Faktanya, bagian modifikasi adalah tempat di mana komentar "##" hanya.. Kelas ini telah mewarisi TimedRotatingFileHandler untuk menulis ulang proses ini. Solusi ini sangat elegan, ada sangat sedikit perubahan, dan juga sangat efektif. Namun, beberapa netizen telah menyarankan bahwa masih ada tempat yang tidak sempurna di sini, yaitu, langkah rename. Jika sangat kebetulan, dua atau lebih proses telah memasuki pernyataan if, dan rename masih sama. Log akan terjadi. Situasi ini memang terjadi. Karena file divisi hanya sekali sehari, ada dua operasi Handler pada saat yang sama ketika divisi dipotong, dan kebetulan ada di sini pada saat yang sama. Di kunci file sebelumnya, if dikunci, dan kemudian dinilai setelah mendapatkan kunci, dan kemudian metode rename sempurna.. Kode tidak diposting lagi, melibatkan kode kunci, yang mempengaruhi keindahan. Solusi 2 Saya pikir solusi paling sederhana dan efektif. Membunuh kembali kelas FileHandler (kelas ini adalah Handler bahwa semua menulis file yang akan diwarisi TimedRotatingFileHandler adalah kelas ini;Kami dapat menambahkan beberapa penilaian dan operasi sederhana. Logika kami seperti ini: Tentukan apakah stempel waktu saat ini bersamaan dengan nama file yang diarahkan Jika tidak, ganti file arah Akhir, apakah itu logika yang sangat sederhana. talking is cheap show me the code: class SafeFileHandler(FileHandler): check_baseFilename adalah logika eksekusi 1 penilaian;build_baseFilename adalah untuk mengeksekusi logika 2 untuk mengubah pegangan. Sangat mudah untuk diselesaikan. Solusi semacam ini berbeda dari sebelumnya bahwa file saat ini adalah current.log.2016-06-01. By Tomorrow, file saat ini adalah current.log.2016-06-02. Sangat sederhana dan elegan. Ini juga dapat menyelesaikan masalah beberapa proses logging. Solusi dan lainnya Tentu saja, ada solusi lain, seperti log proses yang seragam logging, dan proses lain memasuki pipa proses logging dengan proses lain.. Ada juga alasan yang sama di antara log ke dalam jaringan socket. 5. Bahan referensi python logging dokumen resmi |