CodeGym /Java blogg /Slumpmässig /Java-loggning
John Squirrels
Nivå
San Francisco

Java-loggning

Publicerad i gruppen
Hej! När jag skriver lektionerna betonar jag särskilt om det finns ett specifikt ämne som kommer att vara absolut nödvändigt i verkligt arbete. Så, LYSSNA! Ämnet vi kommer att ta upp idag kommer definitivt att komma väl till pass i alla dina projekt från dag ett av anställningen. Vi ska prata om Java-loggning. Det här ämnet är inte alls komplicerat (jag skulle till och med säga lätt). Men du kommer att ha tillräckligt med uppenbara saker att stressa över på ditt första jobb, så det är bättre att förstå det ordentligt nu :) Nåväl, låt oss börja.

Vad är inloggning i Java?

Loggning är handlingen att registrera data om hur ett program fungerar. Platsen där vi registrerar denna data kallas en "logg". Två frågor uppstår omedelbart: vilken data skrivs och var? Låt oss börja med "var". Du kan skriva data om ett programs arbete på många olika ställen. Till exempel, under dina studier, du ofta System.out.println()för att mata ut data till konsolen. Detta är verkligen loggning, om än i sin enklaste form. Naturligtvis är detta inte särskilt bekvämt för användare eller ett produktsupportteam: uppenbarligen kommer de inte att vilja installera en IDE och övervaka konsolen :) Det finns ett mer vanligt format för att spela in information: textfiler. Människor är mycket mer bekväma med att läsa data i detta format, och det är verkligen mycket bekvämare att lagra data! Nu den andra frågan: vilka programdata ska loggas? Det är helt upp till dig! Javas loggningssystem är mycket flexibelt. Du kan konfigurera den för att logga allt som ditt program gör. Å ena sidan är det här bra. Men å andra sidan, föreställ dig hur stora Facebooks eller Twitters loggar skulle vara om de skrev allt i dem. Dessa stora företag har förmodligen förmågan att lagra så mycket data. Men tänk hur svårt det skulle vara att hitta information om ett kritiskt fel i 500 gigabyte textloggar? Det vore värre än att leta efter en nål i en höstack. Följaktligen kan Java konfigureras för att endast logga feldata. Eller till och med bara kritiska fel! Som sagt, det är inte helt korrekt att tala om Javas inbyggda loggningssystem. Faktum är att programmerare behövde logga innan denna funktionalitet lades till språket. När Java introducerade sitt eget loggningsbibliotek använde alla redan log4j-biblioteket. Historien om att logga i Java är faktiskt väldigt lång och informativ. Kort sagt, Java har ett eget loggningsbibliotek, men nästan ingen använder det :) Senare, när flera olika loggningsbibliotek dök upp och började användas av programmerare uppstod kompatibilitetsproblem. För att hindra människor från att återuppfinna hjulet i ett dussin olika bibliotek med olika gränssnitt skapades det abstrakta SLF4J-ramverket ("Service Logging Facade For Java"). Det kallas abstrakt, för även om du använder och anropar metoderna för SLF4J-klasser, använder de under huven faktiskt alla loggningsramverk som kom innan: log4j, standarden java.util.logging och andra. Om du någon gång behöver någon specifik funktion hos Log4j som saknas i andra bibliotek, men du inte vill länka ditt projekt direkt till detta bibliotek, använd bara SLF4J. Och låt det sedan anropa Log4j-metoderna. Om du ändrar dig och bestämmer dig för att du inte längre behöver Log4j-funktioner behöver du bara konfigurera om "här , och Log4j - biblioteket här . Packa sedan upp arkivet och använd IntelliJ IDEA för att lägga till JAR-filerna till klasssökvägen. Menyalternativ: Arkiv -> Projektstruktur -> Bibliotek Välj de nödvändiga JAR-filerna och lägg till dem i projektet (arkiven vi laddade ner innehåller många JAR-filer — titta på bilderna för att se de du behöver) Observera att denna instruktion för de Varför vi behöver logga - 2Varför vi behöver logga - 3eleverna som inte vet hur man använder Maven. Om du vet hur man använder Maven är det oftast bättre (mycket enklare) att försöka börja där. Om du använder Maven , lägg till detta beroende:

    	<dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.14.0</version>
    	</dependency>
Bra! Vi kom på inställningarna :) Låt oss se hur SLF4J fungerar. Hur ser vi till att programmets arbete spelas in någonstans? För att göra detta behöver vi två saker: logger och appender. Låt oss börja med den första. En logger är ett objekt som ger full kontroll över loggning. Att skapa en logger är väldigt enkelt: vi gör detta med de statiska LoggerFactory.getLogger()- metoderna. Metodparametern är den klass vars operation kommer att loggas. Låt oss köra vår kod:

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

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("Test log entry!!!");
       LOGGER.error("An error occurred!");
   }
}
Konsolutgång:

ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2 15:49:08.907 [main] ERROR MyTestClass - An error occurred!
Vad ser vi här? Först ser vi ett felmeddelande. Detta är ett resultat av att vi nu saknar nödvändiga inställningar. Följaktligen kan vår logger för närvarande bara skicka ut felmeddelanden (ERROR) och endast till konsolen. Metoden logger.info () fungerade inte. Men logger.error() gjorde det! På konsolen ser vi det aktuella datumet, metoden där felet uppstod ( main), ordet "FEL" och vårt meddelande! ERROR är loggningsnivån. I allmänhet, om en loggpost är markerad med ordet "ERROR", har ett fel inträffat vid denna tidpunkt i programmet. Om posten är markerad med ordet "INFO", representerar meddelandet helt enkelt aktuell information om programmets normala funktion. SLF4J-biblioteket har många olika loggningsnivåer som låter dig konfigurera loggning flexibelt. Det hela är väldigt enkelt att hantera: all nödvändig logik finns redan i Java Logger -klassen. Du behöver bara ringa de relevanta metoderna. Om du vill logga ett rutinmeddelande, anropar du metoden logger.info() . För ett felmeddelande, använd logger.error() . För en varning, använd logger.warn()

