2.1 Logger pertama - log4j

Seperti yang sudah Anda ketahui, riwayat log dimulai dengan System.err.println()keluaran rekaman ke konsol. Itu masih aktif digunakan untuk debugging, misalnya, Intellij IDEA menggunakannya untuk menampilkan pesan kesalahan ke konsol. Tetapi opsi ini tidak memiliki pengaturan apa pun, jadi mari kita lanjutkan.

Logger pertama dan terpopuler disebut Log4j. Itu adalah solusi yang bagus dan sangat dapat disesuaikan. Karena berbagai keadaan, keputusan ini tidak pernah masuk ke JDK, yang sangat mengecewakan seluruh komunitas.

Logger ini tidak hanya bisa login, itu dibuat oleh programmer untuk programmer dan memungkinkan mereka untuk memecahkan masalah yang terus muncul sehubungan dengan logging.

Seperti yang sudah Anda ketahui, log ditulis di bagian akhir sehingga seseorang membacanya dan mencoba memahami apa yang terjadi selama operasi program - apa dan kapan yang salah seperti yang diharapkan.

Ada log4jtiga hal untuk ini:

  • pencatatan subpaket;
  • set appenders (hasil);
  • pengaturan isi ulang panas.

Pertama, pengaturan log4jdapat ditulis sedemikian rupa untuk mengaktifkan login di satu paket dan menonaktifkannya di paket lain. Misalnya, dimungkinkan untuk mengaktifkan login di com.codegym.server, tetapi menonaktifkannya di com.codegym.server.payment. Ini memungkinkan untuk dengan cepat menghapus informasi yang tidak perlu dari log.

Kedua, log4jmemungkinkan penulisan hasil logging ke beberapa file log sekaligus. Dan output ke masing-masing dapat dikonfigurasi secara individual. Misalnya, dalam satu file dimungkinkan untuk menulis hanya informasi tentang kesalahan serius, di file lain - log dari modul tertentu, dan di file ketiga - log untuk waktu tertentu.

Setiap file log dengan demikian disetel ke jenis masalah yang diharapkan tertentu. Ini sangat menyederhanakan kehidupan pemrogram yang tidak suka melihat file log gigabyte secara manual.

Dan terakhir, ketiga, log4jmemungkinkan mengubah pengaturan log secara langsung saat program sedang berjalan, tanpa memulai ulang. Ini sangat berguna ketika diperlukan untuk memperbaiki pekerjaan log untuk menemukan informasi tambahan tentang kesalahan tertentu.

Penting! Ada dua versi log log4j: 1.2.x dan 2.xx , yang tidak kompatibel satu sama lain .

Anda dapat menghubungkan logger ke proyek menggunakan kode:

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
  </dependency>
 
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
  </dependency>
</dependencies>

2.2 Logger resmi pertama - JUL: java.util.logging

Setelah kebun binatang penebang muncul di komunitas Java, pengembang JDKmemutuskan untuk membuat satu penebang kayu standar yang akan digunakan semua orang. Beginilah tampilan logger JUL: package java.util.logging.

Namun, dalam perkembangannya, pembuat logger tidak mengambil dasar log4j, melainkan varian logger dari IBM, yang memengaruhi perkembangannya. Kabar baiknya adalah logger JULdisertakan JDK, kabar buruknya adalah hanya sedikit orang yang menggunakannya.

JUL

Pengembang tidak hanya JULmembuat "standar universal lain" , mereka juga membuat level logging sendiri untuk itu, yang berbeda dari yang diterima oleh penebang populer saat itu.

Dan itu adalah masalah besar. Lagi pula, produk Javasering kali dikumpulkan dari sejumlah besar perpustakaan, dan setiap perpustakaan tersebut memiliki loggernya sendiri. Jadi perlu untuk mengonfigurasi semua penebang yang ada di aplikasi.

Meskipun loggernya sendiri cukup bagus. Membuat logger kurang lebih sama. Untuk melakukan ini, Anda perlu mengimpor:


java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());

Nama kelas secara khusus diteruskan untuk mengetahui dari mana asal logging.

Hanya dengan rilis, pengembang memecahkan masalah penting, setelah itu JULsangat nyaman digunakan. Sebelumnya, itu adalah semacam penebang kelas dua.

Logger ini juga mendukung ekspresi lambda dan evaluasi malas. Dimulai dengan Java 8, Anda bisa lulus Supplier<String>. Ini membantu untuk membaca dan membuat string hanya pada saat itu benar-benar dibutuhkan, dan tidak setiap saat, seperti sebelumnya.

Metode dengan argumen Supplier<String> msgSupplierterlihat seperti ini:

public void info(Supplier msgSupplier) {
   log(Level.INFO, msgSupplier);
}

2.3 Pembungkus logger pertama - JCL: jakarta commons logging

Untuk waktu yang lama tidak ada standar tunggal di antara para penebang, seharusnya JULmenjadi satu, tetapi lebih buruk log4j, jadi standar tunggal tidak pernah muncul. Tapi seluruh kebun binatang penebang muncul, yang masing-masing ingin menjadi sama.

JCL

Namun, pengembang Java biasa tidak suka bahwa hampir setiap perpustakaan memiliki logger sendiri dan perlu dikonfigurasi dengan cara khusus. Oleh karena itu, komunitas memutuskan untuk membuat pembungkus khusus di atas penebang lain - begitulah caranyaJCL: jakarta commons logging

