Hər kəsə salam, JavaRush icması! Bu gün Java qeydi haqqında danışacağıq:
- Bu nədir, niyə belədir. Hansı hallarda istifadə etmək daha yaxşıdır, hansı hallarda deyil?
- Java-da hansı növ giriş proqramları var və bu müxtəlifliklə nə etməliyik?
Giriş səviyyələri. Əlavənin nə olduğunu və onu necə düzgün konfiqurasiya edəcəyimizi müzakirə edək.
- Giriş qovşaqları və hər şey istədiyimiz kimi işləməsi üçün onları necə düzgün konfiqurasiya etmək olar.
Bu material geniş auditoriya üçün nəzərdə tutulub. Həm Java ilə yeni tanış olanlara, həm də artıq işləyən, lakin bunu yalnız
logger.info(“log something”);
Let's Go ilə başa düşənlərə aydın olacaq!
Giriş niyə lazımdır?
Girişin problemi həll edəcəyi real hallara baxaq. Budur mənim işimdən bir nümunə. Digər xidmətlərlə inteqrasiya edən tətbiq nöqtələri var. Mən bu nöqtələrin qeydini
“alibi” kimi istifadə edirəm : inteqrasiya işləməsə, problemin hansı tərəfdən qaynaqlandığını anlamaq asan olacaq. Verilənlər bazasında saxlanılan vacib məlumatları daxil etmək də məsləhətdir. Məsələn, administrator istifadəçisi yaratmaq. Qeydiyyatdan keçmək yaxşı olardı.
Java Giriş Alətləri
Java-da giriş üçün tanınmış həllər daxildir:
- log4j
- JUL - java.util.logging
- JCL - jakarta Commons logging
- Giriş
- SLF4J - java üçün sadə giriş fasad
Gəlin onların hər birinə qısaca nəzər salaq və materialın praktiki hissəsində Slf4j - log4j əlaqəsini əsas götürəcəyik . Bu, indi qəribə görünə bilər, amma narahat olmayın: məqalənin sonunda hər şey aydın olacaq. |
System.err.println
Əvvəlcə, əlbəttə ki,
System.err.println (konsola qeyd çıxışı) var idi. Sazlama zamanı jurnalı tez bir zamanda əldə etmək üçün hələ də istifadə olunur. Əlbəttə ki, burada heç bir parametr haqqında danışmağa ehtiyac yoxdur, ona görə də onu xatırlayaq və davam edək.
Log4j
Bu, artıq tərtibatçıların ehtiyaclarından yaradılmış tam hüquqlu bir həll idi. İstifadəsi həqiqətən maraqlı bir vasitə olduğu ortaya çıxdı. Müxtəlif şərtlərə görə, bu həll heç vaxt JDK-ya çevrilmədi, bu da bütün cəmiyyəti çox narahat etdi. log4j-də konfiqurasiya seçimləri var idi ki, giriş paketdə açılsın
com.example.type
və alt paketdə söndürülə bilsin
com.example.type.generic
. Bu, qeyd edilməli olanı lazım olmayandan tez bir zamanda ayırmağa imkan verdi. Burada qeyd etmək lazımdır ki,
log4j-in iki versiyası var: 1.2.x və 2.x.x, bir-biri ilə uyğun gəlmir .
log4j əlavə kimi bir konsepsiya əlavə etdi , yəni logların qeyd edildiyi bir alət və layout - log formatlaşdırma. Bu, yalnız sizə lazım olanı və necə ehtiyac duyduğunuzu qeyd etməyə imkan verir. Bir az sonra əlavələr haqqında daha çox danışacağıq.
JUL - java.util.logging
Əsas üstünlüklərdən biri həlldir - JUL JDK-ya (Java inkişaf dəsti) daxildir. Təəssüf ki, onun inkişafı zamanı əsas götürülən məşhur log4j deyil, onun inkişafına təsir edən IBM-in həlli idi. Əslində, hazırda JUL var, amma heç kim istifadə etmir. “Beləliklə”: İYUL ayında giriş səviyyələri Logback, Log4j, Slf4j-də olanlardan fərqlidir və bu, onlar arasındakı anlaşmanı pisləşdirir. Bir logger yaratmaq az və ya çox oxşardır. Bunu etmək üçün idxal etməlisiniz:
java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());
Sinif adı girişin haradan gəldiyini bilmək üçün xüsusi olaraq verilir. Java 8-dən bəri keçmək mümkündür
Supplier<String>
. Bu, əvvəllər olduğu kimi hər dəfə deyil, yalnız həqiqətən lazım olduğu anda bir simli saymağa və yaratmağa kömək edir. Yalnız Java 8-in buraxılması ilə tərtibatçılar mühüm problemləri həll etdilər, bundan sonra JUL həqiqətən istifadəyə yararlı oldu.
Supplier<String> msgSupplier
Məhz, aşağıda göstərildiyi kimi arqumentli üsullar :
public void info(Supplier<String> msgSupplier) {
log(Level.INFO, msgSupplier);
}
JCL - jakarta Commons logging
Uzun müddətdir ki, karotajda heç bir sənaye standartı olmadığına və bir çox insanın öz xüsusi logger yaratdığı bir dövr olduğuna görə, onlar JCL-ni buraxmağa qərar verdilər - başqaları üzərində istifadə ediləcək ümumi sarğı. Niyə? Layihəyə bəzi asılılıqlar əlavə olunduqda, onlar layihədəki qeydedicidən fərqli bir qeyddən istifadə edə bilərdilər. Buna görə də, onlar hamısını bir araya gətirməyə çalışarkən real problemlər yaradan layihəyə keçidlə əlavə edildi. Təəssüf ki, sarğı funksionallıq baxımından çox zəif idi və heç bir əlavə təqdim etmədi. Hər kəs öz işini görmək üçün JCL-dən istifadə etsəydi, yəqin ki, rahat olardı. Ancaq əslində bu, belə nəticə vermədi, ona görə də JCL-dən istifadə etmək hazırda yaxşı fikir deyil.
Giriş
Açıq mənbənin yolu necə də tikanlıdır... Logback onun davamçısı yaratmaq üçün log4j ilə eyni tərtibatçı tərəfindən yazılmışdır. İdeya log4j ilə eyni idi. Fərqlər logback-də idi:
- təkmilləşdirilmiş performans;
- slf4j üçün yerli dəstək əlavə edildi;
- Filtrləmə seçimi genişləndirildi.
Varsayılan olaraq, logback heç bir parametr tələb etmir və DEBUG səviyyəsindən və yuxarıdakı bütün qeydləri qeyd edir. Konfiqurasiya lazımdırsa, xml konfiqurasiyası vasitəsilə edilə bilər:
<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>
SLF4J - java üçün sadə giriş fasad
Təxminən 2006-cı ildə log4j-in yaradıcı atalarından biri layihəni tərk etdi və slf4j - Java üçün Simple Logging Facade - log4j, JUL, ümumi girişlər və logback ətrafında sarğı yaratdı. Göründüyü kimi, irəliləyiş o yerə çatıb ki, sarğının üstünə sarğı yaradıblar... Üstəlik, o, iki hissəyə bölünür: tətbiqdə istifadə olunan API və əlavə olaraq əlavə edilən həyata keçirmə. hər bir giriş növü üçün ayrıca asılılıqlar. Misal üçün,
slf4j-log4j12.jar
,
slf4j-jdk14.jar
. Düzgün tətbiqi birləşdirmək kifayətdir və budur: bütün layihə onunla işləyəcək. Slf4j giriş üçün sətir formatı kimi bütün yeni xüsusiyyətləri dəstəkləyir. Əvvəllər belə bir problem var idi. Tutaq ki, log girişi var:
log.debug("User " + user + " connected from " + request.getRemoteAddr());
Obyektdə sətir birləşməsinə görə
user
gizli çevrilmə baş verir
user.toString()
və bu zaman tələb edir, bu da sistemi yavaşlatır. Tətbiqdə debug etsək hər şey qaydasındadır. Bu sinif üçün qeydiyyat səviyyəsi INFO və daha yüksək olduqda problemlər başlayır. Yəni bu log yazılmamalı, sətir birləşmə də yerinə yetirilməməlidir. Nəzəri olaraq, buna giriş kitabxanasının özü qərar verməli idi. Üstəlik, bu, log4j-in ilk versiyasının ən böyük problemi oldu. Normal bir həll təqdim etmədilər, lakin bunu belə etməyi təklif etdilər:
if (log.isDebugEnabled()) {
log.debug("User " + user + " connected from " + request.getRemoteAddr());
}
Yəni bir logging sətri əvəzinə 3(!) yazmağı təklif etdilər. Giriş kodundakı dəyişiklikləri minimuma endirməlidir və üç sətir ümumi yanaşma ilə açıq şəkildə ziddiyyət təşkil edir. slf4j-in JDK və API ilə uyğunluq problemi yox idi, buna görə də dərhal gözəl bir həll ortaya çıxdı:
log.debug("User {} connected from {}", user, request.getRemoteAddr());
burada
{}
metodda ötürülən arqumentlərin əlavələrini göstərir. Yəni birinci
{}
uyğun gəlir
user
, ikinci
{}
-
request.getRemoteAddr()
. Buna görə, yalnız giriş səviyyəsi girişə icazə verərsə, bu mesaj vahid bir mesaja birləşdirilə bilər. Bundan sonra SJF4J tez bir zamanda populyarlıq qazandı və hazırda ən yaxşı həll yoludur. Buna görə də, paket nümunəsindən istifadə edərək girişi nəzərdən keçirəcəyik
slf4j-log4j12
.
Nəyi qeyd etmək lazımdır
Əlbəttə ki, hər şeyi qeyd etməməlisiniz. Bəzən bu lazımsız və hətta təhlükəlidir. Məsələn, kiminsə şəxsi məlumatlarını girov qoysanız və bu, bir şəkildə üzə çıxsa, xüsusilə Qərbə yönəlmiş layihələrdə real problemlər yaranacaq.
Ancaq qeyd etmək məcburiyyətində olan bir şey də var :
- Tətbiqin başlanğıcı/sonu. Tətbiqin əslində gözlədiyimiz kimi işə salındığını və gözlənildiyi kimi bitdiyini bilməliyik.
- Təhlükəsizlik sualları. Burada parol təxmin cəhdlərini, mühüm istifadəçilərin girişlərini və s. daxil etmək yaxşı olardı.
- Bəzi tətbiq dövlətləri . Məsələn, bir iş prosesində bir vəziyyətdən digərinə keçid.
- Müvafiq giriş səviyyəsi ilə sazlama üçün bəzi məlumatlar.
- Bəzi SQL skriptləri. Bunun lazım olduğu real hallar var. Yenə səviyyələri məharətlə tənzimləməklə əla nəticələr əldə etmək olar.
- Düzgün əməliyyat yoxlanıldığı hallarda yerinə yetirilən mövzular (Thread) daxil edilə bilər.
Populyar giriş səhvləri
Çox nüanslar var, lakin burada bir neçə ümumi səhv var:
- Həddindən artıq giriş. Nəzəri cəhətdən vacib ola biləcək hər addımı qeyd etməməlisiniz. Bir qayda var: jurnallar performansı 10% -dən çox yükləyə bilər. Əks halda performans problemləri olacaq.
- Bütün məlumatların bir fayla daxil edilməsi. Bu, müəyyən bir nöqtədə oxumağı/yazmağı çox çətinləşdirəcək, müəyyən sistemlərdə fayl ölçüsü məhdudiyyətlərini qeyd etmək olmaz.
- Səhv giriş səviyyələrindən istifadə. Hər bir giriş səviyyəsi aydın sərhədlərə malikdir və ona hörmət edilməlidir. Sərhəd qeyri-müəyyəndirsə, hansı səviyyədən istifadə edəcəyinizi razılaşdıra bilərsiniz.
Giriş səviyyələri
|
|
|
x: Görünən |
|
|
|
|
FATAL |
XƏTA |
XƏBƏRDARLIQ |
MƏLUMAT |
DEBUG |
İZ |
HAMISI |
OFF |
|
|
|
|
|
|
|
FATAL |
x |
|
|
|
|
|
|
XƏTA |
x |
x |
|
|
|
|
|
XƏBƏRDARLIQ |
x |
x |
x |
|
|
|
|
MƏLUMAT |
x |
x |
x |
x |
|
|
|
DEBUG |
x |
x |
x |
x |
x |
|
|
İZ |
x |
x |
x |
x |
x |
x |
|
HAMISI |
x |
x |
x |
x |
x |
x |
x |
Giriş səviyyələri nədir? Günlükləri bir növ sıralamaq üçün müəyyən təyinatlar və fərqlər vermək lazım idi. Bu məqsədlə karotaj səviyyələri tətbiq edilmişdir. Səviyyə tətbiqdə müəyyən edilir. Əgər qeyd təyin olunmuş səviyyədən aşağı səviyyəyə aiddirsə, o, jurnala daxil edilmir. Məsələn, proqramın debug edilməsi üçün istifadə olunan qeydlərimiz var. Normal istehsal işində (tətbiq təyinatı üzrə istifadə edildikdə) belə loglara ehtiyac yoxdur. Buna görə də, giriş səviyyəsi sazlamadan daha yüksək olacaq. Nümunə olaraq log4j-dən istifadə edərək səviyyələrə baxaq. JUL istisna olmaqla, digər həllər eyni səviyyələrdən istifadə edir. Burada onlar azalan qaydadadır:
- OFF: heç bir qeyd yazılmır, hamısı nəzərə alınmayacaq;
- FATAL: bundan sonra proqram artıq işləyə bilməyəcək və dayandırılacaq xəta, məsələn, JVM yaddaşdan kənar xəta;
- XƏTƏ: Həll edilməli olan problemlər olduqda səhv nisbəti. Səhv bütövlükdə tətbiqi dayandırmır. Digər sorğular düzgün işləyə bilər;
- XƏBƏRDARLIQ: Xəbərdarlığı ehtiva edən qeydləri göstərir. Gözlənilməz hərəkət baş verdi, buna baxmayaraq sistem müqavimət göstərdi və sorğunu tamamladı;
- MƏLUMAT: proqramda vacib hərəkətləri qeyd edən jurnal. Bunlar səhvlər deyil, xəbərdarlıqlar deyil, sistemin gözlənilən hərəkətləridir;
- DEBUG: proqramın sazlanması üçün lazım olan qeydlər. Sistemin tam olaraq ondan gözlənilənləri yerinə yetirməsini təmin etmək və ya sistemin hərəkətini təsvir etmək üçün: “metod1 işə başladı”;
- TRACE: ən aşağı giriş səviyyəsi ilə sazlama üçün daha aşağı prioritet qeydlər;
- ALL: sistemdən bütün qeydlərin qeydə alınacağı səviyyə.
Belə çıxır ki, INFO qeyd səviyyəsi tətbiqin hansısa yerində aktivləşdirilibsə, INFO-dan başlayaraq FATAL-a qədər bütün səviyyələr qeyd olunacaq. Qeydiyyat səviyyəsi FATAL olarsa, yalnız bu səviyyəli qeydlər qeydə alınacaq.
Qeydlərin yazılması və göndərilməsi: Əlavə
Biz bu prosesi log4j nümunəsi kimi nəzərdən keçirəcəyik: o, qeydləri qeyd etmək/göndərmək üçün geniş imkanlar təqdim edir:
- fayla yazmaq üçün - DailyRollingFileAppender həlli ;
- proqram konsoluna məlumat qəbul etmək - ConsoleAppender ;
- verilənlər bazasına logları yazmaq üçün - JDBCAppender ;
- TCP/IP vasitəsilə ötürülməyə nəzarət etmək - TelnetAppender ;
- girişin performansa təsir etməməsini təmin etmək üçün - AsyncAppender .
Bir neçə başqa tətbiq var: tam siyahı ilə
burada tanış ola bilərsiniz . Yeri gəlmişkən, tələb olunan əlavə mövcud deyilsə, bu problem deyil. Siz sadəcə log4j qəbul edən
Appender interfeysini tətbiq etməklə öz əlavənizi yaza bilərsiniz .
Giriş qovşaqları
Nümayiş üçün biz slf4j interfeysindən və log4j-dən tətbiqdən istifadə edəcəyik.
MainDemo
Bir logger yaratmaq çox sadədir: girişin aparılacağı adlı sinifə aşağıdakıları yazmalısınız :
org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MainDemo.class);
Bu, bizim üçün logger yaradacaq. Gündəlik girişi etmək üçün qeydlərin hansı səviyyədə ediləcəyini göstərən bir çox üsuldan istifadə edə bilərsiniz. Misal üçün:
logger.trace("Method 1 started with argument={}", argument);
logger.debug("Database updated with script = {}", script);
logger.info("Application has started on port = {}", port);
logger.warn("Log4j didn't find log4j.properties. Please, provide them");
logger.error("Connection refused to host = {}", host);
Sinif keçsək də, sonda paketlərlə birlikdə sinfin tam adı yazılır. Bu, girişi qovşaqlara bölmək və hər bir qovşaq üçün giriş səviyyəsini və əlavəni konfiqurasiya etmək üçün edilir. Məsələn, sinfin adı:
com.github.romankh3.logginglecture.MainDemo
- orada logger yaradılmışdır. Və beləliklə onu giriş qovşaqlarına bölmək olar. Əsas node null
RootLogger- dir . Bu, bütün tətbiqin bütün qeydlərini qəbul edən qovşaqdır. Qalanları aşağıda göstərildiyi kimi təsvir etmək olar:
Əlavələr öz işlərini xüsusi olaraq giriş qovşaqlarında konfiqurasiya edirlər.
İndi log4j.properties-dən nümunə kimi istifadə edərək , onları necə konfiqurasiya edəcəyimizə baxacağıq.
Log4j.properties-in addım-addım qurulması
İndi hər şeyi addım-addım quracağıq və nə edilə biləcəyini görəcəyik:
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
Bu sətir deyir ki, biz org.apache.log4j.ConsoleAppender tətbiqindən istifadə edən CONSOLE əlavəsini qeydiyyatdan keçiririk. Bu əlavə məlumatı konsola yazır. Sonra, fayla yazacaq başqa bir əlavəni qeyd edək:
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
Əlavələrin hələ də konfiqurasiya edilməli olduğunu qeyd etmək vacibdir. Biz artıq qeydiyyatdan keçmiş əlavələri əldə etdikdən sonra qovşaqlarda hansı səviyyədə qeyd olunacağını və hansı əlavələrin istifadə olunacağını müəyyən edə bilərik.
log4j.rootLogger=DEBUG, KONSOLU, FAYL
- log4j.rootLogger o deməkdir ki, biz bütün qeydləri ehtiva edən əsas nodu konfiqurasiya edəcəyik;
- bərabər işarədən sonra ilk söz qeydlərin hansı səviyyədə və daha yüksək səviyyədə qeyd olunacağını göstərir (bizim vəziyyətimizdə bu DEBUG);
- sonra vergüldən sonra istifadə ediləcək bütün əlavələr göstərilir.
Müəyyən bir giriş nodeunu konfiqurasiya etmək üçün aşağıdakı girişdən istifadə etməlisiniz:
log4j.logger.com.github.romankh3.logginglecture=TRACE, OWN, CONSOLE
müəyyən bir nodu konfiqurasiya etmək üçün istifadə edildiyi yer
log4j.logger.
, bizim vəziyyətimizdə belədir
com.github.romankh3.logginglecture.
Və indi CONSOLE əlavəsini qurmaq haqqında danışaq:
# CONSOLE appender customisation
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] : %c:%L : %m%n
Burada biz əlavənin işləyəcəyi səviyyəni təyin edə biləcəyimizi görürük. Həqiqi vəziyyət: məlumat səviyyəsi ilə mesaj giriş qovşağı tərəfindən qəbul edildi və ona təyin edilmiş əlavəyə ötürüldü, lakin xəbərdarlıq səviyyəsi və daha yüksək olan əlavə bu jurnalı qəbul etdi, lakin bununla heç nə etmədi. Sonra, mesajda hansı şablonun olacağına qərar verməlisiniz. Mən nümunədə PatternLayout istifadə edirəm, lakin orada bir çox həll yolu var. Bu məqalədə onlar açıqlanmayacaq. FILE əlavəsinin qurulmasına bir nümunə:
# File appender customisation
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=./target/logging/logging.log
log4j.appender.FILE.MaxFileSize=1MB
log4j.appender.FILE.threshold=DEBUG
log4j.appender.FILE.MaxBackupIndex=2
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[ %-5p] - %c:%L - %m%n
Buradan göründüyü kimi qeydlərin hansı fayla yazılacağını konfiqurasiya edə bilərsiniz
log4j.appender.FILE.File=./target/logging/logging.log
Qeyd fayla gedir
logging.log
. Fayl ölçüsü ilə bağlı problemlərin qarşısını almaq üçün maksimumu təyin edə bilərsiniz: bu halda, 1MB. MaxBackupIndex - neçə belə faylın olacağını bildirir. Bu nömrədən çox yaradılarsa, ilk fayl silinəcək.
Girişin konfiqurasiya edildiyi real nümunəyə baxmaq üçün GitHub-da açıq depoya keçə bilərsiniz .
Nəticəni birləşdirək
Özünüz təsvir olunan hər şeyi etməyə çalışın:
- Yuxarıdakı nümunədə olduğu kimi öz layihənizi yaradın.
- Maven-dən istifadə haqqında məlumatınız varsa, biz ondan istifadə edəcəyik; əgər yoxsa, kitabxananı necə birləşdirəcəyini təsvir edən məqaləyə keçid buradadır .
Gəlin ümumiləşdirək
- Java-da hansı həllərin olduğunu danışdıq.
- Demək olar ki, məlum olan bütün giriş kitabxanaları bir nəfərin nəzarəti altında yazılıb :D
- Nəyin qeyd edilməli olduğunu və nəyin olmadığını öyrəndik.
- Giriş səviyyələrini müəyyənləşdirdik.
- Biz logging qovşaqları ilə tanış olduq.
- Əlavənin nə olduğuna və nə üçün olduğuna baxdıq.
- Biz log4j.proterties faylını addım-addım konfiqurasiya etdik.
Əlavə materiallar
- JavaRush: Giriş. Bir stectrace topunu açın
- JavaRush: Logger mühazirəsi
- Habr: Java girişi. Salam dünya
- Habr: Java logging: kabusun hekayəsi
- Youtube: Golovach kursları. Giriş. 1-ci hissə , 2-ci hissə , 3-cü hissə , 4-cü hissə
- Log4j: əlavə
- Log4j: tərtibat
Digər məqalələrimə də baxın:
GO TO FULL VERSION