Чтение переменных среды из файла конфигурации журнала
У меня есть этот файл 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>
И ${MY_HOME}
- это определенная системная переменная (echo $MY_HOME
на linux показывает правильный путь).
Дело в том, что logback, похоже, не читает его правильно, он хранит журналы под MY_HOME_IS_UNDEFINED/logs/my.log
Что я делаю неправильно? Большое спасибо!
EDIT: Я допустил ошибку и поставил OSC_HOME, где я действительно имел в виду MY_HOME. Извините, что
Ответы
Ответ 1
Вопреки тому, что говорили другие, в документации к журналу явно заявляет, что" во время подстановки свойства сначала просматриваются в локальной области, а в области контекста второй, в области свойств системы третий и в среде ОС четвертый и последний. Поэтому, если свойство определено в среде, logback найдет его.
У меня была такая же проблема при запуске моего проекта в Eclipse. Если этот вопрос у вас есть, его можно устранить, перейдя в раздел "Выполнение конфигураций → Среда" и добавив MY_HOME
к переменным среды.
Не уверен, почему он не загружает родную среду по умолчанию. Там даже опция под названием "Добавить среду в родную среду", которая, кажется, не имеет никакого эффекта для меня.
Ответ 2
Существует альтернативный способ чтения переменных среды из файла конфигурации. вы можете поместить свои пользовательские переменные в контекст регистрации с помощью контекстного прослушивателя.
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) {
}
}
Ответ 3
Возможно, вы имеете в виду MY_HOME
. В вашем файле конфигурации есть ссылка для OSC_HOME
. Подробнее см. Правила замены переменных для журнала.
Вы можете передать переменную среды как свойство Java System, а затем 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>
Ответ 4
Если вы используете Eclipse, вам нужно перезапустить его, чтобы выбрать переменные среды, но вы не можете использовать: Файл → Перезагрузка
Вместо этого вы действительно должны полностью закрыть его, а затем снова запустить его.
Ответ 5
Вместо использования переменных окружения вы можете использовать тег для объявления переменных в logback.xml.
Ответ 6
Вещи действительно работают как запроектированные: logback вообще не читает переменные среды при выполнении замены переменных. Цитирование документация:
Значение замещенной переменной может быть определено в самом файле конфигурации во внешнем файле свойств или в качестве системного свойства.
Итак, используйте одно из упомянутых решений или получите OSC_HOME_IS_UNDEFINED
:)