インメモリDB VoltDBのログ設定（ログレベル変更、タイムゾーン変更、動的にログ設定を変更など）

# VoltDBのログ設定

VoltDBではログの出力にlog4jを使用しています（log4j2ではないです）。
デフォルトの設定では、ログレベルがINFO以上のログが以下のファイルに出力されます。

[DBのルートディレクトリ]/log/voltdb.log

VoltDBのログについて以下の項目を説明していきます。

- log4jの設定ファイルを変更する
- 稼働中にlog4jの設定を変更する
- ログのタイムゾーンをGMTからJSTに変更する

VoltDBのログについての情報は、以下の公式サイトのドキュメントに詳細が記載されています。

[Administrator's Guide - Chapter 6. Logging and Analyzing Activity in a VoltDB Database](https://docs.voltdb.com/AdminGuide/ChapLogging.php)


# log4jの設定ファイル

VoltDBのデフォルトのlog4jの設定ファイルは以下のファイルが使用されます。

[VoltDBのインストールディレクトリ]/voltdb/log4j.xml

インストールディレクトリが「/opt/voltdb」の場合、次の設定ファイルが使用されます。

/opt/voltdb/voltdb/log4j.xml

デフォルトの設定では、INFO以上のログが出力され、ファイル1日ごとにローテーションされるように設定されています。

このデフォルトの設定ファイルはVoltDB固有のロギングカテゴリがすべて一覧でコメントで入っており（コメントアウトされています）。
コメントインして設定することで、カテゴリごとに簡単にログレベルを変更することができます。
設定を変更する場合は、このファイルを直接編集するか、ファイルをコピーした後で設定を変更します。

デフォルトの設定ファイルは内容は以下のようになっています。なお、コメントアウトされているカテゴリは省略しています。

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <!-- console is a special appender for the logger CONSOLE
      that allows selectively logging INFO level messages to the console.
      Appender console and appender consolefiltered must have non-intersecting
      level filters or messages will appear on the console once for each
      overlapping appender. -->
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
            value="%m%n"/>
        </layout>
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <param name="levelMin" value="TRACE"/>
            <param name="levelMax" value="INFO"/>
        </filter>
    </appender>
    <!-- console appender displays log messages with priority > INFO. -->
    <appender name="consolefiltered" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
            value="%p: %m%n"/>
        </layout>
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <param name="levelMin" value="WARN"/>
            <param name="levelMax" value="FATAL"/>
        </filter>
    </appender>
    <!-- file appender captures all loggers messages. -->
    <appender name="file" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="file" value="log/volt.log"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d   %-5p [%t] %c: %m%n"/>
        </layout>
    </appender>

   <!-- Always let CSVLoader and its ilk to write to the console. -->
    <logger name="CSVLOADER">
        <level value="INFO"/>
        <appender-ref ref="console"/>
    </logger>

    <!-- Always let the bulk loader and its ilk to write to the console. -->
    <logger name="LOADER">
        <level value="INFO"/>
        <appender-ref ref="console"/>
    </logger>

    <!-- logger to route specific informational messages to the console. -->
    <logger name="CONSOLE">
        <level value="INFO"/>
        <appender-ref ref="console"/>
    </logger>

    <root>
        <priority value="info" />
        <appender-ref ref="file" />
        <appender-ref ref="consolefiltered" />
    </root>
</log4j:configuration>
```


# log4jの設定ファイルを変更する

log4jの設定ファイルを新規に作成した場合、VoltDBデータベースを起動する前に変数LOG4J_CONFIG_PATHにlog4jの設定ファイルを指定します。
例えば、以下のように環境変数LOG4J_CONFIG_PATHを設定し、VoltDBを起動します。

```console
$ LOG4J_CONFIG_PATH="/opt/voltdb/voltdb/mylog4j.xml"
$ voltdb start -H svr1
```


# 稼働中にlog4jの設定を変更する

VoltDBを停止せず、起動したままログの設定を変更することができます。稼働中に設定を変更するためには、@UpdateLoggingシステムプロシージャを使用します。
@UpdateLoggingシステムプロシージャでは、log4jの設定XMLをテキスト文字列としてサーバーに渡すことができます。

以下に実行例を示します。

```console
$ echo "exec @UpdateLogging '" > sqlcmd.input
$ cat mylog4j.xml >> sqlcmd.input
$ echo "';" >> sqlcmd.input
$ cat sqlcmd.input | sqlcmd
```

なお、以下のようにシングルクォーテーションを含む場合はエスケープする必要があります。

```xml
エスケープ前
<param name="DatePattern" value="'.'yyyy-MM-dd" />
エスケープ後
<param name="DatePattern" value="&apos;.&apos;.yyyy-MM-dd" />
```

詳細は以下のドキュメントに記載されています。

[Using VoltDB - @UpdateLogging](https://docs.voltdb.com/UsingVoltDB/sysprocupdatelogging.php)


# ログのタイムゾーンをGMTからJSTに変更する

VoltDBはデフォルトでログのタイムゾーンがGMT（グリニッジ標準時）になっています。
別のタイムゾーンを使用したい場合は、log4jの拡張機能を使用します。

まず、Apache log4j用の[Apache Extrasのサイト](http://logging.apache.org/log4j/extras/)からファイルをダウンロードします。
今回はVoltDB v8.3で使用されているv1.2.17のバージョンのファイルをダウンロードしました。

apache-log4j-extras-1.2.17-bin.tar.gz

次にダウンロードしたファイルを展開して、展開先にあるapache-log4j-extras-1.2.17.jarファイルをVoltDBインストールディレクトリの/lib/extensionフォルダに配置します。

```console
$ tar xvzf apache-log4j-extras-1.2.17-bin.tar.gz
$ cp -p apache-log4j-extras-1.2.17/apache-log4j-extras-1.2.17.jar /opt/voltdb/lib/extension/
```

最後に、log4j設定ファイルを修正し各アペンダにタイムゾーンを指定します。

変更したいAppenderのLayoutクラスとしてEnhancedPatternLayoutを指定することでlog4jの追加機能を有効にします。
次に、レイアウトパターンの一部として目的のタイムゾーンを指定します。
例えば、次の設定はGMTから9時間加えた東京のタイムゾーン("%d{ISO8601}{GMT+9}")に変更しています。

```xml
<appender name="file" class="org.apache.log4j.DailyRollingFileAppender">
  <param name="file" value="log/volt.log"/>
  <param name="DatePattern" value="'.'yyyy-MM-dd" />
  <layout class="org.apache.log4j.EnhancedPatternLayout">
     <param name="ConversionPattern" 
            value="%d{ISO8601}{GMT+9}   %-5p [%t] %c: %m%n"/>
  </layout>
</appender>
```


# 参考

- [Administrator's Guide - Chapter 6. Logging and Analyzing Activity in a VoltDB Database](https://docs.voltdb.com/AdminGuide/ChapLogging.php)
 
- [Using VoltDB - @UpdateLogging](https://docs.voltdb.com/UsingVoltDB/sysprocupdatelogging.php)