我只是不喜欢Logback的XML或Groovy配置,并且更喜欢用Java进行配置(这也是因为我将在初始化后的不同时间在运行时更改配置)。
似乎进行Logback的Java配置的唯一方法是进行某种初始化hijacks the root appender或具有自定义系统属性,告诉logback不使用默认配置(这对单元测试来说相当烦人)和部署)。
我更喜欢的是logback.xml
:
<configuration javaConfig="com.myco.LogBackConfig" />
其中LogbackConfig有一些已建立的静态方法可以进行logback调用,或者它只是重新实例化一个Java bean。
这就是我想要一个默认的类路径资源,它会告诉logback使用Java而不是groovy / xml。基本上我想要一些类似于Java ServiceLoader的logback配置。
也许有一种方法可以在Logback中做到这一点,我错过了?
更新 显然是Log4j2 (the new log4j) does exactly what I want,与Java ServiceLoader非常相似。
答案 0 :(得分:3)
此功能刚刚合并到logback的源代码中。见https://github.com/qos-ch/logback/pull/181
答案 1 :(得分:2)
这是一个绝对的黑客,但我认为它适用于你的情况:
在logback.xml文件中,将扫描设置为较短的时间间隔:http://logback.qos.ch/manual/configuration.html#autoScan
然后让您的代码修改后备文件,设置适当的级别。
Logback将重新扫描xml文件并应用更改。
答案 2 :(得分:1)
另一种方式。
logback version:1.1.2
<强> logback.xml 强>
<configuration debug="true">
<contextListener class="com.example.log.CustomLoggerContextListener"/>
</configuration>
<强> CustomLoggerContextListener.java 强>
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.LoggerContextListener;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.spi.LifeCycle;
public class CustomLoggerContextListener extends ContextAwareBase implements LoggerContextListener, LifeCycle {
private boolean started = false;
@Override
public void start() {
if (started) return;
LoggerContext lctx = (LoggerContext) getContext();
LoggerConfigurer configurer = new LoggerConfigurer();
configurer.configure(lctx);
started = true;
}
@Override
public void stop() {
}
@Override
public boolean isStarted() {
return started;
}
@Override
public boolean isResetResistant() {
return true;
}
@Override
public void onStart(LoggerContext context) {
}
@Override
public void onReset(LoggerContext context) {
}
@Override
public void onStop(LoggerContext context) {
}
@Override
public void onLevelChange(Logger logger, Level level) {
}
}
<强> LoggerConfigurer.java 强>
import ch.qos.logback.classic.AsyncAppender;
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.filter.ThresholdFilter;
import ch.qos.logback.classic.html.HTMLLayout;
import ch.qos.logback.classic.net.SMTPAppender;
import ch.qos.logback.classic.spi.ILoggingEvent;
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;
import ch.qos.logback.core.spi.CyclicBufferTracker;
import ch.qos.logback.core.status.InfoStatus;
import ch.qos.logback.core.status.StatusManager;
import java.io.File;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
public class LoggerConfigurer {
public void configure(LoggerContext loggerContext) {
loggerContext.reset();
StatusManager sm = loggerContext.getStatusManager();
if (sm != null) {
sm.add(new InfoStatus("Setting configuration from " + getClass().getName(), loggerContext));
}
/**
* Root Level
*/
Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(Level.INFO);
/**
* Custom Log Levels
*/
loggerContext.getLogger("com.example.package1").setLevel(Level.INFO);
loggerContext.getLogger("com.example.package2").setLevel(Level.DEBUG);
/**
* Console Appender
*/
configureConsoleAppender(loggerContext, rootLogger);
/**
* File Appender
*/
configureFileAppender(loggerContext, rootLogger);
/**
* SMTP Mail Appender
*/
configureMailAppender(loggerContext, rootLogger);
}
protected void configureConsoleAppender(LoggerContext loggerContext, Logger rootLogger) {
ConsoleAppender<ILoggingEvent> consoleAppender = new ConsoleAppender<ILoggingEvent>();
consoleAppender.setContext(loggerContext);
consoleAppender.setName("myapp-log-console");
consoleAppender.setEncoder(getEncoder(loggerContext));
consoleAppender.start();
rootLogger.addAppender(consoleAppender);
}
protected void configureFileAppender(LoggerContext loggerContext, Logger rootLogger) {
String logFileName = "MY_LOG_FILE";
String maxFileSize = "500mb";
String logPath = "~/myAppLogs";
int maxHistory = 7;
String fileLogLevel = "WARN"; // if needed
logPath = parseLogPath(logPath);
logFileName = parseLogFileName(logFileName);
RollingFileAppender<ILoggingEvent> rollingFileAppender = new RollingFileAppender<ILoggingEvent>();
rollingFileAppender.setContext(loggerContext);
rollingFileAppender.setName("log-file");
rollingFileAppender.setFile(logPath + File.separator + logFileName + ".log");
rollingFileAppender.setEncoder(getEncoder(loggerContext));
rollingFileAppender.setAppend(true);
TimeBasedRollingPolicy rollingPolicy = new TimeBasedRollingPolicy();
rollingPolicy.setContext(loggerContext);
rollingPolicy.setParent(rollingFileAppender);
rollingPolicy.setFileNamePattern(logFileName + "-%d{yyyy-MM-dd}.log");
rollingPolicy.setMaxHistory(maxHistory);
rollingPolicy.start();
SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<ILoggingEvent>();
triggeringPolicy.setContext(loggerContext);
triggeringPolicy.setMaxFileSize(maxFileSize);
triggeringPolicy.start();
rollingFileAppender.setRollingPolicy(rollingPolicy);
rollingFileAppender.setTriggeringPolicy(triggeringPolicy);
ThresholdFilter fileThresholdFilter = new ThresholdFilter();
fileThresholdFilter.setName("file-thresholdFilter");
fileThresholdFilter.setLevel(fileLogLevel);
fileThresholdFilter.start();
rollingFileAppender.start();
AsyncAppender fileAsyncAppender = new AsyncAppender();
fileAsyncAppender.setContext(loggerContext);
fileAsyncAppender.setName(rollingFileAppender.getName() + "-async");
fileAsyncAppender.addAppender(rollingFileAppender);
fileAsyncAppender.setDiscardingThreshold(0);
fileAsyncAppender.start();
rootLogger.addAppender(fileAsyncAppender);
}
protected void configureMailAppender(LoggerContext loggerContext, Logger rootLogger) {
List<String> toMails = Arrays.asList("mail1@mail.com", "mail2@mail.com");
String host = "mail.host";
Integer port = 22;
String username = "mail.user";
String password = "mail.password";
String from = "mail.from";
String subject = "mail.subject";
Boolean startTLS = true;
String mailLogLevel = "ERROR"; // if needed
HTMLLayout htmlLayout = new HTMLLayout();
htmlLayout.setContext(loggerContext);
htmlLayout.setTitle(subject);
htmlLayout.start();
SMTPAppender smtpAppender = new SMTPAppender();
smtpAppender.setContext(loggerContext);
smtpAppender.setName("log-mail");
smtpAppender.setSMTPHost(host);
smtpAppender.setSMTPPort(port);
smtpAppender.setUsername(username);
smtpAppender.setPassword(password);
smtpAppender.setFrom(from);
smtpAppender.setSTARTTLS(startTLS);
smtpAppender.setSubject(subject);
smtpAppender.setLayout(htmlLayout);
CyclicBufferTracker<ILoggingEvent> cyclicBufferTracker = new CyclicBufferTracker<ILoggingEvent>();
cyclicBufferTracker.setBufferSize(1);
smtpAppender.setCyclicBufferTracker(cyclicBufferTracker);
ThresholdFilter mailThresholdFilter = new ThresholdFilter();
mailThresholdFilter.setName("mail-thresholdFilter");
mailThresholdFilter.setLevel(mailLogLevel);
mailThresholdFilter.start();
smtpAppender.addFilter(mailThresholdFilter);
/**
* to mail addresses
*/
for (String toMail : toMails) {
smtpAppender.addTo(toMail);
}
smtpAppender.start();
AsyncAppender mailAsyncAppender = new AsyncAppender();
mailAsyncAppender.setContext(loggerContext);
mailAsyncAppender.setName(smtpAppender.getName() + "-async");
mailAsyncAppender.addAppender(smtpAppender);
mailAsyncAppender.setDiscardingThreshold(0);
mailAsyncAppender.start();
rootLogger.addAppender(mailAsyncAppender);
}
private PatternLayoutEncoder getEncoder(LoggerContext loggerContext) {
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(loggerContext);
encoder.setPattern("%d{HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n");
encoder.setCharset(Charset.forName("UTF-8"));
encoder.start();
return encoder;
}
private String parseLogFileName(String logFileName) {
if (logFileName.startsWith("/") || logFileName.startsWith("\\")) {
logFileName = logFileName.substring(1);
}
return logFileName;
}
private String parseLogPath(String logPath) {
if (logPath.startsWith("~")) {
logPath = logPath.replaceFirst("~", System.getProperty("user.home"));
}
if (logPath.endsWith("/") || logPath.endsWith("\\")) {
logPath = logPath.substring(0, logPath.length() - 1);
}
return logPath;
}
}