Java 从logback配置文件中读取环境变量

Java 从logback配置文件中读取环境变量,java,logging,environment-variables,logback,Java,Logging,Environment Variables,Logback,我有这个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&

我有这个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>

%d{HH:mm:ss.SSS}[%thread]-5级别%logger{36}-%msg%n
${MY_HOME}/logs/mylog.log
logs/my.%d{yyyy-MM-dd}.log
30
%d{HH:mm:ss.SSS}[%thread]-5级别-%msg%n
${MY_HOME}
是一个已定义的系统变量(
echo$MY_HOME
在linux上显示正确的路径)

问题是,logback似乎没有正确读取它,它将日志存储在
MY\u HOME\u is\u UNDEFINED/logs/MY.log

我做错了什么?非常感谢


编辑:我犯了一个错误,把OSC_放在了我真正的家里。很抱歉

你可能是说
我家
。在您的配置文件中有
OSC\u HOME
的参考。有关详细信息,请参见回登录规则

您可以将环境变量作为Java系统属性传递,然后Logback将执行变量替换。您可以在命令行中将其作为JVM选项传递。例如:

java -DMY_HOME=${MY_HOME} -cp ... MainClass
或者您可以在配置文件本身中定义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>

${MY_HOME}/logs/mylog.log

事情实际上按设计进行:在执行变量替换时,logback根本不读取环境变量。引述:

替换变量的值可以在配置文件本身、外部属性文件或系统属性中定义


因此,要么使用上述解决方案之一,要么获取未定义的OSC\u HOME(代码):

与其他解决方案所说的相反,“在替换过程中,首先在本地范围中查找属性,其次在上下文范围中查找属性,第三在系统属性范围中查找属性,第四和最后在操作系统环境中查找属性。”. 因此,如果该属性是在环境中定义的,则logback将找到它

在Eclipse中运行项目时,我遇到了同样的问题。如果这是您遇到的问题,可以通过运行Configurations->Environment并向环境变量添加
MY_HOME
来解决


不确定默认情况下为什么不加载本机环境。甚至还有一个名为“将环境附加到本机环境”的选项,它似乎对我没有任何影响。

如果您使用Eclipse,您必须重新启动它以获取环境变量,但您不能使用:File->restart


实际上,您必须完全关闭它,然后重新启动它。

有另一种方法可以从配置文件中读取环境变量。您可以使用上下文监听器将自定义变量放到logback上下文中

logback.xml


[%-5level]%d{HH:mm:ss.SSS}[%.6thread]%logger-%msg%n
UTF-8
${MY_HOME}/${LOG_FILE}.LOG
真的
真的
${MY_HOME}/${LOG_FILE}.%d{yyyy-MM-dd}.LOG
7.
[%-5level]%d{HH:mm:ss.SSS}[%.6thread]%logger-%msg%n
UTF-8
LoggerStartupListener.java

package com.myapp.logging.listener;
导入ch.qos.logback.classic.Level;
导入ch.qos.logback.classic.Logger;
导入ch.qos.logback.classic.LoggerContext;
导入ch.qos.logback.classic.spi.LoggerContextListener;
导入ch.qos.logback.core.Context;
导入ch.qos.logback.core.spi.ContextAwareBase;
导入ch.qos.logback.core.spi.LifeCycle;
公共类LoggerStartupListener扩展了ContextAwareBase实现了LoggerContextListener的生命周期{
私有静态最终字符串DEFAULT\u LOG\u FILE=“MYAPP”;
private boolean start=false;
@凌驾
公开作废开始(){
如果(开始)返回;
字符串userHome=System.getProperty(“user.home”);
字符串logFile=System.getProperty(“log.file”);//log.file是我们的自定义jvm参数,用于在需要时动态更改日志文件名
logFile=(logFile!=null&&logFile.length()>0)?logFile:DEFAULT\u LOG\u FILE;
Context=getContext();
context.putProperty(“我的家”,userHome);
context.putProperty(“日志文件”,logFile);
开始=真;
}
@凌驾
公共停车场(){
}
@凌驾
公共布尔值isStarted(){
返回开始;
}
@凌驾
公共布尔值IsResestResistant(){
返回true;
}
@凌驾
public void onStart(LoggerContext上下文){
}
@凌驾
公共void onReset(LoggerContext上下文){
}
@凌驾
顶部公共空白(LoggerContext上下文){
}
@凌驾
public void onLevelChange(记录器,级别){
}
}

您可以使用标记在logback.xml中声明变量,而不是使用环境变量


在您回答中的链接中:“在替换过程中,属性首先在本地范围内查找,其次在上下文范围内查找,第三在系统属性范围内查找,最后在操作系统环境中查找。”所以它应该在操作系统环境变量上查找,对吗?@TimPote Yes,它将关注操作系统环境变量环境变量对我来说是有效的,但我必须重新启动Eclipse来获取它们。请看我对这个问题的回答,IntelliJ IDEA也是如此。完全重新启动应用程序将获取环境变量。Logback会读取操作系统环境变量。下面提到了“OS环境”,它是指向Oracle环境变量文档的链接。上面的引语确实暗示了不支持OS环境变量。但是,我在文档中找不到上述引用。当前文档明确提到OS环境变量。需要日志来包含aws ec2实例id。这是我必须采取的方法。