Låt oss nu prata om appender

En appender är platsen dit din data går. På sätt och vis motsatsen till en datakälla, alltså "punkt B". Som standard matas data ut till konsolen. Observera att i det föregående exemplet behövde vi inte konfigurera någonting: texten dök upp i konsolen, och Log4j-bibliotekets logger kan bara skicka meddelanden på ERROR-nivå till konsolen. Uppenbarligen är det bekvämare för människor att läsa och skriva loggar i en textfil. För att ändra loggerens standardbeteende måste vi konfigurera vår filtillägg. För att komma igång måste du skapa en log4j.xml-fil direkt i src-mappen. Du är redan bekant med XML-formatet: vi hade nyligen en lektion om det :) Här är innehållet i filen:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
   <Appenders>
       <File name="MyFileAppender" fileName="C:\Users\Username\Desktop\testlog.txt" immediateFlush="false" append="false">
           <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
       </File>
   </Appenders>
   <Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
   </Loggers>
</Configuration>
Inget speciellt speciellt eller svårt här :) Men låt oss ändå gå igenom innehållet.
<Configuration status="INFO">
Detta är den så kallade StatusLogger. Den är inte relaterad till vår logger och används i Log4js interna processer. Om du ställer in status="TRACE" istället för status="INFO", så kommer all information om Log4j:s interna arbete att visas på konsolen (StatusLogger visar data på konsolen, även om vår appender är en fil). Vi behöver det inte nu, så låt oss lämna det som det är.

<Appenders>
   <File name="MyFileAppender" fileName="C:\Users\Evgeny\Desktop\testlog.txt" append="true">
       <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
   </File>
</Appenders>
Här skapar vi vår appender. Taggen <File> indikerar att det kommer att vara en filtillägg. name="MyFileAppender" anger namnet på bilagan. fileName="C:\Users\Username\Desktop\testlog.txt" indikerar sökvägen till loggfilen där all data kommer att skrivas. append="true" anger om data ska skrivas i slutet av filen. I vårt fall är det precis vad vi kommer att göra. Om du ställer in värdet på false kommer det gamla innehållet i loggfilen att raderas varje gång programmet startas. <PatternLayout pattern="%d{ååå-MM-dd HH:mm:ss.SSS} [%t] %-5nivå %logger{36} - %msg%n"/>indikerar formateringsinställningarna. Här kan vi använda reguljära uttryck för att anpassa hur text formateras i vår logg.

<Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
</Loggers>
Här anger vi rotnivån. Vi har satt "INFO"-nivån, vilket innebär att alla meddelanden vars nivåer är högre än INFO (enligt tabellen som vi tittade på ovan) inte kommer att loggas. Vårt program kommer att ha 3 meddelanden: ett INFO, ett VARNING och ett FEL. Med den aktuella konfigurationen kommer alla 3 meddelanden att loggas. Om du ändrar rotnivån till ERROR, kommer endast det sista meddelandet från LOGGER.error() metodanropet att hamna i loggen. Dessutom finns en hänvisning till bilagan också här. För att skapa en sådan referens måste du skapa en <ApprenderRef> -tagg inuti <Root> -taggen och lägga till attributet ref='din appender's name' till den. Om du har glömt det är det här vi ställer in appendarens namn: <. Och här är vår kod!

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

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("The program is starting!!!");

       try {
           LOGGER.warn("Attention! The program is trying to divide a number by another.
           System.out.println(12/0);
       } catch (ArithmeticException x) {

           LOGGER.error("Error! Division by zero!");
       }
   }
}
Naturligtvis är det lite skumt (att fånga ett RuntimeException är en tveksam idé), men det är perfekt för våra syften :) Låt oss köra vår main() -metod 4 gånger i rad och titta på vår testlog.txt-fil. Du behöver inte skapa det i förväg: biblioteket gör detta automatiskt. Allt fungerade! :) Nu har du en konfigurerad logger. Du kan leka med några av dina gamla program och lägga till loggarrop till varje metod. Titta sedan på den resulterande loggen :) Den tar upp ämnet loggning på djupet. Det skulle vara utmanande att läsa allt på en gång. Som sagt, det innehåller mycket ytterligare användbar information. Du kommer till exempel att lära dig hur du konfigurerar loggern så att den skapar en ny textfil om vår testlog.txt-fil når en viss storlek :) Och det avslutar vår klass! Idag blev du bekant med ett mycket viktigt ämne, och denna kunskap kommer definitivt att vara till hjälp för dig i ditt framtida arbete. Tills nästa gång! :)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION