Java 从 logback 配置文件中读取环境变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1975939/
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
Read environment variables from logback configuration file
提问by Pablo Fernandez
I have this logback.xml file:
我有这个 logback.xml 文件:
<configuration debug="true" scan="true" scanPeriod="60 seconds">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${MY_HOME}/logs/mylog.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>logs/my.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level - %msg%n</Pattern>
</layout>
</appender>
<root level="TRACE">
<appender-ref ref="FILE"/>
</root>
</configuration>
And ${MY_HOME}
is a defined system variable (echo $MY_HOME
on linux shows the correct path).
并且${MY_HOME}
是一个已定义的系统变量(echo $MY_HOME
在 linux 上显示正确的路径)。
The thing is that logback doesnt seem to read it properly, it stores the logs under MY_HOME_IS_UNDEFINED/logs/my.log
问题是 logback 似乎没有正确读取它,它将日志存储在 MY_HOME_IS_UNDEFINED/logs/my.log
What am I doing wrong? Thanks a lot!
我究竟做错了什么?非常感谢!
EDIT: I made a mistake and put OSC_HOME where I really meant MY_HOME. Sorry about that
编辑:我犯了一个错误,把 OSC_HOME 放在我真正的意思是 MY_HOME 的地方。对于那个很抱歉
回答by Chandra Patni
You perhaps mean MY_HOME
. In your config file there is reference for OSC_HOME
. See Variable substitutionrules of Logback for details.
你也许是说MY_HOME
。在您的配置文件中有OSC_HOME
. 有关详细信息,请参阅Logback 的变量替换规则。
You can pass environment variable as a Java System property and then Logback will perform the variable substitution. You can pass this as JVM option in your command line. For example:
您可以将环境变量作为 Java System 属性传递,然后 Logback 将执行变量替换。您可以在命令行中将其作为 JVM 选项传递。例如:
java -DMY_HOME=${MY_HOME} -cp ... MainClass
Or You can define MY_HOME in your config file itself.
或者您可以在您的配置文件中定义 MY_HOME。
<configuration debug="true" scan="true" scanPeriod="60 seconds">
<property name="MY_HOME" value="/home/my" />
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${MY_HOME}/logs/mylog.log</File>
</appender>
</configuration>
回答by Pascal Thivent
Things are actually working as designed: logback doesn't read environment variables at all when doing variable substitution. Quoting the documentation:
事情实际上按设计工作:在进行变量替换时,logback 根本不读取环境变量。引用文档:
The value of the substituted variable can be defined in the configuration file itself, in an external properties file or as a system property.
替换变量的值可以在配置文件本身、外部属性文件或系统属性中定义。
So, either use one of the mentioned solutions or get OSC_HOME_IS_UNDEFINED
:)
因此,要么使用上述解决方案之一,要么获取OSC_HOME_IS_UNDEFINED
:)
回答by Tim Pote
Contrary to what the others have said, the logback documentation explicitly statesthat "During substitution, properties are looked up in the local scope first, in the context scope second, in the system properties scope third, and in the OS environment fourth and last". So if the property is defined in the environment, logback will find it.
与其他人所说的相反,logback 文档明确指出“在替换过程中,首先在本地范围内查找属性,然后在上下文范围内查找,在系统属性范围内查找第三个,在操作系统环境中查找第四个也是最后一个” . 所以如果在环境中定义了属性,logback 会找到它。
I was having the same issue when running my project in Eclipse. If that's the issue you're having, it can be fixed by going to Run Configurations -> Environment and adding MY_HOME
to the environment variables.
在 Eclipse 中运行我的项目时遇到了同样的问题。如果这是您遇到的问题,可以通过转到“运行配置”->“环境”并添加MY_HOME
到环境变量来解决。
Not really sure why it isn't loading the native environment by default. There's even an option called "Append environment to native environment" which doesn't seem to have any effect for me.
不确定为什么默认情况下它不加载本机环境。甚至还有一个名为“将环境附加到本机环境”的选项,它似乎对我没有任何影响。
回答by Brad Cupit
If you're using Eclipse you have to restart it to pick up environment variables, but you can'tuse: File -> Restart
如果您使用的是 Eclipse,则必须重新启动它以获取环境变量,但不能使用:文件 -> 重新启动
Instead you actually have to fully shut it down and then start it back upagain.
相反,您实际上必须完全关闭它,然后重新启动它。
回答by bhdrk
There is an alternative way to read environment variables from config file. you can put your custom variables to logback context with context listener.
还有一种从配置文件中读取环境变量的替代方法。您可以使用上下文侦听器将自定义变量置于 logback 上下文中。
logback.xml
登录文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" scan="true" scanPeriod="30 seconds">
<!-- THIS IS OUR CUSTOM CONTEXT LISTENER -->
<contextListener class="com.myapp.logging.listener.LoggerStartupListener"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%-5level] %d{HH:mm:ss.SSS} [%.6thread] %logger - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="FILEOUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${MY_HOME}/${LOG_FILE}.log</file>
<append>true</append>
<!-- Support multiple-JVM writing to the same log file -->
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Daily rollover -->
<fileNamePattern>${MY_HOME}/${LOG_FILE}.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- Keep 7 days' worth of history -->
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder>
<pattern>[%-5level] %d{HH:mm:ss.SSS} [%.6thread] %logger - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILEOUT"/>
</root>
</configuration>
LoggerStartupListener.java
记录器启动监听器.java
package com.myapp.logging.listener;
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.Context;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.spi.LifeCycle;
public class LoggerStartupListener extends ContextAwareBase implements LoggerContextListener, LifeCycle {
private static final String DEFAULT_LOG_FILE = "MYAPP";
private boolean started = false;
@Override
public void start() {
if (started) return;
String userHome = System.getProperty("user.home");
String logFile = System.getProperty("log.file"); // log.file is our custom jvm parameter to change log file name dynamicly if needed
logFile = (logFile != null && logFile.length() > 0) ? logFile : DEFAULT_LOG_FILE;
Context context = getContext();
context.putProperty("MY_HOME", userHome);
context.putProperty("LOG_FILE", logFile);
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) {
}
}
回答by Paramesh Korrakuti
Instead of using environmental variables, you can use tag to declare variables in logback.xml.
您可以使用 tag 在 logback.xml 中声明变量,而不是使用环境变量。