Ketika proyek Java saya saat ini tumbuh lebih besar dan lebih besar, saya merasakan kebutuhan yang semakin besar untuk memasukkan hasil debug di beberapa titik kode saya.
Untuk mengaktifkan atau menonaktifkan fitur ini dengan tepat, tergantung pada pembukaan atau penutupan sesi tes, saya biasanya meletakkan a private static final boolean DEBUG = false
di awal kelas yang diperiksa oleh tes saya, dan menggunakannya dengan sepele seperti ini (misalnya):
public MyClass {
private static final boolean DEBUG = false;
... some code ...
public void myMethod(String s) {
if (DEBUG) {
System.out.println(s);
}
}
}
dan sejenisnya.
Tapi itu tidak membuat saya senang, karena tentu saja itu berhasil tetapi mungkin ada terlalu banyak kelas untuk mengatur DEBUG menjadi benar, jika Anda tidak hanya menatap beberapa dari mereka.
Sebaliknya, saya (seperti - saya pikir - banyak lainnya) tidak suka menempatkan seluruh aplikasi dalam mode debug, karena jumlah teks yang dihasilkan bisa sangat besar.
Jadi, apakah ada cara yang tepat untuk menangani situasi seperti itu secara arsitektur atau cara yang paling benar adalah dengan menggunakan anggota kelas DEBUG?
Jawaban:
Anda ingin melihat kerangka kerja logging, dan mungkin pada kerangka kerja fasad logging.
Ada beberapa kerangka kerja penebangan di luar sana, seringkali dengan fungsi yang tumpang tindih, sedemikian rupa sehingga seiring berjalannya waktu banyak yang berevolusi untuk bergantung pada API umum, atau telah digunakan melalui kerangka fasad untuk mengabstraksi penggunaannya dan memungkinkannya untuk ditukar di tempat. jika diperlukan.
Kerangka kerja
Beberapa Kerangka Penebangan
Beberapa Fasad Penebangan
Pemakaian
Contoh dasar
Sebagian besar kerangka kerja ini akan memungkinkan Anda untuk menulis sesuatu dari formulir (di sini menggunakan
slf4j-api
danlogback-core
):Perhatikan penggunaan kelas saat ini untuk membuat logger khusus, yang akan memungkinkan SLF4J / LogBack untuk memformat output dan menunjukkan dari mana pesan logging berasal.
Seperti dicatat dalam manual SLF4J , pola penggunaan khas di kelas biasanya:
Tetapi pada kenyataannya, bahkan lebih umum untuk mendeklarasikan logger dengan formulir:
Ini memungkinkan logger untuk digunakan dari dalam metode statis juga, dan itu dibagi di antara semua instance kelas. Ini kemungkinan besar adalah bentuk yang Anda sukai. Namun, seperti dicatat oleh Brendan Long dalam komentar, Anda ingin memastikan untuk memahami implikasinya dan memutuskannya (ini berlaku untuk semua kerangka kerja penebangan yang mengikuti idiom-idiom ini).
Ada beberapa cara lain untuk membuat instance logger, misalnya dengan menggunakan parameter string untuk membuat nama logger:
Level Debug
Tingkat debug bervariasi dari satu kerangka kerja ke kerangka kerja lainnya, tetapi yang umum adalah (dalam urutan kritikalitas, dari jinak ke buruk-buruk, dan dari yang sangat umum hingga mudah-mudahan sangat jarang):
TRACE
Informasi yang sangat rinci. Harus ditulis hanya untuk log. Digunakan hanya untuk melacak aliran program di pos-pos pemeriksaan.DEBUG
Informasi rinci. Harus ditulis hanya untuk log.INFO
Acara runtime yang terkenal. Harus segera terlihat di konsol, jadi gunakan hemat.WARNING
Keanehan runtime dan kesalahan yang dapat dipulihkan.ERROR
Kesalahan runtime lain atau kondisi yang tidak terduga.FATAL
Kesalahan parah yang menyebabkan penghentian prematur.Blok dan Pelindung
Sekarang, katakan Anda memiliki bagian kode di mana Anda akan menulis sejumlah pernyataan debug. Ini dapat dengan cepat memengaruhi kinerja Anda, baik karena dampak dari pencatatan itu sendiri maupun dari pembuatan parameter apa pun yang mungkin Anda lewati ke metode pencatatan.
Untuk menghindari masalah seperti ini, Anda sering ingin menulis sesuatu dari formulir:
Jika Anda belum pernah menggunakan pelindung ini sebelum blok pernyataan debug, meskipun pesan mungkin tidak dihasilkan (jika, misalnya, logger Anda saat ini dikonfigurasikan untuk mencetak hanya hal-hal di atas
INFO
level),heavyComputation()
metode ini masih akan dieksekusi .Konfigurasi
Konfigurasi sangat tergantung pada kerangka logging Anda, tetapi mereka menawarkan sebagian besar teknik yang sama untuk ini:
Mereka juga menawarkan sebagian besar kemampuan yang sama:
Berikut adalah contoh umum dari konfigurasi deklaratif, menggunakan
logback.xml
file.Seperti yang disebutkan, ini tergantung pada kerangka kerja Anda dan mungkin ada alternatif lain (misalnya, LogBack juga memungkinkan skrip Groovy untuk digunakan). Format konfigurasi XML juga dapat bervariasi dari satu implementasi ke yang lain.
Untuk contoh konfigurasi lainnya, silakan rujuk (antara lain) ke:
Beberapa Kesenangan Sejarah
Harap dicatat bahwa Log4J adalah melihat update besar pada saat ini, transisi dari versi 1.x ke 2.x . Anda mungkin ingin melihat keduanya untuk kesenangan atau kebingungan yang lebih historis, dan jika Anda memilih Log4J mungkin lebih suka menggunakan versi 2.x.
Perlu dicatat, seperti yang disebutkan Mike Partridge dalam komentar, bahwa LogBack dibuat oleh mantan anggota tim Log4J. Yang dibuat untuk mengatasi kekurangan kerangka Java Logging. Dan bahwa versi utama Log4J 2.x mendatang adalah dirinya sendiri sekarang mengintegrasikan beberapa fitur yang diambil dari LogBack.
Rekomendasi
Intinya, tetap terpisah sebanyak yang Anda bisa, bermain-main dengan beberapa, dan lihat apa yang terbaik untuk Anda. Pada akhirnya itu hanya kerangka kerja logging . Kecuali jika Anda memiliki alasan yang sangat spesifik, terlepas dari kemudahan penggunaan dan preferensi pribadi, semua ini akan lebih baik sehingga tidak ada gunanya digantung. Sebagian besar dari mereka juga dapat diperluas sesuai kebutuhan Anda.
Namun, jika saya harus memilih kombinasi hari ini, saya akan menggunakan LogBack + SLF4J. Tetapi jika Anda bertanya kepada saya beberapa tahun kemudian saya akan merekomendasikan Log4J dengan Apache Commons Logging, jadi perhatikan dependensi Anda dan berevolusi bersama mereka.
sumber
static
, karena menghemat sedikit memori, tetapi menyebabkan masalah dalam kasus-kasus tertentu: slf4j.org/faq.html#declared_staticgunakan framework logging
sebagian besar waktu ada metode pabrik statis
maka Anda dapat menampilkan kode logging dengan level berbeda:
maka akan ada satu file di mana Anda dapat menentukan pesan mana untuk setiap kelas yang harus ditulis ke output log (file atau stderr)
sumber
Inilah yang dimaksud dengan kerangka logging seperti log4j atau slf4j yang lebih baru. Mereka memungkinkan Anda untuk mengontrol pendataan dengan sangat rinci, dan mengonfigurasinya bahkan saat aplikasi sedang berjalan.
sumber
Kerangka kerja logging jelas merupakan jalan yang harus ditempuh. Namun, Anda juga harus memiliki test suite yang baik. Cakupan pengujian yang baik sering kali menghilangkan kebutuhan untuk debug output secara bersamaan.
sumber