2.1 Birinchi logger – log4j
Bilganingdek, loglar tarixi System.err.println() bilan boshlangan – konsolga yozish uchun. Hozir ham, masalan, Intellij IDEA dasturni debagg qilishda xatolik xabarlarini konsolga chiqarish uchun undan foydalanadi. Ammo bu variantning hech qanday sozlashi yo'q, shuning uchun davom etamiz.
Birinchi va eng mashhur logger Log4j deb atalgan. Bu yaxshi va moslashuvchan sozlanadigan yechim edi. Turli sabablarga ko'ra, bu yechim JDK ga kiritilmadi, bu esa barcha hamjamiyatni biroz xafaladi.
Bu logger nafaqat loglarni yozish mumkin edi, balki u dasturchilar tomonidan dasturchilar uchun yaratilgan va loglar bilan bog'liq muammolarni hal qilishga imkon beradi.
Bilganingizdek, loglar oxirida biror kishining o'qishi va dastur ishlashida nima bo'lganini tushunishga urinishi uchun yoziladi – kutilmagan narsalar qachon va qanday sodir bo'lganini.
log4j da buning uchun uchta narsa bor edi:
- subpaketlarni loglash;
- ko'plab appender’lar (natijalar);
- sozlashlarni qayta yuklash.
Avvalo, log4j sozlashlarini, bir paketda loglashni yoqish va boshqasida o'chirish mumkin edi. Masalan, com.javarush.server paketida loglashni yoqib, lekin com.javarush.server.payment paketida o'chirib qo'yish mumkin edi. Bu loglardan keraksiz ma'lumotlarni tezda olib tashlash imkonini berdi.
Ikkinchidan, log4j loglash natijalarini bir nechta log-fayllarga yozishga ruxsat berdi. Va har biriga individual tarzda sozlash mumkin edi. Masalan, bir faylga faqat jiddiy xatoliklar haqida ma'lumot yozilishi mumkin bo'lgan, ikkinchisiga esa ma'lum bir modul loglari, uchinchisiga esa ma'lum bir vaqt uchun loglar.
Har bir log-fayl, shu tarzda, kutilayotgan muammolarning ma'lum bir turiga moslangan edi. Bu gigabaytli log fayllarini qo'lda ko'rib chiqishdan qoniqmaydigan dasturchilar uchun hayotni yengillashtirdi.
Va nihoyat, uchinchidan, log4j log sozlashlarini dasturni qayta ishga tushirmasdan turib o'zgartirish imkonini berdi. Bu ma'lum bir xatolik bo'yicha qo'shimcha ma'lumot topish uchun log ishlashini tuzatish kerak bo'lganda juda qulay edi.
Muxtasar qilib aytganda! log4j ning ikkita versiyasi mavjud: 1.2.x va 2.x.x, ular bir-biriga mos kelmaydi.
Loggerni loyihaga quyidagi kod bilan ulash mumkin:
<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 Birinchi rasmiy logger – JUL: java.util.logging
Java hamjamiyatida log zootopi paydo bo'lganidan keyin, JDK ishlab chiquvchilari barchasi foydalanishi kerak bo'lgan bir standart logger yaratishga qaror qildilar. Shunday qilib JUL: java.util.logging paketi paydo bo'ldi.
Afsuski, uning ishlab chiqilishida logger yaratish asosiga log4j emas, balki IBM log varianti olindi, bu uning rivojlanishiga ta'sir qildi. Yaxshi yangilik – JUL loggi JDK tarkibida, yomon – undan kamchilik foydalanadi.
Yana shunisi borki, JUL ishlab chiquvchilari "yana bir universal standart" yaratdilar, ular unga o'zlariga xos log darajalarini qo'shdilar, bu esa o'sha davrda mashhur logger sohalarida qabul qilinganlardan farqli edi.
Va bu katta muammo edi. Chunki Java dasturlar ko'pincha ko'p kitobxonlardan iborat bo'ladi va har bir bunday kitobxonada o'z logger mavjud edi. Demak, siz dasturda mavjud bo'lgan barcha loggerlarni sozlash kerak edi.
Logger o'zi unchalik yomon emas. Loggerni yaratish ko'rsatma o'xshash edi. Buning uchun import qilish kerak:
java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());
Sinif ismi loglash qaerdan kelganini bilish uchun maxsus yuboriladi.
Faqat chiqishda muhim muammolar hal etilib, JUL haqiqatan qulay foydalanishga aylandi. Shundan oldin u birorta ikkinchi darajali logger edi.
Bu logger ham lambdalar ifodalarini va dangasa hisoblashlarni qo'llab-quvvatlaydi. Java 8 dan boshlab, unga Supplier<String> ni yuborish mumkin. Bu esa satrni faqat zarur bo'lganda hisoblash va yaratishda foydalanishga yordam beradi, har safar emas, oldingiday.
Metodlar Supplier<String> msgSupplier argumenti bilan quyidagi ko'rinishda:
public void info(Supplier
msgSupplier) { log(Level.INFO, msgSupplier); }
2.3 Birinchi logger-ko'ylak – JCL: jakarta commons logging
Uzoq vaqt davomida loggerlar orasida bir qator standart yo'q edi, JUL bu kabi bo'lishi kerak edi, ammo u log4j dan yomonroq edi, shuning uchun bir qator standart paydo bo'lmadi. Buning o'rniga, har biri o'zi bo'lishni xohlagan loggerlar bog'i paydo bo'ldi.
Biroq oddiy Java ishlab chiquvchilariga har bir kitobxonada o'z logger mavjudligi va uni qanday qilib maxsus sozlash zarurligi yoqmadi. Shuning uchun hamjamiyat boshqa loggerlar ustiga maxsus ko'ylak yaratishga qaror qildi – shunday qilib JCL: jakarta commons logging paydo bo'ldi
Va yana bir bor loyiha, u lider bo'lish uchun yaratilgan, nag'chalik bo'lmadi. G'olibni yaratib bo'lmaydi, faqat g'olib bo'lish mumkin. JCL funksiyasi juda kam edi va hech kim undan foydalanishni xohlamadi. Barcha loggerlarni almashtirish uchun yaratilgan logger JUL kabi taqdirga uchradi – undan foydalanilmagan.
Agar u Apache hamjamiyati tomonidan chiqarilgan ko'pgina kitobxonalar tarkibiga qo'shilgan bo'lsa-da, loggerlar bog'i faqat o'sib bordi.
2.4 Birinchi oxirgi logger – Logback
Lekin bu hammasi emas. log4j dasturchisi o'zini eng aqlli deb o'yladi (axir uning loggeridan ko'pchilik odamlar foydalanishardi) va yangi, yaxshilangan logger yaratishga qaror qildi, u o'zida log4j va boshqa loggerlarning afzalliklarini birlashtiradi.
Yangi logger Logback deb nomlandi. Ushbu logger kelajakda yagona logger bo'lishi kerak edi, undan barchasi foydalanishi kerak edi. Asosda log4j da mavjud bo'lgan g'oya bor edi.
Ushbu loggerni loyihaga quyidagi kod bilan ulash mumkin:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
Farqlar Logback da:
- ishlash kuchaytirilgan;
- native
slf4jqo'llab-quvvatlash qo'shilgan; - filtrlash opsiyasi kengaytirilgan.
Ushbu loggerning yana bir afzalligi shundaki, unda juda yaxshi dastlabki sozlamalar mavjud edi. Loggerni faqat biror narsani o'zgartirmoqchi bo'lsangiz sozlash kerak edi. Shuningdek, sozlash fayli korporativ dastur uchun yaxshiroq moslashtirilgan edi – barcha uning sozlamalari xml/ formatda ko'rsatildi.
Default bo'yicha Logback hech qanday sozlamalarni talab qilmaydi va DEBUG va undan yuqori darajadagi barcha loglarni yozadi. Agar sizga boshqa xatti-harakat kerak bo'lsa, uni xml konfiguratsiyasi orqali sozlash mumkin:
<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 Oxirgi universal logger – SLF4J: Simple Logging Facade for Java
Qanday qilib oltin o'rtani topish yo'li uzoq bo'lishi mumkin...
2006 yilda log4j yaratuvchilaridan biri loyihadan chiqdi va yana bir bor universal logger yaratishga harakat qildi. Ammo bu safar bu yangi logger emas, balki yangi universal standart (ko'ylak) edi, u turli loggerlarni bir-biri bilan qoshiqish imkonini berdi.
Ushbu logger slf4j—Simple Logging Facade for Java deb nomlandi, u log4j, JUL, common-loggins va logback atrofida ko'ylak edi. Ushbu logger haqiqiy muammolarni hal qildi – loggerlar bog'ini boshqarish, shuning uchun ham hamma darhol undan foydalanishni boshladi.
Biz o'zimizga yaratilgan muammolarni qahramonlarcha hal qilamiz. Ko'rib turganimizdek, umr taraqqiyoti shunday bo'ldiki, ko'ylak ustiga ko'ylak yaratdik...
Ko'ylakning o'zi ikki qismdan iborat:
API, ilovalarda foydalanilgan;- Har bir logger uchun alohida bog'liqliklar sifatida qo'shilgan amalga oshirishlar.
Loggerni loyihaga quyidagi kod bilan ulash mumkin:
<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>
To'g'ri amalga oshirishni ulash kifoya va hamma narsa: butun loyiha u bilan ishlaydi.
2.6 slf4j'da optimallashtirish
Slf4j loglarni yozish uchun string formatting kabi barcha yangi funksiyalarni qo'llab-quvvatlaydi. Oldin shunday muammo bor edi. Aytaylik, sen logga xabar yozmoqchisan:
log.debug("User " + user + " connected from " + request.getRemoteAddr());
Bu kod bilan muammo bor. Aytaylik, ilovangiz production da ishlamoqda va hech qanday DEBUG-xabarlarni logga yozmaydi, shunga qaramay, log.debug() metodi chaqiriladi va uning chaqirilishi bilan quyidagi metodlar ham chaqiriladi:
user.toString();request.getRemoteAddr();
Bu metodlar chaqirilishi ilovaning ishlashini sekinlashtiradi. Ularning chaqirilishi faqat debagg qilish vaqti kerak, lekin ular har doim chaqiriladi.
Logik nuqtai nazardan, bu muammoni loglash kutubxonasining o'zida hal qilish kerak edi. Log4j ning birinchi versiyasida bu muammo echimi topilgan:
if (log.isDebugEnabled()) {
log.debug("User " + user + " connected from " + request.getRemoteAddr());
}
Endi loglash uchun bir satr o'rniga uchta yozish kerak edi. Bu kodning o'qilishini keskin yomonlashtirgan va log4j ning mashhurligini pasaytirdi.
Logger slf4j biroz yaxshilay oldi, aqlli loglash taklif qilib. Bu quyidagicha ko'rinishda edi:
log.debug("User {} connected from {}", user, request.getRemoteAddr());
qayerda {} metodda uzatilgan argumentlarni qo'yish belgilanadi. Ya'ni, birinchi {} user ga, ikkinchisi request.getRemoteAddr() ga mos keladi.
Bu parametrlar faqat loglash darajasi logga yozishga ruxsat berganda yagona xabarga konkatene qilinadi. Ideal emas, lekin boshqa barcha variantlardan yaxshiroqdir.
Bundan so'ng SLF4J tezda mashhur bo'la boshladi, hozirgi vaqtda bu eng yaxshi yechimdir.
Shuning uchun biz loglashni slf4j-log4j12 kombinatsiyasi misolida ko'rib chiqamiz.
GO TO FULL VERSION