"Åh, der er du! Har du husket, at vi har endnu en lektion i dag?"

"Nej, jeg ledte bare efter dig. Næsten..."

"Fremragende, så lad os starte. I dag vil jeg fortælle dig om logning."

"Loggen er en liste over de hændelser, der er sket. Næsten som en skibslog eller en dagbog. Eller Twitter - måske kan du bedre relatere til det. Ikke overraskende er en logger et objekt, du bruger til logning."

"I programmering er det kutyme at logge næsten alt. Og i Java logger vi alt og endda lidt mere."

"Faktum er, at Java-programmer meget ofte er store serverapplikationer uden UI, konsol osv. De behandler tusindvis af brugerforespørgsler på samme tid, og der er ofte forskellige fejl. Især når forskellige tråde begynder at forstyrre hinanden."

"Faktisk er den eneste måde at søge efter sjældent reproducerbare fejl og fejl under disse omstændigheder ved at logge alt, hvad der sker på hver tråd."

"Oftest indeholder loggen information om metodeargumenter, eventuelle fangede fejl og en masse mellemliggende information."

"Jo mere komplet loggen er, jo nemmere er det at gengive en sekvens af hændelser og spore årsagerne til fejl eller fejl."

"Nogle gange når logfiler flere gigabyte pr. dag. Dette er normalt."

"Et par gigabyte? O_o"

"Jep. Oftest bliver logfiler automatisk arkiveret med angivelse af den relevante dato."

"Hov."

"Uh-huh. I starten havde Java ikke sin egen logger. Som et resultat blev der skrevet flere uafhængige loggere. Den mest almindelige af disse var log4j."

"Nogle år senere fik Java en egen logger, men dens funktionalitet var langt ringere, og den blev ikke udbredt."

"Det er et faktum, at Java har en officiel logger, men hele samfundet af Java-programmører foretrækker at bruge andre loggere. "

"Senere blev der skrevet flere loggere baseret på log4j."

"Så blev den specielle universelle logger slf4j, som nu er meget brugt, skrevet til dem alle. Den minder meget om log4j, så jeg vil bruge den som eksempel, når jeg skal forklare logning."

"Hele logningsprocessen består af tre dele."

" Først skal du indsamle oplysninger."

" For det andet , filtrer de indsamlede oplysninger."

" For det tredje , optag de valgte oplysninger."

"Lad os starte med indsamling. Her er et typisk eksempel på en klasse, der logger:"

Klasse med logning
class Manager
{
 private static final Logger logger = LoggerFactory.getLogger(Manager.class);

 public boolean processTask(Task task)
 {
  logger.debug("processTask id = " + task.getId());
  try
  {
   task.start();
   task.progress();
   task.complete();
   return true;
  }
  catch(Exception e)
  {
   logger.error("Unknown error", e);
   return false;
  }
 }
}

"Vær opmærksom på ordene fremhævet med rødt."

" Linje 3  – Opret logger- objektet. Sådan et statisk objekt oprettes i næsten hver klasse! Nå, bortset fra klasser, der ikke gør andet end at gemme data."

" LoggerFactory er en speciel klasse til oprettelse af loggere, og getLogger er en af ​​dens statiske metoder. Det aktuelle objekt er normalt bestået, men forskellige muligheder er mulige."

" Linje 7 – Information om metodekaldet skrives til loggeren. Bemærk, at dette er metodens første linje. Så snart metoden kaldes, skriver vi straks information til loggen."

"Vi kalder debug-metoden, hvilket betyder, at informationens betydning er DEBUG-niveau. Dette bruges til filtrering. Jeg fortæller dig om det om et par minutter."

" Linje 17 – Vi fanger en undtagelse og... skriver den straks til loggen! Det er præcis, hvad der skal gøres."

"Denne gang kalder vi fejlmetoden, som umiddelbart indikerer, at informationen er på ERROR-niveau"

Logger - 1

"Alt ser ud til at være klart for nu. Nå, så vidt det kan stå klart midt i vores samtale."

"Godt, så lad os gå videre til beskedfiltrering."

"Normalt har hver logmeddelelse sit eget vigtighedsniveau, som du kan bruge til at kassere nogle af beskederne. Her er vigtighedsniveauer, jeg nævnte:"

Betydningsniveau Beskrivelse
ALLE Alle beskeder
SPOR Finkornede fejlretningsmeddelelser
FEJLFINDE Vigtige fejlretningsmeddelelser
INFO Informationsmeddelelser
ADVARE Advarsler
FEJL Fejl
FATAL Fatale fejl
AF Ingen beskeder

Disse niveauer bruges også ved filtrering af beskeder.

Antag, at du indstiller logningsniveauet til WARN. Så vil alle beskeder, der er mindre vigtige end WARN, blive kasseret: TRACE, DEBUG, INFO.

