2.1 Unang logger - log4j

Tulad ng alam mo na, ang kasaysayan ng mga log ay nagsimula sa System.err.println()output ng isang tala sa console. Aktibo pa rin itong ginagamit para sa pag-debug, halimbawa, ginagamit ito ng Intellij IDEA upang magpakita ng mga mensahe ng error sa console. Ngunit ang pagpipiliang ito ay walang anumang mga setting, kaya magpatuloy tayo.

Ang una at pinakasikat na logger ay tinawag na Log4j. Ito ay isang mahusay at lubos na nako-customize na solusyon. Dahil sa iba't ibang mga pangyayari, ang desisyong ito ay hindi kailanman napunta sa JDK, na labis na ikinagalit ng buong komunidad.

Ang logger na ito ay hindi lamang nakapag-log, ito ay nilikha ng mga programmer para sa mga programmer at pinahintulutan silang malutas ang mga problema na patuloy na lumitaw na may kaugnayan sa pag-log.

Tulad ng alam mo na, ang mga log ay isinulat sa dulo upang mabasa ito ng ilang tao at subukang maunawaan kung ano ang nangyari sa panahon ng pagpapatakbo ng programa - kung ano at kailan nagkamali gaya ng inaasahan.

Mayroong log4jtatlong bagay para dito:

  • subpackage logging;
  • hanay ng mga appenders (mga resulta);
  • mga setting ng mainit na pag-reload.

Una, ang mga setting log4jay maaaring isulat sa paraang paganahin ang pag-log in sa isang pakete at huwag paganahin ito sa isa pa. Halimbawa, posibleng paganahin ang pag-log in sa com.codegym.server, ngunit huwag paganahin ito sa com.codegym.server.payment. Ginawa nitong posible na mabilis na alisin ang hindi kinakailangang impormasyon mula sa log.

Pangalawa, log4jpinayagan nito ang pagsulat ng mga resulta ng pag-log sa ilang mga file ng log nang sabay-sabay. At ang output sa bawat isa ay maaaring i-configure nang isa-isa. Halimbawa, sa isang file posible na magsulat lamang ng impormasyon tungkol sa mga malubhang error, sa isa pa - mga log mula sa isang tiyak na module, at sa isang pangatlo - mga log para sa isang tiyak na oras.

Ang bawat log file ay kaya nakatutok sa isang partikular na uri ng inaasahang problema. Lubos nitong pinapasimple ang buhay ng mga programmer na hindi nasisiyahan sa pagtingin sa mga gigabyte log file nang manu-mano.

At sa wakas, pangatlo, log4jpinahintulutan nitong baguhin ang mga setting ng log nang direkta habang tumatakbo ang programa, nang hindi ito nire-restart. Ito ay napaka-madaling gamitin kapag ito ay kinakailangan upang itama ang gawain ng mga log upang makahanap ng karagdagang impormasyon sa isang partikular na error.

Mahalaga! Mayroong dalawang bersyon ng log log4j: 1.2.x at 2.xx , na hindi tugma sa isa't isa .

Maaari mong ikonekta ang logger sa proyekto gamit ang code:

<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 Unang opisyal na logger - JUL: java.util.logging

Matapos lumitaw ang zoo ng mga logger sa komunidad ng Java, JDKnagpasya ang mga developer na gumawa ng isang karaniwang logger na gagamitin ng lahat. Ito ay kung paano lumitaw ang logger JUL: package java.util.logging.

Gayunpaman, sa panahon ng pag-unlad nito, kinuha ng mga tagalikha ng logger bilang batayan hindi log4j, ngunit isang variant ng logger mula sa IBM, na nakaimpluwensya sa pag-unlad nito. Ang magandang balita ay JULkasama ang logger JDK, ang masamang balita ay kakaunti ang gumagamit nito.

JUL

Hindi lamang JULgumawa ang mga developer ng "isa pang unibersal na pamantayan" , gumawa din sila ng kanilang sariling mga antas ng pag-log para dito, na naiiba sa mga tinanggap ng mga sikat na logger noong panahong iyon.