Dan lagi, proyek yang dibuat untuk menjadi pemimpin tidak menjadi satu. Anda tidak bisa menciptakan pemenang, Anda hanya bisa menjadi pemenang. Fungsinya JCLsangat buruk dan tidak ada yang mau menggunakannya. Logger, yang dirancang untuk menggantikan semua logger, menemui nasib yang sama karena JULtidak digunakan.

Meskipun telah ditambahkan ke banyak perpustakaan yang dirilis oleh komunitas Apache, kebun binatang penebang hanya tumbuh.

2.4 Logger terakhir pertama - Logback

Tapi itu belum semuanya. Pengembang log4jmemutuskan bahwa dia adalah yang paling cerdas (yah, bagaimanapun juga, kebanyakan orang menggunakan logger-nya) dan memutuskan untuk menulis logger baru yang lebih baik yang akan menggabungkan keunggulan log4jlogger lainnya.

Logger baru disebut Logback. Logger inilah yang seharusnya menjadi logger tunggal masa depan yang akan digunakan semua orang. Itu didasarkan pada ide yang sama seperti di log4j.

Anda dapat menghubungkan logger ini ke proyek menggunakan kode:


<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

Perbedaannya adalah pada Logback:

  • peningkatan kinerja;
  • menambahkan dukungan asli slf4j;
  • opsi penyaringan yang diperluas.

Keuntungan lain dari logger ini adalah memiliki pengaturan default yang sangat baik. Dan Anda harus mengonfigurasi logger hanya jika Anda ingin mengubah sesuatu di dalamnya. Selain itu, file pengaturan lebih baik disesuaikan dengan perangkat lunak perusahaan - semua konfigurasinya ditetapkan sebagai xml/.

Secara default, Logbackini tidak memerlukan pengaturan apa pun dan merekam semua log dari level DEBUGke atas. Jika Anda memerlukan perilaku yang berbeda, itu dapat dikonfigurasi melalui xmlkonfigurasi:

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss,SSS} %-5p [%c] - %m%n</pattern>
        </encoder>
    </appender>
    <logger name="org.hibernate.SQL" level="DEBUG" />
    <logger name="org.hibernate.type.descriptor.sql" level="TRACE" />
    <root level="info">
        <appender-ref ref="FILE" />
    </root>
</configuration>

2.5 Logger universal terbaru - SLF4J: Fasad Logging Sederhana untuk Java

Berapa lama waktu yang dibutuhkan untuk menemukan rata-rata emas...

Pada tahun 2006, salah satu pencipta log4jkeluar dari proyek dan memutuskan untuk mencoba lagi membuat logger universal. Tapi kali ini bukan logger baru, tapi standar universal baru (pembungkus) yang memungkinkan logger berbeda untuk berinteraksi bersama.

Logger ini disebut slf4j — Simple Logging Facade for Java, itu adalah pembungkus log4j, JUL, common-loggins and logback. Pencatat ini memecahkan masalah nyata - mengelola kebun binatang penebang, jadi semua orang segera mulai menggunakannya.

Kami dengan heroik memecahkan masalah yang kami buat untuk diri kami sendiri. Seperti yang Anda lihat, kemajuan telah mencapai titik di mana kami telah membuat pembungkus di atas pembungkus ...

Bungkus itu sendiri terdiri dari dua bagian:

  • API, yang digunakan dalam aplikasi;
  • Implementasi yang ditambahkan sebagai dependensi terpisah untuk setiap logger.

Anda dapat menghubungkan logger ke proyek menggunakan kode:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.17.2</version>
</dependency>

Cukup menghubungkan implementasi yang benar dan hanya itu: seluruh proyek akan bekerja dengannya.

2.6 Optimasi di slf4j

Slf4jmendukung semua fitur baru seperti pemformatan string untuk logging . Sebelum ini ada masalah seperti itu. Katakanlah Anda ingin mencetak pesan ke log:

log.debug("User " + user + " connected from " + request.getRemoteAddr());

Ada masalah dengan kode ini. Misalkan aplikasi Anda berfungsi productiondan tidak menulis apa pun ke log DEBUG-messages, namun, metode tersebut log.debug()akan tetap dipanggil, dan saat dipanggil, metode berikut juga akan dipanggil:

  • user.toString();
  • request.getRemoteAddr();

Memanggil metode ini memperlambat aplikasi. Panggilan mereka diperlukan hanya selama debugging, tetapi mereka tetap dipanggil.

Dari sudut pandang logika, masalah ini harus diselesaikan di perpustakaan logging itu sendiri. Dan di versi pertama log4j solusinya muncul:

if (log.isDebugEnabled()) {
    log.debug("User " + user + " connected from " + request.getRemoteAddr());
}

Alih-alih satu baris untuk log, sekarang perlu menulis tiga baris. Yang secara dramatis memperburuk keterbacaan kode, dan menurunkan popularitas log4j.

Logger slf4jdapat sedikit memperbaiki situasi dengan menawarkan smart logging. Itu terlihat seperti ini:

log.debug("User {} connected from {}", user, request.getRemoteAddr());

di mana {}menunjukkan penyisipan argumen yang diteruskan dalam metode. Artinya, yang pertama {}sesuai dengan pengguna, yang kedua {}dengan request.getRemoteAddr().

Parameter ini akan digabungkan menjadi satu pesan hanya jika tingkat logging memungkinkan logging. Tidak sempurna, tetapi lebih baik dari semua opsi lainnya.

Setelah itu, SLF4Jpopularitasnya mulai berkembang pesat, saat ini ini adalah solusi terbaik.

Oleh karena itu, kami akan mempertimbangkan untuk masuk menggunakan contoh bundel slf4j-log4j12.