web-dev-qa-db-ja.com

TomcatWAR-パスでアプリ名を使用するようにログバックを構成します

WARファイルのlibフォルダーにlogbackをデプロイし、classesフォルダーに次のlogback.xmlを作成しました。

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
  <property name="destination" value="${catalina.base:-./temp}/logs/${appName:-myapp}" />

  <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${destination}.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- rollover daily -->
      <fileNamePattern>${destination}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
      <!-- Keep logs for 7 days -->
      <maxHistory>7</maxHistory>

      <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <!-- or whenever the file size reaches 100MB -->
        <maxFileSize>100MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="error">
    <appender-ref ref="ROLLING" />
  </root>
</configuration>

3行目には、ログファイルのパスを作成するいくつかの変数置換があります。

  <property name="destination" value="${catalina.base:-./temp}/logs/${appName:-myapp}" />

${appName}がデプロイされたwarファイルの現在の名前に評価されるようにしたいと思います。

だから私のウェブアプリフォルダがそうだったら

webapps
 - myapp.war
 - myapp-dev.war

Myapp.warの${destination}プロパティは.../logs/myappと評価され、myapp-dev.warは.../logs/myapp-devと評価されます。 appNameにアクセスするためにアクセスできるJNDIプロパティまたは何かがありますか?

ロガーを手動で再構成する必要はありません。

ありがとう!

16
HaxElit

EDIT 2013-06:このListenerをMavenCentralでOSSとして利用できるようにしました。 プロジェクトのホームページ をチェックしてください。

はい、これは実行可能です。まず第一に、Tomcatは実行されないため、いつでもcatalina.baseに依存できます。コンテキスト名をプロパティとして挿入するため。コンテキストを記述します listener これにより、コンテキスト名がJNDIコンテキストに配置され、シャットダウン時に削除されます。それが完了したら、ログバックを使用してJNDIで直接値を取得できます。それを直接サポートしています。これをcontextName要素に書き込むと、完了です。

私はすでにこれを自分で実装しており、すべてのプロジェクトで機能します。あなたや他の誰かが興味を持っているなら、私は月曜日にコード全体を共有することができます。

編集、ここにコードがあります:

import org.Apache.catalina.Context;
import org.Apache.catalina.Lifecycle;
import org.Apache.catalina.LifecycleEvent;
import org.Apache.catalina.LifecycleListener;
import org.Apache.catalina.deploy.ContextEnvironment;
import org.Apache.commons.lang.StringUtils;
import org.Apache.juli.logging.Log;
import org.Apache.juli.logging.LogFactory;

public class LogbackContextNameListener implements LifecycleListener {

    private static final Log logger = LogFactory
            .getLog(LogbackContextNameListener.class);
    private Context context;

    private String name = "logback/contextName";

    @Override
    public void lifecycleEvent(LifecycleEvent le) {

        if (le.getLifecycle() instanceof Context)
            context = (Context) le.getLifecycle();
        else
            return;

        if (le.getType().equals(Lifecycle.START_EVENT)) {
            ContextEnvironment ce = new ContextEnvironment();
            ce.setName(getName());
            ce.setOverride(false);
            ce.setType("Java.lang.String");
            String value = StringUtils.remove(context.getServletContext()
                    .getContextPath(), '/');
            ce.setValue(value);
            logger.debug(String.format("Adding env entry '%s' with value '%s'",
                    getName(), value));
            context.getNamingResources().addEnvironment(ce);
        }

        if (le.getType().equals(Lifecycle.STOP_EVENT)) {
            logger.debug(String.format("Removing env entry '%s'", getName()));
            context.getNamingResources().removeEnvironment(name);
        }

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (StringUtils.isEmpty(name))
            throw new IllegalArgumentException(
                    "Parameter 'name' cannot be empty");

        this.name = name;
    }

}

適切な構成は次のようになります。

<configuration scan="true" scanPeriod="30 minutes">

    <insertFromJNDI env-entry-name="Java:comp/env/logback/contextName" as="contextName" />
    <contextName>${contextName}</contextName>

    <appender name="FILE"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${catalina.base}/logs/${CONTEXT_NAME}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>${catalina.base}/logs/${CONTEXT_NAME}.log.%d.gz</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%-27(%d{HH:mm:ss.SSS} [%.-12thread]) %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO"><!-- WARN -->
        <appender-ref ref="FILE" />
    </root>

</configuration>

これはTomcat6で問題なく動作します。おそらく、変更なしでTomcat7で実行されます。

10
Michael-O

これはMichael-Oの答えに基づいています。それを考慮してcatalina.baseは、Tomcatで実行する場合は常に定義されたシステムプロパティであり、appNameの定義についてのみ心配する必要があります。 Logbackは、 JNDIから変数を取得する のサポートを提供します。 appNameがJNDIで定義されている場合、構成ファイルは次のようになります。

<configuration>
  <!-- retrieve appName from JNDI to set the variable appName -->
  <insertFromJNDI env-entry-name="Java:comp/env/appName" as="appName" />
  <!-- let the context name be the applicaiton name -->
  <contextName>${appName}</contextName>

  <property name="destination" 
            value="${catalina.base:-./temp}/logs/${CONTEXT_NAME:-myapp}" />

  <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${destination}.log</file>
    ... remainder of config file omitted for brevity  
  </appender>
</configuration>

JNDIではなくlogback.xmlでappNameを直接定義することもできます。 (結局のところ、logback.xmlファイルはその名前がす​​でに確立されているWebアプリに付属しています。ただし、質問ではこの仮説が明示的に除外されています。)したがって、logback.xmlファイルは次のように簡略化できます。

<configuration>
  <contextName>the_name_of_your_webapp</contextName>
  <property name="destination" 
            value="${catalina.base:-./temp}/logs/${CONTEXT_NAME:-myapp}" />
   ... the rest omitted for brevity
</configuration? 

ところで、満足のいく解決策を見つけたら、logback-userリストに投稿してそれを共有することを躊躇しないでください。

4
Ceki

それはContextSelectorではありませんか? ContextJNDISelectorとここをご覧ください http://logback.qos.ch/manual/contextSelector.html

1
thomasmey

maxHistoryは、ログファイルの数を意味するものではありません。それは月数を意味します。

0
Dawoon Yi