我正在使用基于 java 的配置进行日志记录并尝试配置 ConsoleAppender 和 RollingFileAppender。这里的问题是应该在控制台上打印的日志被打印在日志文件中。如何将两个日志记录分开到各自的位置?
package com.rsa.springclasses.day3.logback;
import java.io.IOException;
import java.util.Iterator;
import java.util.Properties;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
@Configuration
@ComponentScan
public class AppConfig {
@Bean
public LoggerContext getLoggerContext() {
LoggerContext lctx = this.initLoggerContext();
return lctx;
}
public LoggerContext initLoggerContext() {
LoggerContext lctx = (LoggerContext) LoggerFactory.getILoggerFactory();
lctx.setName("ApplicationLogger");
Properties lp = readLogbackProperties();
this.setLoggerLevels(lctx, lp);
for (Logger l : lctx.getLoggerList()) {
System.out.println("Logger name: " + l.getName() + ", Log Level: " + l.getLevel());
}
PatternLayoutEncoder ple = this.getPatternEncoder(lp);
ple.setContext(lctx);
ple.stop();
ple.start();
System.out.println("Log pattern used: " + ple.getPattern());
// Appenders
ConsoleAppender<ILoggingEvent> capp = this.getConsoleAppender();
capp.setContext(lctx);
capp.setEncoder(ple);
capp.stop();
capp.start();
RollingFileAppender<ILoggingEvent> rfapp = this.getRollingFileAdapter(lctx, ple);
rfapp.stop();
rfapp.start();
Logger rootLogger = lctx.getLogger(Logger.ROOT_LOGGER_NAME);
lctx.stop();
rootLogger.detachAndStopAllAppenders();
rootLogger.addAppender(rfapp);
rootLogger.addAppender(capp);
Iterator<Appender<ILoggingEvent>> apps = rootLogger.iteratorForAppenders();
while(apps.hasNext()) {
Appender<ILoggingEvent> app = apps.next();
System.out.println("Appender added: " + app.getName());
}
lctx.start();
rootLogger.debug("Logger context created.");
return lctx;
}
public RollingFileAppender<ILoggingEvent> getRollingFileAdapter(LoggerContext lctx, PatternLayoutEncoder ple) {
RollingFileAppender<ILoggingEvent> appender = new RollingFileAppender<ILoggingEvent>();
appender.setName("ApplicationRollingFileAppender");
appender.setFile("target/log/application.log");
appender.setContext(lctx);
appender.setEncoder(ple);
TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new TimeBasedRollingPolicy<>();
rollingPolicy.setContext(lctx);
rollingPolicy.setParent(appender);
rollingPolicy.setFileNamePattern("target/log/application.%d{yyyy-MMM-dd_HH:mm:ss}.log");
rollingPolicy.setMaxHistory(30);
SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
triggeringPolicy.setContext(lctx);
triggeringPolicy.setMaxFileSize("1KB");
appender.setRollingPolicy(rollingPolicy);
appender.setTriggeringPolicy(triggeringPolicy);
rollingPolicy.stop();
triggeringPolicy.stop();
rollingPolicy.start();
triggeringPolicy.start();
return appender;
}
public ConsoleAppender<ILoggingEvent> getConsoleAppender() {
ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
appender.setName("ApplicationConsoleAppender");
return appender;
}
public PatternLayoutEncoder getPatternEncoder(Properties props) {
if (props == null) {
props = this.readLogbackProperties();
}
String pattern = "%msg%n";
if (props.containsKey("PATTERN")) {
pattern = props.getProperty("PATTERN");
}
PatternLayoutEncoder ple = new PatternLayoutEncoder();
ple.setPattern(pattern);
return ple;
}
public void setLoggerLevels(LoggerContext lctx, Properties props) {
if (props == null) {
props = this.readLogbackProperties();
}
for(String lname: props.stringPropertyNames()) {
if (lname.startsWith("SET_LOGBACK_LEVEL_")) {
String level = props.getProperty(lname);
String pname = lname.substring(18);
lctx.getLogger(pname).setLevel(Level.valueOf(level));
}
}
}
public Properties readLogbackProperties() {
ClassPathResource cpr = new ClassPathResource("day3/logback/logback.properties");
Properties p = new Properties();
try {
p.load(cpr.getInputStream());
} catch (IOException e) {
throw new IllegalArgumentException("Failed to find day3/logback/logback.properties in classpath. " + e.getMessage());
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("Failed to read day3/logback/logback.properties in classpath. File might contain a malformed Unicode escape sequence. " + iae.getMessage());
}
return p;
}
}
Junit测试
public class AppConfigJunitTest {
@Autowired
LoggerContext lctx;
@Test
public void testLoggerContext() {
Logger logger = lctx.getLogger(this.getClass());
logger.debug("Debug message");
logger.error("Error message");
logger.info("Info message");
logger.trace("Trace message");
logger.warn("Warn message");
assertNotNull(lctx);
}
}
在 cosole 上打印的输出:
Logger name: ROOT, Log Level: DEBUG
Logger name: com, Log Level: null
Logger name: com.rsa, Log Level: null
Logger name: com.rsa.springclasses, Log Level: null
Logger name: com.rsa.springclasses.day3, Log Level: null
Logger name: com.rsa.springclasses.day3.logback, Log Level: DEBUG
Logger name: com.rsa.springclasses.day3.logback.AppConfigJunitTest, Log Level: DEBUG
Logger name: org, Log Level: null
Logger name: org.hibernate, Log Level: ERROR
Logger name: org.hibernate.type, Log Level: ERROR
Log pattern used: %date{yyyy-MMM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{36} %msg%n
Appender added: ApplicationRollingFileAppender
Appender added: ApplicationConsoleAppender
在日志文件中打印的日志:
2016-Aug-18_22:50:31.862 [main] DEBUG ROOT Logger context created.
2016-Aug-18_22:50:31.862 [main] DEBUG ROOT Logger context created.
2016-Aug-18_22:50:31.909 [main] DEBUG c.r.s.d.logback.AppConfigJunitTest Debug message
2016-Aug-18_22:50:31.909 [main] DEBUG c.r.s.d.logback.AppConfigJunitTest Debug message
2016-Aug-18_22:50:31.909 [main] ERROR c.r.s.d.logback.AppConfigJunitTest Error message
2016-Aug-18_22:50:31.909 [main] ERROR c.r.s.d.logback.AppConfigJunitTest Error message
2016-Aug-18_22:50:31.909 [main] INFO c.r.s.d.logback.AppConfigJunitTest Info message
2016-Aug-18_22:50:31.909 [main] INFO c.r.s.d.logback.AppConfigJunitTest Info message
2016-Aug-18_22:50:31.909 [main] WARN c.r.s.d.logback.AppConfigJunitTest Warn message
2016-Aug-18_22:50:31.909 [main] WARN c.r.s.d.logback.AppConfigJunitTest Warn message