At iyon ay isang malaking problema. Pagkatapos ng lahat, ang mga produkto ay Javamadalas na kinokolekta mula sa isang malaking bilang ng mga aklatan, at ang bawat nasabing aklatan ay may sariling logger. Kaya kinailangan na i-configure ang lahat ng mga logger na nasa application.

Kahit na ang logger mismo ay medyo maganda. Ang paggawa ng isang logger ay halos pareho. Upang gawin ito, kailangan mong mag-import:


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

Espesyal na ipinapasa ang pangalan ng klase upang malaman kung saan nanggagaling ang pag-log.

Sa pamamagitan lamang ng paglabas, nalutas ng mga developer ang mahahalagang problema, pagkatapos nito JULay talagang maginhawang gamitin. Bago iyon, ito ay isang uri ng pangalawang-rate na logger.

Sinusuportahan din ng logger na ito ang mga expression ng lambda at tamad na pagsusuri. Simula sa Java 8, makakapasa ka Supplier<String>. Nakakatulong ito na magbasa at lumikha ng isang string sa sandaling ito ay talagang kailangan, at hindi sa lahat ng oras, tulad ng dati.

Ang mga pamamaraan na may argumento Supplier<String> msgSupplieray ganito ang hitsura:

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

2.3 Unang logger wrapper - JCL: jakarta commons logging

Sa loob ng mahabang panahon walang iisang pamantayan sa mga magtotroso, JULdapat ay naging isa ito, ngunit ito ay mas masahol pa log4j, kaya hindi lumitaw ang isang solong pamantayan. Ngunit lumitaw ang isang buong zoo ng mga magtotroso, bawat isa ay gustong maging pareho.

JCL

Gayunpaman, hindi nagustuhan ng mga ordinaryong developer ng Java na halos bawat library ay may sariling logger at kailangang i-configure kahit papaano sa isang espesyal na paraan. Samakatuwid, nagpasya ang komunidad na lumikha ng isang espesyal na wrapper sa iba pang mga magtotroso - ito ay kung paanoJCL: jakarta commons logging

At muli, ang proyekto, na nilikha upang maging isang pinuno, ay hindi naging isa. Hindi ka makakagawa ng panalo, maaari ka lang maging panalo. JCLNapakahina ng functionality at walang gustong gumamit nito. Ang logger, na idinisenyo upang palitan ang lahat ng mga logger, ay nakatagpo ng parehong kapalaran dahil JULhindi ito ginamit.

Kahit na ito ay naidagdag sa maraming mga aklatan na inilabas ng komunidad ng Apache, ang zoo ng mga magtotroso ay lumago lamang.

2.4 Unang huling logger - Logback

Ngunit hindi lang iyon. Nagpasya ang developer log4jna siya ang pinakamatalino (mabuti naman, karamihan sa mga tao ay gumamit ng kanyang logger) at nagpasya na magsulat ng bagong pinahusay na logger na magsasama-sama ng mga pakinabang log4jng iba pang mga logger.

Ang bagong logger ay tinawag na Logback. Ang logger na ito ang dapat na maging isang solong logger sa hinaharap na gagamitin ng lahat. Ito ay batay sa parehong ideya tulad ng sa log4j.

Maaari mong ikonekta ang logger na ito sa proyekto gamit ang code:

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

Ang mga pagkakaiba ay sa Logback:

  • pinahusay na pagganap;
  • nagdagdag ng katutubong suporta slf4j;
  • pinalawak na opsyon sa pag-filter.

Ang isa pang bentahe ng logger na ito ay mayroon itong napakahusay na default na mga setting. At kailangan mong i-configure ang logger kung gusto mong baguhin ang isang bagay sa kanila. Gayundin, ang file ng mga setting ay mas mahusay na inangkop sa corporate software - lahat ng mga configuration nito ay itinakda bilang xml/.

