Logback vs Log4j Eksempel
I dette indlæg viser vi et omfattende eksempel på Logback vs Log4j. Logback og Log4j er de mest udbredte logningsrammer i Java-fællesskabet. I denne øvelse vil jeg demonstrere, hvordan du logger beskederne i Java-applikationer med både Logback og Log4j.
Indholdsfortegnelse
- 1. Indledning
- 2. Anvendte teknologier
- 3. Maven Java Application
- 3.1 Afhængigheder
- 3.2 Datamodel
- 4. Logger niveau
- 5. Logmeddelelser
- 5.1 Log4j1_Demo
- 5.2 Log4j2_Demo
- 5.3 Logback_Demo
- 6. Logningskonfiguration
- 6.1 Log4j.xml
- 6.2 Log4j2.xml
- 6.3 Logback.xml
- 7. Demo
- 7.1 Log4j Demo
- 7.2 Log4j 2 Demo
- 7.3 Logback-demo
- 8. Resumé
- 9. Download kildekoden
1. Introduktion
Java-applikationer er afhængige af log-meddelelser til at identificere og fejlfinde problemer i ikke-udviklingsmiljøer. Logback og Log4j er de mest udbredte logningsrammer i Java-fællesskabet.
Apache Log4j er et Java-baseret logningsværktøj. Det er en del af Apache Logging Services-projektet og blev først udgivet i 2001. Det stoppede ved version 1.2.17. Apache meddelte, at det var et udtjent produkt og er ødelagt på JDK9.
Logback er tænkt som en efterfølger til Log4j-projektet. Den blev først udgivet i august 2006. Den mest opdaterede version er i øjeblikket 2.11.1 og blev udgivet i juli 2018. Logback implementerer SLF4J API. Logback-dokumentationswebstedet har en liste over årsager til, hvorfor det er bedre end Log4j.
Apache Log4j 2 er en opgradering til Log4j, der giver betydelige forbedringer i forhold til Log4j og giver mange af de forbedringer, der er tilgængelige i Logback, mens de løser nogle iboende problemer i Logbacks arkitektur. Klik her for en detaljeret sammenligning mellem Logback og Log4j2.
Logback og Log4j har tre af de samme kernekomponenter:loggere, appenders og layouts. Disse komponenter arbejder sammen for at gøre det muligt for udviklere at logge meddelelser og formatere meddelelser.
Logger
– den klasse, som applikationen interagerer med for at oprette logbeskederAppender
– destinationen, som indeholder logbeskederLayout
– grænsefladen, der forbereder og formaterer meddelelserne til output
I dette eksempel vil jeg bygge tre Java-applikationer, som bruger henholdsvis Log4j, Log4j2 og Logback til at demonstrere:
- Sådan logger du meddelelserne med
Logger
- Sådan formateres logmeddelelserne med
Layout
- Hvor skal logmeddelelserne placeres med
Appender
- Sådan maskerer du adgangskoden
2. Anvendte teknologier
Eksempelkoden i denne artikel blev bygget og kørt ved hjælp af:
- Java 1.8.101
- Maven 3.3.9
- Eclipse Oxygen
- Logtilbage 1.2.3
- Log4j 1.2.17
- Log4j2 2.8.2
3. Maven Java-applikation
Der er mange måder at oprette en Maven Java-applikation på. Den nemmeste måde for mig er via Eclipse. Klik venligst her for detaljerede trin.
3.1 Afhængigheder
Pom.xml
styrer projektafhængighederne.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>jcg.zheng.demo</groupId> <artifactId>log4j-logback-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Mary Zheng demo for log4j vs logback</name> <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties> <dependencies> <!-- log4j1 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- log4j2 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.8.2</version> </dependency> <!-- logback --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-access</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
- Linje 17-21:Log4j-afhængighed
- Linje 25-35:Log4j 2-afhængigheder
- Linje 38-53:Logback-afhængigheder
3.2 Datamodel
I dette trin vil jeg oprette en Java-klasse:DemoModel
. Det inkluderer password
. Vi skjuler password
i logfilen i trin 5 og 6.
DemoModel.java
package jcg.zheng.demo.util; public class DemoModel { private Integer modelId; private String username; private String password; public static DemoModel createDummy() { DemoModel model = new DemoModel(); model.setModelId(123); model.setUsername("mzheng"); model.setPassword("PwdShouldHide"); return model; } public Integer getModelId() { return modelId; } public void setModelId(Integer modelId) { this.modelId = modelId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { System.out.println("toString called"); StringBuilder sb = new StringBuilder(); sb.append("Id=").append(String.valueOf(this.getModelId())).append(", "); sb.append("Username=").append(this.getUsername()).append(", "); sb.append("Password=").append(this.getPassword()); return sb.toString(); } }
4. Logger niveau
Log4j og Log4j2 har seks loggerniveauer; Logback har fem.
Niveau | Beskrivelse | Log4j | Log tilbage | Log4j2 |
---|---|---|---|---|
SPOR | De mest detaljerede informationsbegivenheder | Ja | Ja | Ja |
DEBUG | Finmaskede informationsbegivenheder, der er mest nyttige til at fejlsøge et program | Ja | Ja | Ja |
INFO | Informationsmeddelelser, der fremhæver applikationens fremskridt | Ja | Ja | Ja |
ADVAR | Potentielt skadelige situationer | Ja | Ja | Ja |
FEJL | Fejlhændelser | Ja | Ja | Ja |
FATAL | Fejl fik applikationen til at afbryde | Ja | Nej | Ja |
Bemærk: Log4j2 understøtter også brugerdefinerede loggerniveauer, klik her for flere detaljer.
5. Logmeddelelser
Log4j og Logback logger meddelelserne på en meget lignende måde. I dette trin vil jeg demonstrere dette med tre Java-applikationer.
5.1 Log4j1_Demo
I dette trin vil jeg oprette en Java-klasse –Log4j1_Demo
. Den logger seks loggemeddelelser, en for hvert loggerniveau.
Log4j1_Demo.java
package jcg.zheng.demo; import org.apache.log4j.Logger; import jcg.zheng.demo.util.DemoModel; public class Log4j1_Demo { private static final Logger LOG = Logger.getLogger(Log4j1_Demo.class); public static void main(String[] args) { Log4j1_Demo demo = new Log4j1_Demo(); demo.step1(DemoModel.createDummy()); } public void step1(DemoModel model) { if (LOG.isTraceEnabled()) { LOG.trace("Start step1 for " + model.toString()); } if (LOG.isDebugEnabled()) { LOG.debug("Start step1 for " + model.toString()); } if (LOG.isInfoEnabled()) { LOG.info("Start step1" + model.toString()); } LOG.warn("Start step1" + model.toString()); LOG.error("Start step1" + model.toString()); LOG.fatal("Start step1" + model.toString()); } }
- Linje 9:Logger er
org.apache.log4j.Logger
- linje 18, 22, 26:
isTraceEnabled
,isDebugEnabled
ogisInfoEnabled
vil have bedre ydeevne
5.2 Log4j2_Demo
I dette trin vil jeg oprette en Java-klasse –Log4j2_Demo
. Den logger seks beskeder.
Log4j2_Demo.java
package jcg.zheng.demo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import jcg.zheng.demo.util.DemoModel; public class Log4j2_Demo { private static Logger LOG = LogManager.getLogger(Log4j2_Demo.class); public static void main(String[] args) { Log4j2_Demo demo = new Log4j2_Demo(); demo.step1(DemoModel.createDummy()); } public void step1(DemoModel model) { LOG.trace("Start step1 for {}", () -> model.toString()); LOG.debug("Start step1 for {}", () -> model.toString()); LOG.info("Start step1 {}", () -> model.toString()); LOG.warn("Start step1 {}", () -> model.toString()); LOG.error("Start step1 {}", () -> model.toString()); LOG.fatal("Start step1 {}", () -> model.toString()); } }
- Linje 9:Logger er
org.apache.logging.log4j.Logger
- Linje 19-24:Doven logning giver bedre ydeevne. Det forhindrer også at kalde
model.toString()
5.2.1 MaskLog
Jeg vil oprette en MaskLog
klasse for at skjule adgangskoden fra logfilen. MaskLog
udvider LogEventPatternConverter
. Den søger i "Password=.*"
erstatter den derefter med “Password=***"
.
MaskLog.java
package jcg.zheng.demo.log4j2; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.pattern.ConverterKeys; import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; @Plugin(name = "logmask", category = "Converter") @ConverterKeys(value = { "cm" }) public class MaskLog extends LogEventPatternConverter { public MaskLog(String[] options) { super("cm", "cm"); } public static MaskLog newInstance(final String[] options) { return new MaskLog(options); } @Override public void format(LogEvent logEvent, StringBuilder outputMsg) { String message = logEvent.getMessage().getFormattedMessage(); if (message != null && message.contains("Password")) { String finalMsg = message.replaceAll("Password=.*", "Password=***"); outputMsg.append(finalMsg); } else { outputMsg.append(message); } } }
- Linje 9:Definer tilpasset konverter:
cm
- Linje 24:Skjul adgangskoden
5.3 Logback_Demo
I dette trin vil jeg oprette en Java-klasse –Logback_Demo
. Den logger fem beskeder.
Logback_Demo.java
package jcg.zheng.demo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jcg.zheng.demo.util.DemoModel; public class Logback_Demo { private final Logger lOG = LoggerFactory.getLogger(this.getClass()); public static void main(String[] args) { Logback_Demo demo = new Logback_Demo(); demo.step1(DemoModel.createDummy()); } public void step1(DemoModel model) { if (lOG.isTraceEnabled()) { lOG.trace("Start step1 for {}", model.toString()); } if (lOG.isDebugEnabled()) { lOG.debug("Start step1 for {}", model.toString()); } if (lOG.isInfoEnabled()) { lOG.info("Start step1 {}", model.toString()); } if (lOG.isWarnEnabled()) { lOG.warn("Start step1 {}", model.toString()); } if (lOG.isErrorEnabled()) { lOG.error("Start step1 {}", model.toString()); } } }
- Linje 10:Logger er
org.slf4j.Logger
- Linje 20, 24, 28, 32, 36:Parametriseret logning forhindrer ikke opkald
model.toString()
, så brugisXXXEnabled
for bedre ydeevne
6. Logningskonfiguration
Logback og Log4j bruger konfiguration til at formatere loghændelser baseret på layoutkonventionsmønsteret og skrive loghændelser til den ønskede destination baseret på appenderen. Logback, Log4j og Log4j2 kan konfigureres programmatisk. Det er dog langt mere fleksibelt at konfigurere det ved hjælp af konfigurationsfiler. Logback og Log4j understøtter forskellige konfigurationsfiltyper:egenskabsfil, XML-fil, Groovy-fil, JSON-fil, YAML-fil osv. Det mest brugte er XML-formatet. I dette trin vil jeg vise dig, hvordan du konfigurerer med XML-filerne til Logback, Log4j og Log4j2.
6.1 Log4j.xml
Log4js konfigurationsfiler kan skrives i XML eller i Java-egenskaber (nøgle=værdi) format. I dette trin vil jeg vise en log4j.xml
konfiguration til at skrive logfilerne på logs/log4j1
vejviser.
Log4j.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration debug="true"> <appender name="DAILYLOG" class="org.apache.log4j.DailyRollingFileAppender"> <param name="File" value="logs/log4j1/demo.log" /> <param name="Append" value="true" /> <!-- Rollover at midnight each day --> <param name="DatePattern" value="'.'yyyy-MM-dd" /> <layout class="org.apache.log4j.EnhancedPatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZZ} llevel=%-5p, lthread_id='%t',lclass=%C{2.}.%L,lmethod=%M %m%n" /> </layout> </appender> <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <param name="Target" value="System.out" /> <layout class="org.apache.log4j.EnhancedPatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZZ} llevel=%-5p, lthread_id='%t',lclass=%C{2.}.%L,lmethod=%M %m%n" /> </layout> </appender> <logger name="jcg.zheng.demo"> <level value="INFO" /> </logger> <root> <priority value="INFO" /> <appender-ref ref="DAILYLOG" /> <appender-ref ref="CONSOLE" /> </root> </log4j:configuration>
6.2 Log4j2.xml
Log4j2s konfigurationsfiler kan skrives i Java-egenskabsformatet (nøgle=værdi), XML, JSON, YAML-format. I dette trin vil jeg vise en log4j2.xml
konfiguration til at logge meddelelserne på logs/log4j2
vejviser.
Log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="trace" monitorInterval="30" packages="jcg.zheng.demo.log4j2" xmlns="http://logging.apache.org/log4j/2.0/config"> <Properties> <Property name="basePath">logs/log4j2</Property> </Properties> <Appenders> <!-- File Appender --> <RollingFile name="FILE" fileName="${basePath}/logfile.log" filePattern="${basePath}/logfile.%d{yyyy-MM-dd}-%i.log" append="true"> <PatternLayout pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %cm%n" /> <Policies> <SizeBasedTriggeringPolicy size="1 KB" /> </Policies> <DefaultRolloverStrategy max="4" /> </RollingFile> <!-- Console Appender --> <Console name="STDOUT" target="SYSTEM_OUT"> <PatternLayout pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %cm%n" /> </Console> </Appenders> <Loggers> <Logger name="jcg.zheng.demo" level="warn" /> <Root level="info"> <AppenderRef ref="STDOUT" /> <AppenderRef ref="FILE" /> </Root> </Loggers> </Configuration>
- Linje 3:
MaskLog
pakke medfølger - Linje 13, 22:Brug
cm
for at maskere adgangskoden
6.3 Logback.xml
Logbacks konfigurationsfiler kan skrives i XML og groovy. I dette trin vil jeg vise en logback.xml
konfiguration til at skrive logfilerne ved logs/logback
vejviser.
Logback.xml
<!-- demo the debug value difference --> <configuration debug="true" scan="true" scanPeriod="10 seconds"> <property name="LOG_DIR" value="logs/logback" /> <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_DIR}/demo.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern> %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %replace(%msg){"Password=.*","Password=xxxxx"}%n </Pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- rollover daily --> <fileNamePattern>${LOG_DIR}/demo.%d{yyyy-MM-dd}.%i.log </fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> </appender> <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <charset>UTF-8</charset> <Pattern>%d %-4relative [%thread] %-5level %logger{35} - %msg%n </Pattern> </encoder> </appender> <logger name="jcg.zheng.demo" level="warn" additivity="false"> <appender-ref ref="FILE_INFO" /> <appender-ref ref="consoleAppender" /> </logger> <root level="error"> <appender-ref ref="FILE_INFO" /> <appender-ref ref="consoleAppender" /> </root> </configuration>
- Linje 4:Definer log-mappeegenskab
- Linje 22: Brug
%replace
for at maskere adgangskoden
6.4 XML-konfigurationsoversigt
Som du ser disse tre XML-konfigurationseksempler, ligner Logback XML-konfigurationen meget Log4j. Log4j2 har forskellige XML-elementer til Appender
og Layout
. Logback giver en oversætter til at konvertere konfigurationsfilen fra Log4j-format til Logback.
7. Demo
I dette trin vil vi køre tre Java-applikationer og overvåge logmeddelelserne på både systemkonsollen og logfilerne.
7.1 Log4j Demo
Udfør Log4j1_demo
Ansøgning.
output
log4j: reset attribute= "false". log4j: Threshold ="null". log4j: Retreiving an instance of org.apache.log4j.Logger. log4j: Setting [jcg.zheng.demo] additivity to [true]. log4j: Level value for jcg.zheng.demo is [INFO]. log4j: jcg.zheng.demo level set to INFO log4j: Level value for root is [INFO]. log4j: root level set to INFO log4j: Class name: [org.apache.log4j.DailyRollingFileAppender] log4j: Setting property [file] to [logs/log4j1/demo.log]. log4j: Setting property [append] to [true]. log4j: Setting property [datePattern] to ['.'yyyy-MM-dd]. log4j: Parsing layout of class: "org.apache.log4j.EnhancedPatternLayout" log4j: Setting property [conversionPattern] to [%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZZ} llevel=%-5p, lthread_id='%t',lclass=%C{2.}.%L,lmethod=%M %m%n]. log4j: setFile called: logs/log4j1/demo.log, true log4j: setFile ended log4j: Appender [DAILYLOG] to be rolled at midnight. log4j: Adding appender named [DAILYLOG] to category [root]. log4j: Class name: [org.apache.log4j.ConsoleAppender] log4j: Setting property [target] to [System.out]. log4j: Parsing layout of class: "org.apache.log4j.EnhancedPatternLayout" log4j: Setting property [conversionPattern] to [%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZZ} llevel=%-5p, lthread_id='%t',lclass=%C{2.}.%L,lmethod=%M %m%n]. log4j: Adding appender named [CONSOLE] to category [root]. toString called 2018-08-02T21:17:15.732-0500 llevel=INFO , lthread_id='main',lclass=jc.zh.de.Log4j1_Demo.27,lmethod=step1 Start step1Id=123, Username=mzheng, Password=PwdShouldHide toString called 2018-08-02T21:17:15.737-0500 llevel=WARN , lthread_id='main',lclass=jc.zh.de.Log4j1_Demo.30,lmethod=step1 Start step1Id=123, Username=mzheng, Password=PwdShouldHide toString called 2018-08-02T21:17:15.737-0500 llevel=ERROR, lthread_id='main',lclass=jc.zh.de.Log4j1_Demo.31,lmethod=step1 Start step1Id=123, Username=mzheng, Password=PwdShouldHide toString called 2018-08-02T21:17:15.737-0500 llevel=FATAL, lthread_id='main',lclass=jc.zh.de.Log4j1_Demo.32,lmethod=step1 Start step1Id=123, Username=mzheng, Password=PwdShouldHide
7.2 Log4j 2 Demo
Udfør Log4j2_demo
Ansøgning.
output
2018-08-02 21:23:40,977 main DEBUG Initializing configuration XmlConfiguration[location=C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml] 2018-08-02 21:23:40,993 main DEBUG Installed script engines 2018-08-02 21:23:41,611 main DEBUG Oracle Nashorn Version: 1.8.0_31, Language: ECMAScript, Threading: Not Thread Safe, Compile: true, Names: {nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript} 2018-08-02 21:23:41,611 main DEBUG Took 0.002831 seconds to load 1 plugins from package jcg.zheng.demo.log4j2 2018-08-02 21:23:41,611 main DEBUG PluginManager 'Core' found 112 plugins 2018-08-02 21:23:41,611 main DEBUG PluginManager 'Level' found 0 plugins 2018-08-02 21:23:41,611 main DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property]. 2018-08-02 21:23:41,642 main TRACE TypeConverterRegistry initializing. 2018-08-02 21:23:41,643 main DEBUG PluginManager 'TypeConverter' found 26 plugins 2018-08-02 21:23:41,643 main DEBUG createProperty(name="basePath", value="logs/log4j2") 2018-08-02 21:23:41,643 main DEBUG Building Plugin[name=properties, class=org.apache.logging.log4j.core.config.PropertiesPlugin]. 2018-08-02 21:23:41,659 main DEBUG configureSubstitutor(={basePath=logs/log4j2}, Configuration(C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml)) 2018-08-02 21:23:41,659 main DEBUG PluginManager 'Lookup' found 13 plugins 2018-08-02 21:23:41,659 main DEBUG Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout]. 2018-08-02 21:23:41,659 main DEBUG PatternLayout$Builder(pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %cm%n", PatternSelector=null, Configuration(C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml), Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="null", noConsoleNoAnsi="null", header="null", footer="null") 2018-08-02 21:23:41,659 main DEBUG PluginManager 'Converter' found 42 plugins 2018-08-02 21:23:41,690 main DEBUG Building Plugin[name=SizeBasedTriggeringPolicy, class=org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy]. 2018-08-02 21:23:41,690 main DEBUG createPolicy(size="1 KB") 2018-08-02 21:23:41,690 main DEBUG Building Plugin[name=Policies, class=org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy]. 2018-08-02 21:23:41,690 main DEBUG createPolicy(={SizeBasedTriggeringPolicy(size=1024)}) 2018-08-02 21:23:41,690 main DEBUG Building Plugin[name=DefaultRolloverStrategy, class=org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy]. 2018-08-02 21:23:41,690 main DEBUG createStrategy(max="4", min="null", fileIndex="null", compressionLevel="null", ={}, stopCustomActionsOnError="true", Configuration(C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml)) 2018-08-02 21:23:41,690 main DEBUG Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.RollingFileAppender]. 2018-08-02 21:23:41,721 main DEBUG RollingFileAppender$Builder(fileName="logs/log4j2/logfile.log", filePattern="logs/log4j2/logfile.%d{yyyy-MM-dd}-%i.log", append="true", locking="null", Policies(CompositeTriggeringPolicy(policies=[SizeBasedTriggeringPolicy(size=1024)])), DefaultRolloverStrategy(DefaultRolloverStrategy(min=1, max=4, useMax=true)), advertise="null", advertiseUri="null", createOnDemand="null", bufferedIo="null", bufferSize="null", immediateFlush="null", ignoreExceptions="null", PatternLayout(%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %cm%n), name="FILE", Configuration(C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml), Filter=null) 2018-08-02 21:23:41,721 main TRACE New file 'logs/log4j2/logfile.log' created = false 2018-08-02 21:23:41,737 main DEBUG Starting RollingFileManager logs/log4j2/logfile.log 2018-08-02 21:23:41,737 main DEBUG PluginManager 'FileConverter' found 2 plugins 2018-08-02 21:23:41,737 main DEBUG Setting prev file time to 2018-08-02T21:18:35.422-0500 2018-08-02 21:23:41,737 main DEBUG Initializing triggering policy CompositeTriggeringPolicy(policies=[SizeBasedTriggeringPolicy(size=1024)]) 2018-08-02 21:23:41,737 main DEBUG Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout]. 2018-08-02 21:23:41,737 main DEBUG PatternLayout$Builder(pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %cm%n", PatternSelector=null, Configuration(C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml), Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="null", noConsoleNoAnsi="null", header="null", footer="null") 2018-08-02 21:23:41,737 main DEBUG Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.ConsoleAppender]. 2018-08-02 21:23:41,737 main DEBUG ConsoleAppender$Builder(target="SYSTEM_OUT", follow="null", direct="null", bufferedIo="null", bufferSize="null", immediateFlush="null", ignoreExceptions="null", PatternLayout(%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %cm%n), name="STDOUT", Configuration(C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml), Filter=null) 2018-08-02 21:23:41,753 main DEBUG Jansi is not installed, cannot find org.fusesource.jansi.WindowsAnsiOutputStream 2018-08-02 21:23:41,753 main DEBUG Starting OutputStreamManager SYSTEM_OUT.false.false 2018-08-02 21:23:41,753 main DEBUG Building Plugin[name=appenders, class=org.apache.logging.log4j.core.config.AppendersPlugin]. 2018-08-02 21:23:41,753 main DEBUG createAppenders(={FILE, STDOUT}) 2018-08-02 21:23:41,753 main DEBUG Building Plugin[name=logger, class=org.apache.logging.log4j.core.config.LoggerConfig]. 2018-08-02 21:23:41,753 main DEBUG createLogger(additivity="true", level="WARN", name="jcg.zheng.demo", includeLocation="null", ={}, ={}, Configuration(C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml), Filter=null) 2018-08-02 21:23:41,753 main DEBUG Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef]. 2018-08-02 21:23:41,753 main DEBUG createAppenderRef(ref="STDOUT", level="null", Filter=null) 2018-08-02 21:23:41,753 main DEBUG Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef]. 2018-08-02 21:23:41,753 main DEBUG createAppenderRef(ref="FILE", level="null", Filter=null) 2018-08-02 21:23:41,768 main DEBUG Building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger]. 2018-08-02 21:23:41,768 main DEBUG createLogger(additivity="null", level="INFO", includeLocation="null", ={STDOUT, FILE}, ={}, Configuration(C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml), Filter=null) 2018-08-02 21:23:41,768 main DEBUG Building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin]. 2018-08-02 21:23:41,768 main DEBUG createLoggers(={jcg.zheng.demo, root}) 2018-08-02 21:23:41,768 main DEBUG Configuration XmlConfiguration[location=C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml] initialized 2018-08-02 21:23:41,768 main DEBUG Starting configuration XmlConfiguration[location=C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml] 2018-08-02 21:23:41,768 main DEBUG Log4j2 ConfigurationScheduler starting 1 threads 2018-08-02 21:23:41,768 main DEBUG Started configuration XmlConfiguration[location=C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml] OK. 2018-08-02 21:23:41,768 main TRACE Stopping org.apache.logging.log4j.core.config.DefaultConfiguration@4629104a... 2018-08-02 21:23:41,768 main TRACE DefaultConfiguration notified 1 ReliabilityStrategies that config will be stopped. 2018-08-02 21:23:41,768 main TRACE DefaultConfiguration stopping root LoggerConfig. 2018-08-02 21:23:41,768 main TRACE DefaultConfiguration notifying ReliabilityStrategies that appenders will be stopped. 2018-08-02 21:23:41,768 main TRACE DefaultConfiguration stopping remaining Appenders. 2018-08-02 21:23:41,768 main DEBUG Shutting down OutputStreamManager SYSTEM_OUT.false.false-1 2018-08-02 21:23:41,768 main DEBUG Shut down OutputStreamManager SYSTEM_OUT.false.false-1, all resources released: true 2018-08-02 21:23:41,768 main DEBUG Appender DefaultConsole-1 stopped with status true 2018-08-02 21:23:41,768 main TRACE DefaultConfiguration stopped 1 remaining Appenders. 2018-08-02 21:23:41,768 main TRACE DefaultConfiguration cleaning Appenders from 1 LoggerConfigs. 2018-08-02 21:23:41,768 main DEBUG Stopped org.apache.logging.log4j.core.config.DefaultConfiguration@4629104a OK 2018-08-02 21:23:41,831 main TRACE Reregistering MBeans after reconfigure. Selector=org.apache.logging.log4j.core.selector.ClassLoaderContextSelector@1bb266b3 2018-08-02 21:23:41,831 main TRACE Reregistering context (1/1): '2a139a55' org.apache.logging.log4j.core.LoggerContext@306cf3ea 2018-08-02 21:23:41,846 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55' 2018-08-02 21:23:41,846 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55,component=StatusLogger' 2018-08-02 21:23:41,846 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55,component=ContextSelector' 2018-08-02 21:23:41,846 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55,component=Loggers,name=*' 2018-08-02 21:23:41,846 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55,component=Appenders,name=*' 2018-08-02 21:23:41,846 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55,component=AsyncAppenders,name=*' 2018-08-02 21:23:41,846 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55,component=AsyncLoggerRingBuffer' 2018-08-02 21:23:41,846 main TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55,component=Loggers,name=*,subtype=RingBuffer' 2018-08-02 21:23:41,846 main DEBUG Registering MBean org.apache.logging.log4j2:type=2a139a55 2018-08-02 21:23:41,862 main DEBUG Registering MBean org.apache.logging.log4j2:type=2a139a55,component=StatusLogger 2018-08-02 21:23:41,862 main DEBUG Registering MBean org.apache.logging.log4j2:type=2a139a55,component=ContextSelector 2018-08-02 21:23:41,862 main DEBUG Registering MBean org.apache.logging.log4j2:type=2a139a55,component=Loggers,name= 2018-08-02 21:23:41,862 main DEBUG Registering MBean org.apache.logging.log4j2:type=2a139a55,component=Loggers,name=jcg.zheng.demo 2018-08-02 21:23:41,862 main DEBUG Registering MBean org.apache.logging.log4j2:type=2a139a55,component=Appenders,name=FILE 2018-08-02 21:23:41,862 main DEBUG Registering MBean org.apache.logging.log4j2:type=2a139a55,component=Appenders,name=STDOUT 2018-08-02 21:23:41,862 main TRACE Using default SystemClock for timestamps. 2018-08-02 21:23:41,862 main TRACE Using DummyNanoClock for nanosecond timestamps. 2018-08-02 21:23:41,862 main DEBUG Reconfiguration complete for context[name=2a139a55] at URI C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml (org.apache.logging.log4j.core.LoggerContext@306cf3ea) with optional ClassLoader: null 2018-08-02 21:23:41,862 main DEBUG Shutdown hook enabled. Registering a new one. 2018-08-02 21:23:41,862 main DEBUG LoggerContext[name=2a139a55, org.apache.logging.log4j.core.LoggerContext@306cf3ea] started OK. toString called WARN | 2018-08-02 21:23:41 | [main] demo.Log4j2_Demo (Log4j2_Demo.java:22) - Start step1 Id=123, Username=mzheng, Password=*** toString called ERROR | 2018-08-02 21:23:41 | [main] demo.Log4j2_Demo (Log4j2_Demo.java:23) - Start step1 Id=123, Username=mzheng, Password=*** 2018-08-02 21:23:41,893 main TRACE DefaultRolloverStrategy.purge() took 9.0 milliseconds 2018-08-02 21:23:41,893 main DEBUG RollingFileManager executing synchronous FileRenameAction[logs\log4j2\logfile.log to logs\log4j2\logfile.2018-08-02-1.log, renameEmptyFiles=false] 2018-08-02 21:23:41,893 main TRACE Renamed file C:\gitworkspace\log4j-logback-demo\logs\log4j2\logfile.log to C:\gitworkspace\log4j-logback-demo\logs\log4j2\logfile.2018-08-02-1.log with Files.move 2018-08-02 21:23:41,893 main DEBUG Now writing to logs/log4j2/logfile.log at 2018-08-02T21:23:41.893-0500 toString called FATAL | 2018-08-02 21:23:41 | [main] demo.Log4j2_Demo (Log4j2_Demo.java:24) - Start step1 Id=123, Username=mzheng, Password=*** 2018-08-02 21:23:41,893 pool-1-thread-1 DEBUG Stopping LoggerContext[name=2a139a55, org.apache.logging.log4j.core.LoggerContext@306cf3ea] 2018-08-02 21:23:41,893 pool-1-thread-1 DEBUG Stopping LoggerContext[name=2a139a55, org.apache.logging.log4j.core.LoggerContext@306cf3ea]... 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE Unregistering 1 MBeans: [org.apache.logging.log4j2:type=2a139a55] 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE Unregistering 1 MBeans: [org.apache.logging.log4j2:type=2a139a55,component=StatusLogger] 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE Unregistering 1 MBeans: [org.apache.logging.log4j2:type=2a139a55,component=ContextSelector] 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE Unregistering 2 MBeans: [org.apache.logging.log4j2:type=2a139a55,component=Loggers,name=, org.apache.logging.log4j2:type=2a139a55,component=Loggers,name=jcg.zheng.demo] 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE Unregistering 2 MBeans: [org.apache.logging.log4j2:type=2a139a55,component=Appenders,name=STDOUT, org.apache.logging.log4j2:type=2a139a55,component=Appenders,name=FILE] 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55,component=AsyncAppenders,name=*' 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55,component=AsyncLoggerRingBuffer' 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=2a139a55,component=Loggers,name=*,subtype=RingBuffer' 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE Stopping XmlConfiguration[location=C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml]... 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE XmlConfiguration notified 3 ReliabilityStrategies that config will be stopped. 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE XmlConfiguration stopping 2 LoggerConfigs. 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE XmlConfiguration stopping root LoggerConfig. 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE XmlConfiguration notifying ReliabilityStrategies that appenders will be stopped. 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE XmlConfiguration stopping remaining Appenders. 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG Shutting down OutputStreamManager SYSTEM_OUT.false.false 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG Shut down OutputStreamManager SYSTEM_OUT.false.false, all resources released: true 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG Appender STDOUT stopped with status true 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG Shutting down RollingFileManager logs/log4j2/logfile.log 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG Shutting down RollingFileManager {}logs/log4j2/logfile.log 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG All asynchronous threads have terminated 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG RollingFileManager shutdown completed with status true 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG Shut down RollingFileManager logs/log4j2/logfile.log, all resources released: true 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG Appender FILE stopped with status true 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE XmlConfiguration stopped 2 remaining Appenders. 2018-08-02 21:23:41,909 pool-1-thread-1 TRACE XmlConfiguration cleaning Appenders from 3 LoggerConfigs. 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG Log4j2 ConfigurationScheduler shutting down threads in java.util.concurrent.ScheduledThreadPoolExecutor@268918ec[Running, pool size = 1, active threads = 0, queued tasks = 1, completed tasks = 0] 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG Stopped XmlConfiguration[location=C:\gitworkspace\log4j-logback-demo\target\classes\log4j2.xml] OK 2018-08-02 21:23:41,909 pool-1-thread-1 DEBUG Stopped LoggerContext[name=2a139a55, org.apache.logging.log4j.core.LoggerContext@306cf3ea] with status true
Linje 86, 88, 94:Skjul adgangskoden.
7.3 Logback-demo
Udfør Logback_demo
Ansøgning.
output
21:18:53,336 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml] 21:18:53,336 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy] 21:18:53,338 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/C:/gitworkspace/log4j-logback-demo/target/classes/logback.xml] 21:18:53,521 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Will scan for changes in [file:/C:/gitworkspace/log4j-logback-demo/target/classes/logback.xml] 21:18:53,521 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Setting ReconfigureOnChangeTask scanning period to 10 seconds 21:18:53,526 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 21:18:53,533 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [FILE_INFO] 21:18:53,621 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@1654589030 - No compression will be used 21:18:53,623 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@1654589030 - Will use the pattern logs/logback/demo.%d{yyyy-MM-dd}.%i.log for the active file 21:18:53,628 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@75412c2f - The date pattern is 'yyyy-MM-dd' from file name pattern 'logs/logback/demo.%d{yyyy-MM-dd}.%i.log'. 21:18:53,628 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@75412c2f - Roll-over at midnight. 21:18:53,633 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@75412c2f - Setting initial period to Thu Aug 02 16:13:47 CDT 2018 21:18:53,633 |-WARN in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@75412c2f - SizeAndTimeBasedFNATP is deprecated. Use SizeAndTimeBasedRollingPolicy instead 21:18:53,633 |-WARN in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@75412c2f - For more information see http://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedRollingPolicy 21:18:53,641 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[FILE_INFO] - Active log file name: logs/logback/demo.log 21:18:53,643 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[FILE_INFO] - File property is set to [logs/logback/demo.log] 21:18:53,646 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender] 21:18:53,648 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [consoleAppender] 21:18:53,648 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 21:18:53,651 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [jcg.zheng.demo] to WARN 21:18:53,651 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [jcg.zheng.demo] to false 21:18:53,651 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [FILE_INFO] to Logger[jcg.zheng.demo] 21:18:53,651 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [consoleAppender] to Logger[jcg.zheng.demo] 21:18:53,651 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to ERROR 21:18:53,651 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [FILE_INFO] to Logger[ROOT] 21:18:53,653 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [consoleAppender] to Logger[ROOT] 21:18:53,653 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration. 21:18:53,653 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@2aafb23c - Registering current configuration as safe fallback point toString called 2018-08-02 21:18:53,656 368 [main] WARN jcg.zheng.demo.Logback_Demo - Start step1 Id=123, Username=mzheng, Password=PwdShouldHide toString called 2018-08-02 21:18:53,661 373 [main] ERROR jcg.zheng.demo.Logback_Demo - Start step1 Id=123, Username=mzheng, Password=PwdShouldHide
Her er log-outputfilerne.
Figur 1 Log-mappe
8. Resumé
I denne artikel dækkede vi de grundlæggende funktioner ved at bruge Logback og Log4j i tre Java-applikationer. Vi demonstrerede tre konfigurationseksempler til at oprette, formatere og filtrere logmeddelelser samt til at maskere adgangskodedataene. Logback kræver Java 6 siden version 1.1.3. Log4j2 2.4+ kræver Java 7, version 2.0-alpha1 til 2.3 kræver Java 6.
9. Download kildekoden
Dette eksempel består af Java-applikationer til at demonstrere Logback- og Log4j-funktionerne.log4j-logback