Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read environment variables from logback configuration file

I have this logback.xml file:

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

The thing is that logback doesnt seem to read it properly, it stores the logs under 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

like image 768
Pablo Fernandez Avatar asked Dec 29 '09 17:12

Pablo Fernandez


People also ask

How do I read application properties in Logback xml?

xml , you can use <springProperty> to access properties from Spring's environment including those configured in application. properties . This is described in the documentation: The tag allows you to surface properties from the Spring Environment for use within Logback.

How do I change the Logback configuration file?

Setting the location of the configuration file via a system property. You may specify the location of the default configuration file with a system property named "logback. configurationFile" . The value of this property can be a URL, a resource on the class path or a path to a file external to the application.

Does SLF4J use Logback?

Native implementation of slf4j is logback, thus using both as logger framework implies zero memory and computational overhead.


2 Answers

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.

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.

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.

like image 178
Tim Pote Avatar answered Sep 16 '22 21:09

Tim Pote


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.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

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) {     } } 
like image 35
bhdrk Avatar answered Sep 18 '22 21:09

bhdrk