java 如何在 log4j2.02 中以编程方式配置 Logger?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26668938/
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
How to configure Logger Programmatically in log4j2.02?
提问by Eastsun
I want to use log4j withoutany configure file. What I wan to do is something as:
我想在没有任何配置文件的情况下使用 log4j 。我想做的是:
logger = (Logger) LogManager.getLogger(this.getClass());
String pattern = "[%level] %m%n";
//do something to make this logger output to an local file "/xxx/yyy/zzz.log"
I have found this answer: Configuring Log4j Loggers Programmatically.
我找到了这个答案:以 编程方式配置 Log4j 记录器。
But the docs of Logger#addAppender
says:
This method is notexposed through the public API and is used primarily for unit testing.
但是文档Logger#addAppender
说:
这个方法不是通过公共 API 公开的,主要用于单元测试。
I am not sure if it is the right way to use this method in my code or there is other better solution to solve my problem.
我不确定在我的代码中使用这种方法是否正确,或者是否有其他更好的解决方案来解决我的问题。
回答by ToYonos
The official documentationshows an example : Programatically Adding to the Current Configuration
官方文档展示了一个例子:Programatically Add to the Current Configuration
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
Layout layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null, null,null, null);
Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true", "false", "false", "4000", layout, null, "false", null, config);
appender.start();
config.addAppender(appender);
AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
AppenderRef[] refs = new AppenderRef[] {ref};
LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", "org.apache.logging.log4j", "true", refs, null, config, null );
loggerConfig.addAppender(appender, null, null);
config.addLogger("org.apache.logging.log4j", loggerConfig);
ctx.updateLoggers();
With these limitations :
有这些限制:
- If the configuration file is changed the configuration will be reloaded and the manual changes will be lost.
- Modification to the running configuration requires that all the methods being called (addAppender and addLogger) be synchronized.
- 如果配置文件被更改,配置将被重新加载并且手动更改将丢失。
- 对运行配置的修改要求所有被调用的方法(addAppender 和 addLogger)都是同步的。
This solution avoids to use method from the core implementation org.apache.logging.log4j.core.Logger
, and it avoids dirty cast like that :
此解决方案避免使用核心实现中的方法org.apache.logging.log4j.core.Logger
,并且避免了像这样的脏转换:
import org.apache.logging.log4j.Logger;
Logger logger = (Logger) LogManager.getLogger(this.getClass());
((org.apache.logging.log4j.core.Logger) logger).addAppender(...); // Bypassing the public API
回答by Dev
With the latest version of log4j2
, all create the APIs like
使用最新版本的log4j2
,都创建了像
PatternLayout.createLayout,
FileAppender.createAppender,
LoggerConfig.createLogger
have become deprecated, it's better to use a custom log ConfigurationFactory
along with ConfigurationBuilder
for defining the log configuration programmatically.
已被弃用,最好使用自定义日志ConfigurationFactory
以及以ConfigurationBuilder
编程方式定义日志配置。
回答by will
If I simply respond to your requirement, I can suggest three options. I use the first one for a kind of bootstrap Logger config; however I thought the second would be necessary at first. Your third choice seems cumbersome since you need to call different log4j API-s to get configured.
如果我只是回应您的要求,我可以提出三个选项。我将第一个用于一种引导记录器配置;但是我认为一开始需要第二个。您的第三个选择似乎很麻烦,因为您需要调用不同的 log4j API-s 来进行配置。
Using Log4j over the simple logging framework for Java ...
在 Java 的简单日志记录框架上使用 Log4j ...
Make a 'minimal' or 'default' log4j.properties file in your resources for the JAR file. Then declare some statics...
private static final URL LOGGER_CONFIG_URL = resolveConfigUrl(); : private static URL resolveConfigUrl(){ URL url = LogConfig.class.getResource( LOGGER_CONFIG_NAME ); if( null == url ) // Second chance, try for a file. { url = FileHelp.resolveUrlNameAsUrlToFile( LOGGER_CONFIG_NAME ); //-- Make this function with: url = tmpFile.toURI().toURL() // Plus appropriate try/catch and error checks. } return url; } private static void configureLogger(){ BasicConfigurator.configure(); PropertyConfigurator.configure( LOGGER_CONFIG_URL ); LOG.info( "Logging config done: " + LOGGER_CONFIG_NAME ); }
Write your config to a StreamWriter instead of placing a file in your JAR, and then give the Stream to the log configurator as a StringReader and use the example above (more or less).
You can use the slf4j APIto do your log config, rather than write direct to Log4j. Most places I've been prefer the SLF4J route.
在 JAR 文件的资源中创建一个“最小”或“默认”log4j.properties 文件。然后声明一些静态...
private static final URL LOGGER_CONFIG_URL = resolveConfigUrl(); : private static URL resolveConfigUrl(){ URL url = LogConfig.class.getResource( LOGGER_CONFIG_NAME ); if( null == url ) // Second chance, try for a file. { url = FileHelp.resolveUrlNameAsUrlToFile( LOGGER_CONFIG_NAME ); //-- Make this function with: url = tmpFile.toURI().toURL() // Plus appropriate try/catch and error checks. } return url; } private static void configureLogger(){ BasicConfigurator.configure(); PropertyConfigurator.configure( LOGGER_CONFIG_URL ); LOG.info( "Logging config done: " + LOGGER_CONFIG_NAME ); }
将您的配置写入 StreamWriter 而不是在 JAR 中放置文件,然后将 Stream 作为 StringReader 提供给日志配置器并使用上面的示例(或多或少)。
您可以使用slf4j API进行日志配置,而不是直接写入 Log4j。我去过的大多数地方都喜欢 SLF4J 路线。
Personally, I prefer option #1; it is easy to maintain. simple and you can always re-order the code to accept/look for a file to load first. There are some other lateral avenues you can consider, such as setting environment variables programmatically at start-up. That seems contrived to me.
就个人而言,我更喜欢选项#1;易于维护。简单,您可以随时重新排序代码以接受/查找要首先加载的文件。您还可以考虑其他一些横向途径,例如在启动时以编程方式设置环境变量。这对我来说似乎是人为的。
The way I use #1 is to establish a default / bootstrap logger configuration via the resources file, which itself gets wrapped into the JAR file. You can reconfigure things 'later' while this option gives you a minimalist star-up or bootstrap config. In the early stages I found things weren't (yet) being logged because the logger initialisation was yet to happen on embedded apps. So I kept the simple option for bootstrap (or default) as a basic ever since. Hope this helps.
我使用 #1 的方法是通过资源文件建立默认/引导记录器配置,资源文件本身被包装到 JAR 文件中。您可以“稍后”重新配置,而此选项为您提供极简的启动或引导配置。在早期阶段,我发现事情还没有(还)被记录,因为记录器初始化尚未在嵌入式应用程序上发生。所以我一直将引导程序(或默认)的简单选项作为基本选项。希望这可以帮助。