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
dan logback-core
):
package chapters.introduction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// copied from: http://www.slf4j.org/manual.html
public class HelloWorld {
public static void main(String[] args) {
final Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.debug("Hello world, I'm a DEBUG level message");
logger.info("Hello world, I'm an INFO level message");
logger.warn("Hello world, I'm a WARNING level message");
logger.error("Hello world, I'm an ERROR level message");
}
}
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:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyClass {
final Logger logger = LoggerFactory.getLogger(MyCLASS.class);
public void doSomething() {
// some code here
logger.debug("this is useful");
if (isSomeConditionTrue()) {
logger.info("I entered by conditional block!");
}
}
}
Tetapi pada kenyataannya, bahkan lebih umum untuk mendeklarasikan logger dengan formulir:
private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class);
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:
Logger logger = LoggerFactory.getLogger("MyModuleName");
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:
if (LOGGER.isDebugEnabled()) {
// lots of debug logging here, or even code that
// is only used in a debugging context.
LOGGER.debug(" result: " + heavyComputation());
}
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:
- konfigurasi terprogram (saat runtime, melalui API - memungkinkan untuk perubahan runtime ),
- konfigurasi deklaratif statis (saat start-time, biasanya melalui file XML atau properti - kemungkinan merupakan yang Anda butuhkan pada awalnya ).
Mereka juga menawarkan sebagian besar kemampuan yang sama:
- konfigurasi format pesan keluaran (cap waktu, spidol, dll ...),
- konfigurasi level output,
- konfigurasi filter berbutir halus (misalnya untuk menyertakan / mengecualikan paket atau kelas),
- konfigurasi appenders untuk menentukan di mana harus log (untuk menghibur, untuk file, ke layanan web ...) dan mungkin apa yang harus dilakukan dengan log yang lebih lama (misalnya, dengan file bergulir otomatis).
Berikut adalah contoh umum dari konfigurasi deklaratif, menggunakan logback.xml
file.
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
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.