• JSVCのログローテート

    2013年07月24日 21時30分
    JSVC利用時のログローテートについて色々調べたのでメモっておきます。
    なお、Linux上でのJSVC 1.0.15の内容です。


    rotatelogsで行けるか


    JSVCの起動スクリプトはこのような感じです。
    start   )
          "$JSVC" $JSVC_OPTS \
          -java-home "$JAVA_HOME" \
          -user $TOMCAT_USER \
          -pidfile "$CATALINA_PID" \
          -wait 10 \
          -outfile "$CATALINA_OUT" \
          -errfile "&1" \
          -classpath "$CLASSPATH" \
          "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \
          -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \
          -Dcatalina.base="$CATALINA_BASE" \
          -Dcatalina.home="$CATALINA_HOME" \
          -Djava.io.tmpdir="$CATALINA_TMP" \
          $CATALINA_MAIN
          exit $?
        ;;


    ログ出力を指定するオプションはoutfileerrfileの2つで
    名前の通り標準出力と標準エラー出力の出力先を指定します。

    最初はここにrotatelogsを指定してみました。
    -outfile "|/usr/local/apache2/bin/rotatelogs $CATALINA_OUT.%Y%m%d 86400 540" \

    しかし、そんなに便利には出来ていません。


    調べたところこれらのオプションに指定できる値は次の通りです。
    • &1 (標準出力)
    • &2 (標準エラー出力)
    • SYSLOG (SYSLOG)
    • ファイルパス

    ならば一旦全部標準出力に出してパイプに流してみる。
    start   )
          "$JSVC" $JSVC_OPTS \
          -java-home "$JAVA_HOME" \
          -user $TOMCAT_USER \
          -pidfile "$CATALINA_PID" \
          -wait 10 \
          -outfile "&1" \
          -errfile "&1" \
          -classpath "$CLASSPATH" \
          "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \
          -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \
          -Dcatalina.base="$CATALINA_BASE" \
          -Dcatalina.home="$CATALINA_HOME" \
          -Djava.io.tmpdir="$CATALINA_TMP" \
          $CATALINA_MAIN |/usr/local/apache2/bin/rotatelogs $CATALINA_OUT.%Y%m%d 86400 540
          exit $?
        ;;


    ダメ。JSVCがdaemon化されるためかうまく取れません。
    (試したところ親プロセスの出力がコンソールに出て子プロセスの出力がパイプに流れる。
    この辺りのdaemonの動作をちゃんと知ってればやり方があるのかも。)

    rotatelogsはちょっと無理そう。


    logrotate + SIGHUP


    ならば仕方ないlogrotateで行きます。

    簡単に行くならcopytruncateを指定して終わりなのですが、
    copyとtruncate処理が気持ち高コストな気がしたり、
    copyとtruncateの間のログが欠損する確率がわずかながら有る等
    若干もやっとするので使わなくて済むか調べます。


    copytruncateを指定しない場合にはログファイルの再オープンが必要になり、
    一般的にはSIGHUPを送ることで行われます。

    しかし、JSVCの場合は以下のような動作になっており、SIGHUPを送っても再オープンされません。
    1. 親プロセスでファイルをオープン
    2. 子プロセスを起動 (子プロセス側で再オープンしないので親プロセスと同じファイルを使用)
    3. SIGHUP
    4. 子プロセス再起動

    (まあ仮に子プロセス再起動時にファイルを再オープンしてくれたとしても
    プロセス再起動自体がちょっとまずいのでどの道却下なのですが・・・)


    logrotate + SIGUSR1


    ファイルオープン周りのソースをさらに読み進めたところ、SIGUSR1というのが実装されています。

    SIGUSR1を送ると次のような動作になります。
    1. 親プロセスでファイルをオープン
    2. 子プロセスを起動 (子プロセス側で再オープンしないので親プロセスと同じファイルを使用)
    3. SIGUSR1
    4. 子プロセスのファイルを再オープン

    子プロセスはファイルの再オープンのみを行ってくれるという望み通りの結果ですが、
    親プロセスは再オープンされず残ってしまいます。

    親プロセスのSIGUSR1にファイルの再オープン処理を追加すれば解決するような気もするのですが
    前述の通りdaemonの動作に明るくなく、危険な気がしたのでやめておきました。


    結局logrotate + copytruncate


    JSVCのログは量も少ないし欠損して困るデータも無いよねと自分に言い聞かせ
    最終的にlogrotate + copytruncateで行くことにしました。

    色々調べるのが大変だったわりには実に普通な結果です。

  • Tomcat6のContext設定

    2011年12月07日 23時48分
    Tomcat6でDBCPを使ってみました。
    設定はContextにResourceとして書き込むのですが、
    そもそもContextの設定の仕方がよくわからなかったので調べました。
    せっかくなのでメモっておこうと思います。


    設定を書ける箇所は次の3か所のようです。(公式の説明)
    1. $CATALINA_BASE/conf/server.xml
    2. $CATALINA_BASE/conf/context.xml
    3. $CATALINA_BASE/conf/[enginename]/[hostname]/context.xml (無い場合/META-INF/context.xml)

    また、設定を書く箇所が複数あるので、優先順位があります。
    同一の設定項目に対して別々の値を設定をした場合、上の方のファイルに書かれた値が優先されます。
    別々の設定項目の場合は全てのファイルで設定された値が有効になります。
    (全てのファイルの設定をマージして、キーが重複したら上の方を優先する)


    アプリケーションをデプロイする時には、
    warファイルを置いておしまいにしたい(広範囲な設定はあまり触りたくない)ので、
    /META-INF/context.xmlに設定を書くことにしました。