Jetty のログを任意のディレクトリに出力する方法

# 概要

軽量Webサーバーの[Jetty](https://www.eclipse.org/jetty/)では以下の2つのログファイルが出力されます。

* 標準出力/標準エラー出力
* アクセスログ

これらのログファイルはデフォルト状態では `jetty.base` プロパティで指定されたディレクトリ直下の `logs` に出力されます。

Jettyのリファレンス [Default Logging with Jetty’s StdErrLog](https://www.eclipse.org/jetty/documentation/current/default-logging-with-stderrlog.html) や [Configuring Jetty Request Logs](https://www.eclipse.org/jetty/documentation/current/configuring-jetty-request-logs.html) を参照しましたが、出力先を任意のディレクトリに変更する方法が分かりにくかったので本記事でまとめました。

# 内容

## 1. 標準出力/標準エラー出力ログの出力先の変更方法

ログファイルの設定は `etc/jetty-logging.xml` から行います。

```xml:jetty-logging.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">


<!-- =============================================================== -->
<!-- Configure stderr and stdout to a Jetty rollover log file        -->
<!-- this configuration file should be used in combination with      -->
<!-- other configuration files.  e.g.                                -->
<!--    java -jar start.jar etc/jetty-logging.xml                    -->
<!-- =============================================================== -->
<Configure id="logging" class="org.eclipse.jetty.util.log.Log">

    <New id="ServerLog" class="java.io.PrintStream">
      <Arg>
        <New class="org.eclipse.jetty.util.RolloverFileOutputStream">
          <Arg><Property name="jetty.logs" default="./logs"/>/yyyy_mm_dd.stderrout.log</Arg>
          <Arg type="boolean">false</Arg>
          <Arg type="int">90</Arg>
          <Arg><Call class="java.util.TimeZone" name="getTimeZone"><Arg>GMT</Arg></Call></Arg>
          <Get id="ServerLogName" name="datedFilename"/>
        </New>
      </Arg>
    </New>

    <Get name="rootLogger">
      <Call name="info"><Arg>Redirecting stderr/stdout to <Ref refid="ServerLogName"/></Arg></Call>
    </Get>
    <Call class="java.lang.System" name="setErr"><Arg><Ref refid="ServerLog"/></Arg></Call>
    <Call class="java.lang.System" name="setOut"><Arg><Ref refid="ServerLog"/></Arg></Call>

</Configure>
```

### 変更箇所

```xml
<Arg><Property name="jetty.logs" default="./logs"/>/yyyy_mm_dd.stderrout.log</Arg>
```

`jetty.logs` プロパティで指定されたディレクトリ直下(プロパティがなければ $pwd/logs)に `yyyy_mm_dd.stderrout.log` として出力されるようになっています。

対応方法としては Jetty 起動コマンドのシステムプロパティに `LOG_DIR=/test/logs` という値を指定して `jetty-logging.xml` で `LOG_DIR` を参照することでログを任意のディレクトリに出力できるようになります。

```
$ java -DLOG_DIR=/test/logs -jar start.jar
```

```xml
<Arg><Property name="LOG_DIR"/>/yyyy_mm_dd.stderrout.log</Arg>
```

この例では標準出力/標準エラー出力ログが `/test/logs/yyyy_mm_dd.stderrout.log` に出力されます。

## 2. アクセスログの出力先の変更方法

ログファイルの設定は `etc/jetty-requestlog.xml` から行います。

```xml:jetty-requestlog.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">

<!-- =============================================================== -->
<!-- Configure the Jetty Request Log                                 -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">

  <!-- =========================================================== -->
  <!-- Configure Request Log -->
  <!-- =========================================================== -->
  <Ref refid="Handlers">
    <Call name="addHandler">
      <Arg>
        <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler">
          <Set name="requestLog">
            <New id="RequestLogImpl" class="org.eclipse.jetty.server.AsyncNCSARequestLog">
              <Set name="filename"><Property name="jetty.base" default="." /><Property name="requestlog.filename" default="/logs/yyyy_mm_dd.request.log"/></Set>
              <Set name="filenameDateFormat"><Property name="requestlog.filenameDateFormat" default="yyyy_MM_dd"/></Set>
              <Set name="retainDays"><Property name="requestlog.retain" default="90"/></Set>
              <Set name="append"><Property name="requestlog.append" default="false"/></Set>
              <Set name="extended"><Property name="requestlog.extended" default="false"/></Set>
              <Set name="logCookies"><Property name="requestlog.cookies" default="false"/></Set>
              <Set name="LogTimeZone"><Property name="requestlog.timezone" default="GMT"/></Set>
            </New>
          </Set>
        </New>
      </Arg>
    </Call>
  </Ref>

</Configure>
```

### 変更箇所

```xml
<Set name="filename"><Property name="jetty.base" default="." /><Property name="requestlog.filename" default="/logs/yyyy_mm_dd.request.log"/></Set>
```

`jetty.base` プロパティで指定されたディレクトリ直下(プロパティがなければ $pwd)に `/logs/yyyy_mm_dd.request.log` として出力されるようになっています。

アクセスログは標準出力/標準エラー出力ログと違って出力先ディレクトリと出力ファイル名が個別に指定されています。
注意点としては、出力ファイル名に `logs` ディレクトリの指定がデフォルトで含まれているところです。

対応方法としては標準出力/標準エラー出力ログと同じように Jetty 起動コマンドのシステムプロパティに `LOG_DIR=/test/logs` という値を指定して `jetty-requestlog.xml` で `LOG_DIR` を参照することでログを任意のディレクトリに出力できるようになります。

```
$ java -DLOG_DIR=/test/logs -jar start.jar
```

```xml
<Set name="filename"><Property name="LOG_DIR"/><Property name="requestlog.filename" default="/yyyy_mm_dd.request.log"/></Set>
```

`requestlog.filename` プロパティの出力ファイル名からは `logs` ディレクトリの指定を取り除いてファイル名のみとしています。

この例ではアクセスログが `/test/logs/yyyy_mm_dd.request.log` に出力されます。