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

时间:2022-01-30 22:57:10

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}是一个已定义的系统变量(linux上的echo $ MY_HOME显示正确的路径)。

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的地方。对于那个很抱歉

6 个解决方案

#1


48  

Contrary to what the others have said, the logback documentation explicitly states that "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.

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

#2


20  

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

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

LoggerStartupListener.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) {
    }
}

#3


10  

You perhaps mean MY_HOME. In your config file there is reference for OSC_HOME. See Variable substitution rules 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>

#4


1  

If you're using Eclipse you have to restart it to pick up environment variables, but you can't use: File -> Restart

如果您正在使用Eclipse,则必须重新启动它以获取环境变量,但您无法使用:文件 - >重新启动

Instead you actually have to fully shut it down and then start it back up again.

相反,你实际上必须完全关闭它然后再次启动它。

#5


-2  

Instead of using environmental variables, you can use tag to declare variables in logback.xml.

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

#6


-4  

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 :)

#1


48  

Contrary to what the others have said, the logback documentation explicitly states that "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.

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

#2


20  

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

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

LoggerStartupListener.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) {
    }
}

#3


10  

You perhaps mean MY_HOME. In your config file there is reference for OSC_HOME. See Variable substitution rules 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>

#4


1  

If you're using Eclipse you have to restart it to pick up environment variables, but you can't use: File -> Restart

如果您正在使用Eclipse,则必须重新启动它以获取环境变量,但您无法使用:文件 - >重新启动

Instead you actually have to fully shut it down and then start it back up again.

相反,你实际上必须完全关闭它然后再次启动它。

#5


-2  

Instead of using environmental variables, you can use tag to declare variables in logback.xml.

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

#6


-4  

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 :)