Hvis du indstiller filtreringsniveauet til FATAL, vil selv ERROR-meddelelser blive kasseret.

"Der er to vigtige niveauer, der bruges ved filtrering: FRA, som kasserer alle meddelelser; og ALLE, som viser alle meddelelser (intet kasseres)."

"Hvordan og hvor konfigurerer jeg filtrering?"

"Jeg fortæller dig det uden videre."

"Sædvanligvis er log4j logger indstillinger angivet i log4j.properties filen."

Du kan angive flere vedhæftede objekter i denne fil. Data skrives til disse objekter. Der er datakilder, og der er appenders - objekter, der har modsatte formål. Objekter, som data flyder ind i som vand.

"Her er nogle eksempler:"

Logger til konsollen
# Root logger option
log4j.rootLogger = INFO, stdout

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

Linje 1 og 4 – Dette er kommentarer

Linje 2 – Vi angiver det logningsniveau, vi ønsker. Alle mindre vigtige niveauer (DEBUG, TRACE) vil blive kasseret.

Samme sted tilføjer vi et komma og angiver så navnet på det objekt (som vi selv finder på), som loggen vil blive skrevet til. Linje 5-9 indeholder dens indstillinger.

Linje 5 – Vi angiver typen af ​​appender ( ConsoleAppender ).

Linje 6 – Vi angiver præcis, hvor vi skriver ( System.out. ).

Linje 7 – Vi sætter den klasse, der skal administrere konverteringsmønstre (PatternLayout).

Linje 8 – Vi sætter det konverteringsmønster, der skal bruges til at skrive. I eksemplet ovenfor er det dato og klokkeslæt.

"Og sådan ser det ud at skrive til en fil:"

Logger til en fil
# Root logger option
log4j.rootLogger = INFO, file

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

"Linje 2 indstiller meddelelsesfiltreringsniveauet og navnet på appenderingsobjektet (sink)."

"Linje 5 – Vi angiver filtilføjelsestypen ( RollingFileAppender )."

"Linje 6 – Vi angiver navnet på den fil, som loggen vil blive skrevet til."

"Linje 7 – Vi angiver den maksimale logstørrelse. Når denne størrelsesgrænse overskrides, oprettes en ny fil."

"Linje 8 – Vi angiver antallet af gamle logfiler, der skal gemmes."

"Linje 9-10 – Indstil konverteringsmønsteret."

"Jeg ved ikke, hvad der sker her, men jeg kan gætte det. Det er opmuntrende."

"Det er fantastisk. Så er her et eksempel på, hvordan man skriver en log til en fil og konsollen:"

Logger til konsollen og en fil
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

"Ah, så du kan gøre det? Det er fantastisk!"

"Jep. Du kan deklarere så mange bilag, du vil, og tilpasse hver enkelt."

Desuden kan hver appender have meget fleksible indstillinger for meddelelsesfiltrering. Ikke kun kan vi tildele et individuelt meddelelsesfiltreringsniveau til hver vedhæfter, men vi kan også filtrere meddelelser efter pakke! Det er derfor, du skal angive en klasse, når du opretter en logger (jeg taler om LoggerFactory.getLogger ).

"For eksempel:"

Logger til konsollen og en fil
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.threshold = DEBUG
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold = ERROR
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

log4j.logger.org.springframework = ERROR
log4j.logger.org.hibernate = ERROR
log4j.logger.com.codegym = DEBUG
log4j.logger.org.apache.cxf = ERROR

"Linje 6 og 15 – Vi indstiller vores eget filtreringsniveau for hver appender."

"Linje 20-23 – Vi specificerer pakkenavnet og filtreringsniveauet for dets meddelelser. Log4j.logger er et præfiks: pakkenavnet er fremhævet med orange."

"Virkelig? Du kan endda gøre det. Nå, fedt!"

"I øvrigt er hverken log4j eller slf4j inkluderet i JDK. Du skal downloade dem separat. Det kan du gøre her . Men der er en anden måde:"

" Trin 1. Tilføj importer til klassen:"

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

" Trin 2. Sæt markøren på disse linjer og tryk Alt+Enter i IntelliJ IDEA"

" Trin 3. Vælg menupunktet 'Fil jar on web».'

" Trin 4. Vælg 'slf4j-log4j13.jar'"

" Trin 5. Angiv, hvor biblioteket (jar) skal downloades"

" Trin 6. Brug de klasser, du har brug for."

"Wow! Hvilken dag det har været. Så meget, der er nyt, og så meget, der er fedt!"

"Her er en anden god artikel om logning: https://docs.oracle.com/javase/10/core/java-logging-overview.htm#JSCOR-GUID-48004124-2C00-49F7-A640-0C0DDA271DBC "

"Okay, det er nok. Slap af, programmør."