Bilang default, Logbackhindi ito nangangailangan ng anumang mga setting at itinatala ang lahat ng mga log mula sa antas DEBUGat mas mataas. Kung kailangan mo ng ibang pag-uugali, maaari itong i-configure sa pamamagitan ng xmlpagsasaayos:

<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 Pinakabagong unibersal na logger - SLF4J: Simple Logging Facade para sa Java

Gaano katagal upang mahanap ang gintong ibig sabihin...

Noong 2006, isa sa mga tagalikha log4jang umalis sa proyekto at nagpasyang subukang muli upang lumikha ng isang unibersal na logger. Ngunit sa pagkakataong ito ay hindi bagong logger, ngunit isang bagong unibersal na pamantayan (wrapper) na nagpapahintulot sa iba't ibang logger na makipag-ugnayan nang magkasama.

Ang magtotroso na ito ay tinatawag na slf4j — Simple Logging Facade for Java, ito ay isang balot sa paligid log4j, JUL, common-loggins and logback. Nalutas ng logger na ito ang isang tunay na problema - ang pamamahala sa isang zoo ng mga logger, kaya agad na nagsimulang gamitin ito ng lahat.

Bayani nating nilulutas ang mga problemang nilikha natin para sa ating sarili. Tulad ng nakikita mo, ang pag-unlad ay umabot sa punto na nakagawa kami ng isang wrapper sa ibabaw ng wrapper ...

Ang pambalot mismo ay binubuo ng dalawang bahagi:

  • API, na ginagamit sa mga aplikasyon;
  • Mga pagpapatupad na idinagdag bilang hiwalay na mga dependency para sa bawat logger.

Maaari mong ikonekta ang logger sa proyekto gamit ang code:

<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>

Ito ay sapat na upang ikonekta ang tamang pagpapatupad at iyon lang: ang buong proyekto ay gagana dito.

2.6 Pag-optimize sa slf4j

Slf4jsumusuporta sa lahat ng mga bagong tampok tulad ng pag-format ng string para sa pag-log . Bago ito may ganoong problema. Sabihin nating gusto mong mag-print ng mensahe sa log:

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

May problema sa code na ito. Ipagpalagay na ang iyong aplikasyon ay gumagana productionat hindi nagsusulat ng anuman sa log DEBUG-messages, gayunpaman, ang pamamaraan log.debug()ay tatawagin pa rin, at kapag ito ay tinawag, ang mga sumusunod na pamamaraan ay tatawagin din:

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

Ang pagtawag sa mga paraang ito ay nagpapabagal sa aplikasyon. Ang kanilang tawag ay kailangan lamang sa panahon ng pag-debug, ngunit sila ay tinatawag pa rin.

Mula sa punto ng view ng lohika, ang problemang ito ay kailangang malutas sa mismong logging library. At sa unang bersyon ng log4j ang solusyon ay dumating:

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

Sa halip na isang linya para sa log, ngayon ay kinakailangan na magsulat ng tatlo. Na higit na nagpalala sa pagiging madaling mabasa ng code, at nagpababa sa katanyagan ng log4j.

slf4jNagawa ng logger na bahagyang mapabuti ang sitwasyon sa pamamagitan ng pag-aalok ng matalinong pag-log. Ito ay mukhang ganito:

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

kung saan {}ipahiwatig ang pagpasok ng mga argumento na ipinasa sa pamamaraan. Ibig sabihin, ang una {}ay tumutugma sa user, ang pangalawa {}sa request.getRemoteAddr().

Ang mga parameter na ito ay pagsasama-samahin sa isang mensahe lamang kung ang antas ng pag-log ay nagpapahintulot sa pag-log. Hindi perpekto, ngunit mas mahusay kaysa sa lahat ng iba pang mga pagpipilian.

Pagkatapos nito, SLF4Jnagsimula itong lumago nang mabilis sa katanyagan, sa ngayon ito ang pinakamahusay na solusyon.

Samakatuwid, isasaalang-alang namin ang pag-log gamit ang halimbawa ng isang bundle slf4j-log4j12.