Java 以编程方式设置 Logback Appender 路径
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3803184/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting Logback Appender path programmatically
提问by yshalbar
I'm trying to set Logback appender path programmatically. (RollingFileAppenderwith FixedWindowRollingPolicy to be exact)
我正在尝试以编程方式设置 Logback appender 路径。(确切地说是带有 FixedWindowRollingPolicy 的RollingFileAppender)
I'm doing this because I want to enable my users to set the log path in a preference dialog (Eclipse RCP)
我这样做是因为我想让我的用户在首选项对话框(Eclipse RCP)中设置日志路径
I've tried something like this, but I doesn't change the log path from what's defined in the configuration file:
我试过这样的事情,但我没有改变配置文件中定义的日志路径:
Logger logback_logger = (ch.qos.logback.classic.Logger)LoggerFactory
.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
RollingFileAppender<ILoggingEvent> rfappender =
(RollingFileAppender<ILoggingEvent>)logback_logger.getAppender("FILE");
rfappender.setFile(newFile);
FixedWindowRollingPolicy rollingPolicy =
(FixedWindowRollingPolicy)rfappender.getRollingPolicy();
rollingPolicy.setFileNamePattern(newPattern);
采纳答案by yshalbar
Using system properties and reloading the configuration file seems cleaner:
使用系统属性并重新加载配置文件似乎更清晰:
change the logback.xml file:
更改 logback.xml 文件:
<file>${log_path:-}myfile.log</file>
....
<FileNamePattern>${log_path:-}myfile.%i.log</FileNamePattern>
This will set the default location to the working directory. Then, use:
这会将默认位置设置为工作目录。然后,使用:
System.setProperty("log_path", my_log_path);
//Reload:
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
ContextInitializer ci = new ContextInitializer(lc);
lc.reset();
try {
//I prefer autoConfig() over JoranConfigurator.doConfigure() so I wouldn't need to find the file myself.
ci.autoConfig();
} catch (JoranException e) {
// StatusPrinter will try to log this
e.printStackTrace();
}
StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
回答by yshalbar
Looking at the Logback code, I have found a workaround:
查看 Logback 代码,我找到了一个解决方法:
rollingPolicy.stop();
rfappender.stop();
rollingPolicy.start();
rfappender.start();
This causes Logback to use the new definitions. It still feels like a workaround, though.
这会导致 Logback 使用新定义。不过,它仍然感觉像是一种解决方法。
回答by Ceki
Once you programmatically configure your appender, you need invoke its start()
method. If the appender has sub-components, invoke start()
on the sub-components first. You then add the appender to the logger of your choice.
以编程方式配置 appender 后,您需要调用它的start()
方法。如果 appender 有子组件,先调用start()
子组件。然后将 appender 添加到您选择的记录器中。
Here is an example:
下面是一个例子:
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
import ch.qos.logback.core.util.StatusPrinter;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
public class Main {
public static void main(String[] args) {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
RollingFileAppender rfAppender = new RollingFileAppender();
rfAppender.setContext(loggerContext);
rfAppender.setFile("testFile.log");
FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy();
rollingPolicy.setContext(loggerContext);
// rolling policies need to know their parent
// it's one of the rare cases, where a sub-component knows about its parent
rollingPolicy.setParent(rfAppender);
rollingPolicy.setFileNamePattern("testFile.%i.log.zip");
rollingPolicy.start();
SizeBasedTriggeringPolicy triggeringPolicy = new ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy();
triggeringPolicy.setMaxFileSize("5MB");
triggeringPolicy.start();
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(loggerContext);
encoder.setPattern("%-4relative [%thread] %-5level %logger{35} - %msg%n");
encoder.start();
rfAppender.setEncoder(encoder);
rfAppender.setRollingPolicy(rollingPolicy);
rfAppender.setTriggeringPolicy(triggeringPolicy);
rfAppender.start();
// attach the rolling file appender to the logger of your choice
Logger logbackLogger = loggerContext.getLogger("Main");
logbackLogger.addAppender(rfAppender);
// OPTIONAL: print logback internal status messages
StatusPrinter.print(loggerContext);
// log something
logbackLogger.debug("hello");
}
}
The above code is the programmatic expression of the steps taken by the logback's XML configurator, i.e. Joran, when it parses the RollingFixedWindow.xmlfile.
上面的代码是 logback 的 XML 配置器(即 Joran)在解析RollingFixedWindow.xml文件时所采取的步骤的编程表达。