System.out.println vs Loggers

1. Mengapa Pembalak?

Semasa menulis program atau mengembangkan aplikasi pengeluaran perusahaan, menggunakan System.out.println nampaknya merupakan pilihan termudah dan termudah. Tidak ada perpustakaan tambahan yang akan ditambahkan ke jalan kelas dan tidak ada konfigurasi tambahan yang akan dibuat.

Tetapi menggunakan System.out.println dilengkapi dengan beberapa kelemahan yang mempengaruhi kebolehgunaannya dalam banyak keadaan. Dalam tutorial ini, kita akan membincangkan mengapa dan bila kita akan mahu menggunakan Logger berumur lebih daripada biasa System.out dan System.err . Kami juga akan menunjukkan beberapa contoh cepat menggunakan kerangka log Log4J2.

2. Persediaan

Sebelum memulakan, mari kita perhatikan kebergantungan dan konfigurasi Maven yang diperlukan.

2.1. Ketergantungan Maven

Mari mulakan dengan menambahkan kebergantungan Log4J2 ke pom.xml kami :

 org.apache.logging.log4j log4j-api 2.12.1   org.apache.logging.log4j log4j-core 2.12.1 

Kami dapat mencari versi terbaru log4j-api dan log4j-core di Maven Central.

2.2. Konfigurasi Log4J2

Penggunaan System.out tidak memerlukan konfigurasi tambahan. Namun, untuk menggunakan Log4J2, kami memerlukan fail konfigurasi log4j.xml :

Hampir semua kerangka kerja logger memerlukan beberapa tahap konfigurasi, sama ada secara programatik atau melalui fail konfigurasi luaran, seperti fail XML yang ditunjukkan di sini.

3. Memisahkan Hasil Log

3.1. System.out dan System.err

Semasa kami menyebarkan aplikasi kami ke pelayan seperti Tomcat, pelayan menggunakan loggernya sendiri. Sekiranya kita menggunakan System.out , log akan berakhir di catalina.out . Jauh lebih mudah untuk debug aplikasi kami jika log dimasukkan ke dalam fail yang berasingan. Dengan Log4j2, kita perlu memasukkan pelengkap fail dalam konfigurasi untuk menyimpan log aplikasi dalam fail yang berasingan.

Juga, dengan System.out.println , tidak ada kawalan atau penapisan log mana yang akan dicetak. Satu-satunya cara yang mungkin untuk memisahkan log adalah menggunakan System.out.println untuk log maklumat dan System.err.println untuk log ralat:

System.out.println("This is an informational message"); System.err.println("This is an error message");

3.2. Tahap Pembalakan Log4J2

Dalam persekitaran debug atau pengembangan, kami ingin melihat semua maklumat yang dicetak oleh aplikasi. Tetapi dalam aplikasi perusahaan langsung, lebih banyak log bermaksud peningkatan kependaman. Kerangka logger seperti Log4J2 menyediakan pelbagai kawalan tahap log:

  • MAUT
  • KESALAHAN
  • AMARAN
  • INFO
  • HUTANG
  • LATIHAN
  • SEMUA

Dengan menggunakan tahap ini, kita dapat menapis kapan dan di mana mencetak maklumat apa dengan mudah :

logger.trace("Trace log message"); logger.debug("Debug log message"); logger.info("Info log message"); logger.error("Error log message"); logger.warn("Warn log message"); logger.fatal("Fatal log message");

Kami juga boleh mengkonfigurasi tahap untuk setiap pakej kod sumber secara berasingan. Untuk keterangan lebih lanjut mengenai konfigurasi tahap log, rujuk artikel Java Logging kami.

4. Menulis Log ke Fail

4.1. Laluan semula System.out dan System.err

Adalah mungkin untuk mengarahkan System.out.println ke fail menggunakan kaedah System.setOut () :

PrintStream outStream = new PrintStream(new File("outFile.txt")); System.setOut(outStream); System.out.println("This is a baeldung article");

Dan sekiranya System.err :

PrintStream errStream = new PrintStream(new File("errFile.txt")); System.setErr(errStream); System.err.println("This is a baeldung article error");

Ketika mengalihkan output ke file menggunakan System.out atau System.err , kami tidak dapat mengendalikan ukuran file , sehingga file terus berkembang selama jangka waktu aplikasi berjalan.

Apabila saiz fail bertambah, mungkin sukar untuk membuka atau menganalisis log yang lebih besar ini.

4.2. Melog masuk ke Fail Dengan Log4J2

Log4J2 menyediakan mekanisme untuk menulis log dalam fail secara sistematik dan juga menggulung fail berdasarkan dasar tertentu. Sebagai contoh, kita dapat mengkonfigurasi fail yang akan digulung berdasarkan corak tarikh / waktu :

Atau kita boleh menggulung fail berdasarkan ukuran setelah mencapai ambang yang ditentukan :

...   %d{yyyy-MM-dd HH:mm:ss} %p %m%n      

5. Log masuk ke Sistem Luaran

Seperti yang telah kita lihat di bahagian sebelumnya, kerangka logger membenarkan menulis log ke fail. Begitu juga, mereka juga menyediakan appenders untuk menghantar log ke sistem dan aplikasi lain . Ini memungkinkan untuk menghantar log ke Aliran Kafka atau pangkalan data Elasticsearch menggunakan lampiran Log4J daripada menggunakan System.out.println.

Sila rujuk artikel pelengkap Log4j kami untuk maklumat lebih lanjut mengenai cara menggunakan pelengkap tersebut.

6. Menyesuaikan Output Log

Dengan penggunaan Logger, kita dapat menyesuaikan maklumat apa yang akan dicetak bersama dengan mesej sebenar. Maklumat yang boleh kami cetak merangkumi nama pakej, tahap log, nombor baris, cap waktu, nama kaedah, dll.

While this would be possible with System.out.println, it would require a lot of manual work, while logging frameworks provide this functionality out of the box. With loggers, we can simply define a pattern in the logger configuration:

If we consider Log4J2 for our logger framework, there are several patterns that we can choose from or customize. Refer to the official Log4J2 documentation to learn more about them.

7. Conclusion

This article explains various reasons why to use a logger framework and why not to rely only on System.out.println for our application logs. While it is justifiable to use System.out.println for small test programs, we'd prefer not to use it as our main source of logging for an enterprise production application.

As always, the code examples in the article are available over on GitHub.