79

私はこの 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}は定義済みのシステム変数です ( echo $MY_HOMELinux では正しいパスが表示されます)。

問題は、ログバックが正しく読み取っていないように見えることです。ログは次の場所に保存されますMY_HOME_IS_UNDEFINED/logs/my.log

私は何を間違っていますか?どうもありがとう!

編集: 私は間違いを犯し、本当に MY_HOME を意味する場所に OSC_HOME を置きました。ごめんなさい

4

6 に答える 6

74

他の人が言ったこととは反対に、ログバックドキュメントには、「置換中、プロパティは最初にローカルスコープで、次にコンテキストスコープで、3番目にシステムプロパティスコープで、4番目で最後にOS環境で検索される」と明示的に記載されています。 。したがって、プロパティが環境で定義されている場合、logbackはそれを検出します。

Eclipseでプロジェクトを実行しているときに同じ問題が発生していました。MY_HOMEそれが問題である場合は、[構成の実行]-> [環境]に移動し、環境変数に追加することで修正できます。

デフォルトでネイティブ環境をロードしない理由はよくわかりません。「ネイティブ環境に環境を追加する」というオプションもありますが、効果がないようです。

于 2012-04-11T15:57:27.287 に答える
33

構成ファイルから環境変数を読み取る別の方法があります。コンテキストリスナーを使用して、カスタム変数を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

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) {
    }
}
于 2014-05-31T11:49:51.807 に答える
18

あなたはおそらく意味しMY_HOMEます。構成ファイルには、 への参照がありますOSC_HOME。詳しくは、Logback の変数置換規則を参照してください。

環境変数を 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>
于 2009-12-29T18:16:03.143 に答える
2

Eclipse を使用している場合は、環境変数を取得するために再起動する必要がありますが、使用することはできません: ファイル -> 再起動

代わりに、実際には完全にシャットダウンしてから、再度起動する必要があります。

于 2012-12-04T21:33:25.843 に答える
-5

物事は実際に設計どおりに機能しています。変数置換を行うときに、logback は環境変数をまったく読み取りません。ドキュメントの引用:

置換変数の値は、構成ファイル自体、外部プロパティ ファイル、またはシステム プロパティとして定義できます。

したがって、前述のソリューションのいずれかを使用するか、取得してOSC_HOME_IS_UNDEFINEDください:)

于 2009-12-29T18:43:52.553 に答える
-6

環境変数を使用する代わりに、タグを使用して logback.xml で変数を宣言できます。

于 2014-07-16T05:11:43.613 に答える