Java zapisivanje s ugniježđenim dijagnostičkim kontekstom (NDC)

1. Pregled

Ugnježđeni dijagnostički kontekst (NDC) mehanizam je koji pomaže u razlikovanju isprepletenih dnevničkih poruka iz različitih izvora. NDC to čini pružajući mogućnost dodavanja prepoznatljivih kontekstualnih informacija u svaki zapisnik.

U ovom ćemo članku istražiti upotrebu NDC-a i njegovu upotrebu / podršku u raznim Java sustavima zapisivanja.

2. Dijagnostički konteksti

U tipičnoj aplikaciji s više niti, poput web aplikacije ili REST API-ja, svaki zahtjev klijenta poslužuje druga nit. Evidencije generirane iz takve aplikacije sastojat će se od svih zahtjeva i izvora klijenta. To otežava bilo kakav poslovni smisao dnevnika ili otklanjanje pogrešaka.

Ugniježđeni dijagnostički kontekst (NDC) upravlja snopom kontekstualnih podataka, po osnovi niti. Podaci u NDC-u dostupni su za svaki zahtjev dnevnika u kodu i mogu se konfigurirati za prijavu sa svakom porukom dnevnika - čak i na mjestima gdje podaci nisu u opsegu. Ovi kontekstualni podaci u svakoj poruci dnevnika pomažu u razlikovanju dnevnika po izvoru i kontekstu.

Mapirani dijagnostički kontekst (MDC) također upravlja informacijama na osnovi niti, ali kao karta.

3. NDC stog u uzorku aplikacije

Da bismo demonstrirali upotrebu NDC stoga, uzmimo primjer REST API-ja koji novac šalje na investicijski račun.

Podaci potrebni za unos predstavljeni su u Ulaganje razred:

investicija javne klase {private StringactionId; privatni vlasnik niza; privatni Dugi iznos; javno ulaganje (StringactionId, Vlasnik niza, Dugi iznos) {this.transactionId =actionId; this.owner = vlasnik; this.amount = iznos; } // standardni getteri i postavljači}

Prijenos na račun ulaganja vrši se pomoću InvestmentService. Potpuni izvorni kod za ove klase može se naći u ovom github projektu.

U uzorku prijave podaci transactionId i vlasnik smješteni su u NDC stog, u nit koja obrađuje zadani zahtjev. Ti su podaci dostupni u svakoj poruci dnevnika u toj niti. Na taj se način može pratiti svaka jedinstvena transakcija i prepoznati relevantan kontekst svake poruke dnevnika.

4. NDC u Log4j

Log4j nudi klasu koja se zove NDC koji pruža statičke metode za upravljanje podacima u NDC stogu. Osnovna upotreba:

  • Kada unosite kontekst, upotrijebite NDC.push () za dodavanje podataka o kontekstu u trenutnu nit
  • Kada napuštate kontekst, upotrijebite NDC.pop () izvaditi podatke o kontekstu
  • Kada izlazite iz niti, nazovite NDC.remove () ukloniti dijagnostički kontekst niti i osigurati oslobađanje memorije (od Log4j 1.3, više nije potrebno)

U primjeru aplikacije upotrijebimo NDC za dodavanje / uklanjanje kontekstualnih podataka na relevantnim mjestima u kodu:

import org.apache.log4j.NDC; @RestController javna klasa Log4JController {@Autowired @Qualifier ("Log4JInvestmentService") private InvestmentService log4jBusinessService; @RequestMapping (value = "/ ndc / log4j", method = RequestMethod.POST) javni ResponseEntity postPayment (@RequestBody Investment investment) {NDC.push ("tx.id =" + investment.getTransactionId ()); NDC.push ("tx.owner =" + investment.getOwner ()); log4jBusinessService.transfer (investment.getAmount ()); NDC.pop (); NDC.pop (); NDC.remove (); vratiti novi ResponseEntity (ulaganje, HttpStatus.OK); }}

Sadržaj NDC-a može se prikazati u dnevničkim porukama pomoću %x opcija u ConversionPattern koristi se dodavačem u log4j.svojstva:

log4j.appender.consoleAppender.layout.ConversionPattern =% -4r [% t]% 5p% c {1} -% m - [% x]% n

Postavimo REST API u tomcat. Zahtjev za uzorak:

POST / logging-service / ndc / log4j {"actionId ":" 4 "," owner ":" Marc "," amount ": 2000}

Informacije o dijagnostičkom kontekstu možemo vidjeti u izlazu dnevnika:

48569 [http-nio-8080-exec-3] INFO Log4JInvestmentService - Priprema za prijenos 2000 $. - [tx.id = 4 tx.owner = Marc] 49231 [http-nio-8080-exec-4] INFO Log4JInvestmentService - Priprema za prijenos 1500 $. - [tx.id = 6 tx.owner = Samantha] 49334 [http-nio-8080-exec-3] INFO Log4JInvestmentService - Je li prijenos 2000 $ uspješno dovršen? pravi. - [tx.id = 4 tx.owner = Marc] 50023 [http-nio-8080-exec-4] INFO Log4JInvestmentService - Je li prijenos od 1500 $ uspješno dovršen? pravi. - [tx.id = 6 tx.owner = Samantha] ...

5. NDC u Log4j 2

NDC u Log4j 2 naziva se skupom konteksta niti:

import org.apache.logging.log4j.ThreadContext; @RestController javna klasa Log4J2Controller {@Autowired @Qualifier ("Log4J2InvestmentService") private InvestmentService log4j2BusinessService; @RequestMapping (value = "/ ndc / log4j2", method = RequestMethod.POST) javni ResponseEntity postPayment (@RequestBody investicija ulaganja) {ThreadContext.push ("tx.id =" + investment.getTransactionId ()); ThreadContext.push ("tx.owner =" + investment.getOwner ()); log4j2BusinessService.transfer (investment.getAmount ()); ThreadContext.pop (); ThreadContext.pop (); ThreadContext.clearAll (); vratiti novi ResponseEntity (ulaganje, HttpStatus.OK); }}

Kao i kod Log4j, upotrijebimo %x opcija u konfiguracijskoj datoteci Log4j 2 log4j2.xml:

Izlaz iz dnevnika:

204724 [http-nio-8080-exec-1] INFO Log4J2InvestmentService - Priprema za prijenos 1500 $. - [tx.id = 6, tx.owner = Samantha] 205455 [http-nio-8080-exec-2] INFO Log4J2InvestmentService - Priprema za prijenos 2000 $. - [tx.id = 4, tx.owner = Marc] 205525 [http-nio-8080-exec-1] INFO Log4J2InvestmentService - Je li prijenos od 1500 dolara uspješno dovršen? lažno. - [tx.id = 6, tx.owner = Samantha] 206064 [http-nio-8080-exec-2] INFO Log4J2InvestmentService - Je li prijenos od 2000 $ uspješno dovršen? pravi. - [tx.id = 4, tx.owner = Marc] ...

6. NDC u prijavljivanju fasada (JBoss Logging)

Fasade za bilježenje poput SLF4J pružaju integraciju s različitim okvirima za bilježenje. NDC nije podržan u SLF4J (ali je uključen u slf4j-ext modul). JBoss Logging je most za sječu, baš kao i SLF4J. NDC je podržan u JBoss Loggingu.

Prema zadanim postavkama, JBoss Logging pretražuje ClassLoader za dostupnost back-endova / davatelja u sljedećem redoslijedu prioriteta: JBoss LogManager, Log4j 2, Log4j, SLF4J i JDK Logging.

JBoss LogManager kao pružatelj usluge bilježenja obično se koristi unutar poslužitelja aplikacija WildFly. U našem slučaju, most za bilježenje JBoss odabrat će sljedeći po redu prioriteta (a to je Log4j 2) kao davatelja usluge bilježenja.

Započnimo dodavanjem potrebne ovisnosti u pom.xml:

 org.jboss.logging jboss-logging 3.3.0.Final 

Najnoviju verziju ovisnosti možete provjeriti ovdje.

Dodajmo kontekstualne informacije u NDC stog:

import org.jboss.logging.NDC; @RestController javna klasa JBossLoggingController {@Autowired @Qualifier ("JBossLoggingInvestmentService") private InvestmentService jbossLoggingBusinessService; @RequestMapping (value = "/ ndc / jboss-logging", method = RequestMethod.POST) javni ResponseEntity postPayment (@RequestBody Investment investment) {NDC.push ("tx.id =" + investment.getTransactionId ()); NDC.push ("tx.owner =" + investment.getOwner ()); jbossLoggingBusinessService.transfer (investment.getAmount ()); NDC.pop (); NDC.pop (); NDC.clear (); vratiti novi ResponseEntity (ulaganje, HttpStatus.OK); }}

Izlaz iz dnevnika:

17045 [http-nio-8080-exec-1] INFO JBossLoggingInvestmentService - Priprema za prijenos 1.500 $. - [tx.id = 6, tx.owner = Samantha] 17725 [http-nio-8080-exec-1] INFO JBossLoggingInvestmentService - Je li prijenos od 1500 $ uspješno dovršen? pravi. - [tx.id = 6, tx.owner = Samantha] 18257 [http-nio-8080-exec-2] INFO JBossLoggingInvestmentService - Priprema za prijenos 2.000 $. - [tx.id = 4, tx.owner = Marc] 18904 [http-nio-8080-exec-2] INFO JBossLoggingInvestmentService - Je li prijenos od 2000 $ uspješno dovršen? pravi. - [tx.id = 4, tx.owner = Marc] ...

7. Zaključak

Vidjeli smo kako dijagnostički kontekst pomaže u značajnoj korelaciji dnevnika - s poslovnog stajališta, kao i za uklanjanje pogrešaka. To je neprocjenjiva tehnika za obogaćivanje bilježenja, posebno u višenitnim aplikacijama.

Primjer korišten u ovom članku nalazi se u projektu Github.