Java heeft een logging-API-bibliotheek opgenomen als onderdeel van het framework van JDK 1.4. Tegenwoordig is dit een ingebouwde ondersteuning van Java. Deze bibliotheek is echter aanpasbaar en uitbreidbaar in die zin dat we een of meer alternatieve logging-oplossingen kunnen gebruiken die worden aangeboden door bibliotheken van derden. Hoewel deze oplossingen van derden een andere benadering hebben voor het maken van loggegevens, hebben ze uiteindelijk hetzelfde doel, namelijk het loggen van berichten van applicatieruntime. Dit artikel onderzoekt de basisprincipes van loggen en laat zien hoe het kan worden gebruikt in een Java-programma.
Java-logboekregistratie
Een log betekent meestal het bijhouden van een soort record. Vanuit het perspectief van programmeren is het een proces van het schrijven van berichten in een logbestand tijdens de uitvoering van het programma. Aanhoudende berichtenlogboeken worden, meestal door de programmeur, doorverwezen om bepaalde runtime-statistieken te verzamelen die, wanneer ze worden geanalyseerd, onvoorziene situaties aan het licht kunnen brengen. In feite kunnen er tal van verschillende redenen zijn waarom logboekregistratie wordt gebruikt en dit is er slechts één van. Volgens de Java API-documentatie zijn er vier primaire toepassingen van logboekregistratie:
- Voor probleemdiagnose door eindgebruikers en systeembeheerders.
- Het is handig voor buitendienstmonteurs om het probleem te diagnosticeren aan de hand van gelogde berichten en het snel op te lossen.
- Ontwikkelingsorganisatie kan de interne uitvoering van een bepaald subsysteem traceren en analyseren.
- Ontwikkelaars kunnen fouten opsporen in de applicatie die in ontwikkeling is door snel inzicht te krijgen in het onderliggende probleem uit gelogde berichten.
Java API-logboekregistratie is op een goedkope manier ontworpen in die zin dat het zelfs in een productietoepassing als een residu kan worden achtergelaten. Dit zorgt niet voor veel overhead voor de efficiëntie van de uitvoering van het programma. De API biedt het mechanisme om de productie van logboekberichten dynamisch te wijzigen, zodat de impact van logboekregistratie kan worden geminimaliseerd tijdens bewerkingen die maximale efficiëntie vereisen. De API bestaat uit een aantal klassen en interfaces die kunnen worden aangepast door ze uit te breiden. De volledige logging-API is verpakt onder java.util.logging . De klassen en interfaces in dit pakket bieden de belangrijkste logfaciliteiten in Java.
Logniveaus
De urgentie van inloggen in een Java-programma kan worden onderverdeeld in verschillende niveaus. Door op en neer te nivelleren, kunnen we de kosten van het loggen in een productietoepassing verhogen of verlagen. Dit is hoe we de efficiëntie van de uitvoering van een applicatie controleren wanneer het nodig is om een of meer van zijn gebeurtenissen te loggen. Dit wordt bereikt door een klasse genaamd Niveau , die het belang van logboekregistratie definieert. Het logniveau wordt geordend en gespecificeerd door statisch integer constanten, zoals:
- Niveau.ALL: Alle berichten worden gelogd, ongeacht het belang
- Niveau.UIT: Logboekregistratie is uitgeschakeld
- Niveau. ERNSTIG: Geeft ernstig falen aan; moet ingelogd zijn
- Niveau.WAARSCHUWING: Geeft waarschuwingsberichten aan
- Niveau.INFO: Runtime-informatiebericht
- Niveau.CONFIG: Statische configuratieberichten
- Niveau.FIJN: Berichten traceren
- Niveau.FINER: Gedetailleerde traceringsberichten
- Niveau.FIJNSTE: Zeer gedetailleerde traceerberichten
Logcomponenten
We hebben een Logger nodig bijvoorbeeld om elke vorm van logging in Java uit te voeren. Deze instantie is verantwoordelijk voor het loggen van gegevens in een LogRecord . Het LogRecord instances worden gebruikt om logverzoeken door te geven tussen logframeworks en individuele loghandlers. Java SE biedt vijf ingebouwde handlers:StreamHandler , ConsoleHandler , FileHandler , SocketHandler , en MemoryHandler . Men kan echter een nieuwe handler maken of een van deze uitbreiden als een aanpassing. De handlers bepalen wat er met het logrecord moet gebeuren; het kan bijvoorbeeld worden bewaard in een lokale repository of het via een netwerk doorgeven aan een server. Java SE bevat ook twee standaard formatters:SimpleFormatter en XMLFormatter . Deze formatters worden gebruikt om een LogRecord . te formatteren respectievelijk in voor mensen leesbaar formaat en standaard XML-formaat.
Er is een LogManager class die globale logboekinformatie bijhoudt, zoals een hiërarchische naamruimte van benoemde Loggers en een set logboekbesturingseigenschappen uit het configuratiebestand. Het staat centraal bij het inloggen in Java en regelt vrijwel alles wat moet worden geregistreerd, waar moet worden ingelogd, inclusief andere initialisatiedetails, enzovoort.
Een eenvoudig voorbeeld van loggen
Een Logger maken voorwerp is heel eenvoudig. Hier is een heel eenvoudige code om dat te illustreren.
import java.util.logging.Logger; public class App { private static Logger logger = Logger.getLogger(App.class.getName()); public static void main(String[] args) { logger.info("This is a log message !!!"); logger.info("The name of the logger is " + logger.getName() + " nwhich is same as class name: " + App.class.getName()); } }
Logger objecten worden meestal benoemd met de String waarde van een hiërarchische door punten gescheiden naamruimte. In het voorgaande geval is dit hetzelfde als de klassenaam. De naam kan echter een willekeurige tekenreekswaarde zijn, maar normaal gesproken zijn namen gebaseerd op de pakketnaam of de klassenaam van de gelogde component. Het is ook mogelijk om een "anonieme" logger aan te maken die niet wordt opgeslagen in de Logger naamruimte.
Log in op een extern bestand met behulp van XML-opmaak
In de volgende code worden de logberichten omgeleid naar een bestand met behulp van FileHandler .
Opmerking: Het bestand wordt aangemaakt in de projectdirectory. |
De FileHandler kan ofwel naar een gespecificeerd bestand schrijven, ofwel naar een roterende set bestanden. De roterende set bestanden betekent dat oudere bestanden een naam krijgen door 0,1,2 enzovoort toe te voegen aan de basisbestandsnaam. De XMLFormatter is de standaardopmaak die wordt gebruikt door FileHandler .
import java.io.IOException; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; public class App { private static FileHandler fileHandler; private static Logger logger = Logger.getLogger(App.class.getName()); public static void main(String[] args) throws IOException { fileHandler = new FileHandler(App.class.getName() + ".log"); logger.setLevel(Level.ALL); logger.addHandler(fileHandler); logger.info("Log message redirected to a file"); logger.info("The name of the logger is " + logger.getName() + " nwhich is same as class name: " + App.class.getName()); } }
Log in op een extern bestand met aangepaste opmaak
We zullen de volgende code een beetje aanpassen om de opmaak van het bericht aan te passen. Dit verandert hoe de berichten in het externe bestand worden geschreven.
Opmerking: Bekijk de inhoud van het logbestand over hoe de opmaak is veranderd. |
import java.io.IOException; import java.util.logging.*; public class App { private static FileHandler fileHandler; private static Logger logger = Logger.getLogger(App.class.getName()); public static void main(String[] args) throws IOException { fileHandler = new FileHandler(App.class.getName() + ".log"); logger.setLevel(Level.ALL); fileHandler.setFormatter(newCustomFormatter()); logger.addHandler(fileHandler); logger.fine("Log message redirected to a file"); logger.finer("The name of the logger is " + logger.getName()); loggerfinest("This is same as class name: " + App.class.getName()); } private static class CustomFormatter extends Formatter { private static final String format = "[%1$tF %1$tT] [%2$-4s] %3$s %n"; public String format(LogRecord record) { returnString.format(format, record.getMillis(), record.getLevel().getLocalizedName(), record.getMessage()); } } }
Dat is alles. Experimenteer met Java-logging en probeer vele andere mogelijkheden. Raadpleeg waar nodig de Java API-documenten.
Andere Logging Frameworks in Java
Soms is het handig om een logging-framework van derden te gebruiken, en er zijn nogal wat populaire om uit te kiezen. De logging-API van SLF4J maakt bijvoorbeeld gebruik van een eenvoudig façadepatroon, een abstractielaag waarmee de applicatie kan worden losgekoppeld van het logging-framework. Log4j is syntactisch vergelijkbaar met ingebouwde Java-logboekregistratie. Het heeft een standaardconfiguratie om alle logberichten naar de console uit te voeren. Logback is een opvolger van Log4j en is een uitbreiding van zijn voorganger. tinyLog is een lichtgewicht logging-framework dat zowel met Java als Android kan worden gebruikt.
Conclusie
Het logproces is ontworpen om eenvoudig en efficiënt te zijn in het leveren van wat het zou moeten doen. Het is mogelijk om snel aan de slag te gaan met Logging API's in Java. Het ontwerp is uitbreidbaar en kan worden aangepast aan de eindbehoeften van de ontwikkelaar. Dit artikel is een kijkje in de basisprincipes van Java-logboekregistratie. Veel ingewikkelde details zijn voor de eenvoud weggelaten. Bestudeer de Java API-documentatie en andere geschikte documenten voor meer informatie hierover.
Referenties
- Overzicht Java-logboekregistratie
- Java API-documentatie