2013年11月30日土曜日

Tomcatとjsvcとumask

前回tomcatをjsvcでサービス化をしてみました(ここ)。で後で気が付いたのですが、実行ユーザのumaskが有効になっていないみたいです。

# ls -lrt /var/tomcat/logs

total 12
-rw------- 1 root   root      0 Nov 29 15:14 catalina-daemon.out
-rw------- 1 tomcat tomcat    0 Nov 29 15:14 manager.2013-11-29.log
-rw------- 1 tomcat tomcat    0 Nov 29 15:14 host-manager.2013-11-29.log
-rw-r--r-- 1 tomcat tomcat    0 Nov 29 15:14 localhost_access_log.2013-11-29.txt
-rw------- 1 tomcat tomcat  447 Nov 29 15:14 localhost.2013-11-29.log
-rw------- 1 tomcat tomcat 2016 Nov 29 15:14 catalina.2013-11-29.log
-rw------- 1 root   root   2016 Nov 29 15:14 catalina-daemon.err

アクセスログだけumask 0022が聞いているみたいです。これだと何かと都合が悪いので、
指定できないか?を調べてみたのですが、helpを見てもそのような記載がありませんでした。
そこでjsvcのソースを見たところ、"-umask"というオプションで指定できることがわかりました。

ということで、jsvcのオプションで指定してみます。

# vi /var/tomcat/bin/setenv.sh
====


#jsvc options
export JSVC_OPTS="-umask 0022"

====

これでサービス再起動!
# service tomcat stop
# rm -f /var/tomcat/logs/*
# service tomcat start
# ls -lrt /var/tomcat/logs

-rw-r--r-- 1 tomcat tomcat    0 Nov 29 15:17 manager.2013-11-29.log
-rw-r--r-- 1 tomcat tomcat    0 Nov 29 15:17 host-manager.2013-11-29.log
-rw-r--r-- 1 tomcat tomcat    0 Nov 29 15:17 localhost_access_log.2013-11-29.txt
-rw-r--r-- 1 root   root    332 Nov 29 15:41 catalina-daemon.out
-rw-r--r-- 1 tomcat tomcat 1122 Nov 29 15:41 localhost.2013-11-29.log
-rw-r--r-- 1 tomcat tomcat 4828 Nov 29 15:41 catalina.2013-11-29.log
-rw-r--r-- 1 root   root   4828 Nov 29 15:41 catalina-daemon.err

めでたし!

2013年11月22日金曜日

Tomcatのサービス化でjsvcを使ってみる

Tomcatのサービス化で、プロセスを活かしたままログローテーションを実装するため、jsvcを使ってみた。環境は以下の通り。

 OS:CentOS 6.4(x64)
 Java 1.7.0_45
 Tomcat 7.0.47
 実行ユーザ tomcat

1.JavaとTomcatのセットアップ

それぞれを以下のディレクトリにインストール

 ・/opt/java/jdk1.7.0_45
 ・/opt/tomcat/apache-tomcat-7.0.47

実際には以下の通り。まずはjavaのインストール。

# mkdir /opt/java
# cd /opt/java

javaはこちらのサイトから、tarball(jdk-7u45-linux-x64.gz)のものをダウンロードし、/opt/javaに配置
※wgetでは直接ダウンロードできません(304で飛ばされる)

# gunzip jdk-7u45-linux-x64.gz
# tar xvf jdk-7u45-linux-x64

次にtomcatです。

# make /opt/tomcat
# cd /opt/tomcat
# wget http://ftp.jaist.ac.jp/pub/apache/tomcat/tomcat-7/v7.0.47/bin/apache-tomcat-7.0.47.tar.gz
# tar xvfz apache-tomcat-7.0.47.tar.gz

実行アカウントを作成し、上記のtomcatフォルダのオーナーを変更しておく

# useradd -d /opt/tomcat -s /sbin/nologin tomcat
# chown -R tomcat. /opt/tomcat

あと何かと面倒なので、環境変数も設定しておく

# vi ~/.bahsrc

==
export JAVA_HOME=/opt/java/jdk1.7.0_45

export PATH=$PATH:$JAVA_HOME/bin
==

# source ~/.bashrc
# java -version

java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)

Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)


2.jsvcの構築

Tomcatのサイトに記載されいてるようにjsvcを作成してみる。

# cd /opt/tomcat/apache-tomcat-7.0.47/bin
# tar xvfz commons-daemon-native.tar.gz
# cd commons-daemon-1.0.15-native-src/unix
# ./configure

*** Current host ***
checking build system type... x86_64-unknown-linux-gnu
 ・
 ・
 ・
*** Java compilation tools ***
checking for JDK location... configure: error: Java Home not defined. Rerun with --with-java=... parameter

とエラーになってしまった。改めて

# ./configure --with-java=/opt/java/jdk1.7.0_45

*** Current host ***
checking build system type... x86_64-unknown-linux-gnu
 ・
configure: WARNING: cannot find headers for libcap
 ・
*** All done ***
Now you can issue "make"

となった。makeできるらしいが、libcapのヘッダーがないってワーニングがでている。これは
Capablityが使えないということになるのかな?そうなると起動時のユーザを変更できないと思われる。とりあえず、対応なしで進めてみる。

と思ってちょっと調べてみたら、、、こんなセキュリティ脆弱性も出ている。

うーん、今回はVersion的には解決していますが、こういった類の問題が今後も出る可能性が
あるという点では、jsvcを使わずに、普通にtomcatをsuで実行したほうがよいのかもしれない。
必要はよくよく検討したほうがよいというか。
ちなみにNational Vulnerability Databaseでjsvcの脆弱性はこれだけしかヒットしなかった。

とりあえず今回はjsvcを使う想定で進める。

# make

(cd native; make  all)
make[1]: Entering directory `/opt/tomcat/apache-tomcat-7.0.47/bin/commons-daemon-1.0.15-native-src/unix/native'
gcc -g -O2 -DOS_LINUX -DDSO_DLFCN -DCPU=\"amd64\" -Wall -Wstrict-prototypes   -I/opt/java/jdk1.7.0_45/include -I/opt/java/jdk1.7.0_45/include/linux -c jsvc-unix.c -o jsvc-unix.o

 ・
 ・
 ・

gcc   jsvc-unix.o libservice.a -ldl -lpthread -o ../jsvc
make[1]: Leaving directory `/opt/tomcat/apache-tomcat-7.0.47/bin/commons-daemon-1.0.15-native-src/unix/native'

# ./jsvc --help

Usage: jsvc [-options] class [args...]
 ・
 ・
 ・
jsvc (Apache Commons Daemon) 1.0.15-dev
Copyright (c) 1999-2013 Apache Software Foundation.

ということで、Version情報も確認でき、コンパイル完了。

3.起動スクリプトの設定

用意するファイルは以下の3つ

 ・起動スクリプト(例:/etc/init.d/tomcat)

 ・jsvc起動シェル($CATALINA_HOME/bin/daemon.sh)

 ・起動引数シェル($CATALINA_BASE/bin/setenv.sh)

上記から順に起動される。

/etc/init.d/tomcat

起動スクリプトを用意。ポイントは、複数のTomcatを起動できるように
 ・固有になるインスタンス名を設定
 ・CATALINA_BASEに、/var/[インスタンス名]を設定
としたこと。

==========================================================
#!/bin/sh
#
# tomcat       Startup script for the Apache Tomcat Servlet/JSP container.
#
# chkconfig: - 80 10
# description: The Apache Tomcat Servlet/JSP container.
#

# Source function library.
. /etc/init.d/functions

RETVAL=0

INSTANCE=tomcat

JAVA_HOME=/opt/java/jdk1.7.0_45
CATALINA_HOME=/opt/tomcat/apache-tomcat-7.0.47
DAEMON=$CATALINA_HOME/bin/daemon.sh
USER=tomcat
shellname=${0##*/}
CATALINA_BASE=/var/$INSTANCE
LOCKFILE=/var/lock/subsys/$shellname
PIDFILE=/var/run/$shellname

start() {
        echo -n $"Starting tomcat: "
        $DAEMON --java-home $JAVA_HOME \
                --catalina-home $CATALINA_HOME \
                --catalina-base $CATALINA_BASE \
                --catalina-pid $PIDFILE \
                --tomcat-user $USER \
                start
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
                echo_success
                touch $LOCKFILE
        else
                echo failure
        fi
        echo
        return $RETVAL
}

stop() {
        echo -n $"Shutting down tomcat: "
        local PID=`cat $PIDFILE`
        if [ -z "$PID" ] ; then
                echo "server is not running "
                return 0
        fi
        $DAEMON --java-home $JAVA_HOME \
                --catalina-home $CATALINA_HOME \
                --catalina-base $CATALINA_BASE \
                --catalina-pid $PIDFILE \
                stop
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
                echo_success
                rm -f $LOCKFILE
        else
                echo failure
        fi
        echo
        return $RETVAL
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        stop
        start
        ;;
  status)
        status -p $PIDFILE jsvc
        ;;
  reopen)
        kill -USR1 `cat $PIDFILE`  > /dev/null 2>&1 || true
        ;;
  *)
        echo $"Usage: $0 {start|stop|restart|status|reopen}"
        exit 3
esac
==========================================================

$CATALINA_HOME/bin/daemon.sh

次にjsvc起動シェルを用意する。binディレクトリに、オリジナルのdaemon.shがあるので、それをベースに気になるところを修正
具体的にはstart処理のerrfileの出力先が標準出力になっていたので、選択ができるように修正
を加えたてみた。

==========================================================
#!/bin/sh

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# -----------------------------------------------------------------------------
# Commons Daemon wrapper script.
#
# $Id: daemon.sh 1202058 2011-11-15 06:37:12Z mturk $
# -----------------------------------------------------------------------------
#
# resolve links - $0 may be a softlink
ARG0="$0"
while [ -h "$ARG0" ]; do
  ls=`ls -ld "$ARG0"`
  link=`expr "$ls" : '.*-> \(.*\)$'`
  if expr "$link" : '/.*' > /dev/null; then
    ARG0="$link"
  else
    ARG0="`dirname $ARG0`/$link"
  fi
done
DIRNAME="`dirname $ARG0`"
PROGRAM="`basename $ARG0`"
while [ ".$1" != . ]
do
  case "$1" in
    --java-home )
        JAVA_HOME="$2"
        shift; shift;
        continue
    ;;
    --catalina-home )
        CATALINA_HOME="$2"
        shift; shift;
        continue
    ;;
    --catalina-base )
        CATALINA_BASE="$2"
        shift; shift;
        continue
    ;;
    --catalina-pid )
        CATALINA_PID="$2"
        shift; shift;
        continue
    ;;
    --tomcat-user )
        TOMCAT_USER="$2"
        shift; shift;
        continue
    ;;
    --service-start-wait-time )
        SERVICE_START_WAIT_TIME="$2"
        shift; shift;
        continue
    ;;
    * )
        break
    ;;
  esac
done
# OS specific support (must be 'true' or 'false').
cygwin=false;
darwin=false;
case "`uname`" in
    CYGWIN*)
        cygwin=true
        ;;
    Darwin*)
        darwin=true
        ;;
esac

# Use the maximum available, or set MAX_FD != -1 to use that
test ".$MAX_FD" = . && MAX_FD="maximum"
# Setup parameters for running the jsvc
#
test ".$TOMCAT_USER" = . && TOMCAT_USER=tomcat
# Set JAVA_HOME to working JDK or JRE
# JAVA_HOME=/opt/jdk-1.6.0.22
# If not set we'll try to guess the JAVA_HOME
# from java binary if on the PATH
#
if [ -z "$JAVA_HOME" ]; then
    JAVA_BIN="`which java 2>/dev/null || type java 2>&1`"
    test -x "$JAVA_BIN" && JAVA_HOME="`dirname $JAVA_BIN`"
    test ".$JAVA_HOME" != . && JAVA_HOME=`cd "$JAVA_HOME/.." >/dev/null; pwd`
else
    JAVA_BIN="$JAVA_HOME/bin/java"
fi

# Only set CATALINA_HOME if not already set
test ".$CATALINA_HOME" = . && CATALINA_HOME=`cd "$DIRNAME/.." >/dev/null; pwd`
test ".$CATALINA_BASE" = . && CATALINA_BASE="$CATALINA_HOME"
test ".$CATALINA_MAIN" = . && CATALINA_MAIN=org.apache.catalina.startup.Bootstrap
# If not explicitly set, look for jsvc in CATALINA_BASE first then CATALINA_HOME
if [ -z $JSVC ]; then
    JSVC="$CATALINA_BASE/bin/jsvc"
    if [ ! -x $JSVC ]; then
        JSVC="$CATALINA_HOME/bin/jsvc"
    fi
fi
# Set the default service-start wait time if necessary
test ".$SERVICE_START_WAIT_TIME" = . && SERVICE_START_WAIT_TIME=10

# Ensure that any user defined CLASSPATH variables are not used on startup,
# but allow them to be specified in setenv.sh, in rare case when it is needed.
CLASSPATH=
JAVA_OPTS=
if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
  . "$CATALINA_BASE/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
  . "$CATALINA_HOME/bin/setenv.sh"
fi

# Add on extra jar files to CLASSPATH
test ".$CLASSPATH" != . && CLASSPATH="${CLASSPATH}:"
CLASSPATH="$CLASSPATH$CATALINA_HOME/bin/bootstrap.jar:$CATALINA_HOME/bin/commons-daemon.jar"

test ".$CATALINA_OUT" = . && CATALINA_OUT="$CATALINA_BASE/logs/catalina-daemon.out"
test ".$CATALINA_TMP" = . && CATALINA_TMP="$CATALINA_BASE/temp"

# added by hayashi 2013/11/16
test ".$CATALINA_ERR" = . && CATALINA_ERR="$CATALINA_BASE/logs/catalina-daemon.out"

# Add tomcat-juli.jar to classpath
# tomcat-juli.jar can be over-ridden per instance
if [ -r "$CATALINA_BASE/bin/tomcat-juli.jar" ] ; then
  CLASSPATH="$CLASSPATH:$CATALINA_BASE/bin/tomcat-juli.jar"
else
  CLASSPATH="$CLASSPATH:$CATALINA_HOME/bin/tomcat-juli.jar"
fi
# Set juli LogManager config file if it is present and an override has not been issued
if [ -z "$LOGGING_CONFIG" ]; then
  if [ -r "$CATALINA_BASE/conf/logging.properties" ]; then
    LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
  else
    # Bugzilla 45585
    LOGGING_CONFIG="-Dnop"
  fi
fi

test ".$LOGGING_MANAGER" = . && LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
JAVA_OPTS="$JAVA_OPTS $LOGGING_MANAGER"

# Set -pidfile
test ".$CATALINA_PID" = . && CATALINA_PID="$CATALINA_BASE/logs/catalina-daemon.pid"

# Increase the maximum file descriptors if we can
if [ "$cygwin" = "false" ]; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ "$?" -eq 0 ]; then
        # Darwin does not allow RLIMIT_INFINITY on file soft limit
        if [ "$darwin" = "true" -a "$MAX_FD_LIMIT" = "unlimited" ]; then
            MAX_FD_LIMIT=`/usr/sbin/sysctl -n kern.maxfilesperproc`
        fi
        test ".$MAX_FD" = ".maximum" && MAX_FD="$MAX_FD_LIMIT"
        ulimit -n $MAX_FD
        if [ "$?" -ne 0 ]; then
            echo "$PROGRAM: Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        echo "$PROGRAM: Could not query system maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# ----- Execute The Requested Command -----------------------------------------
case "$1" in
    run     )
      shift
      "$JSVC" $* \
      $JSVC_OPTS \
      -java-home "$JAVA_HOME" \
      -pidfile "$CATALINA_PID" \
      -wait "$SERVICE_START_WAIT_TIME" \
      -nodetach \
      -outfile "&1" \
      -errfile "&2" \
      -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 $?
    ;;
    start   )
      "$JSVC" $JSVC_OPTS \
      -java-home "$JAVA_HOME" \
      -user $TOMCAT_USER \
      -pidfile "$CATALINA_PID" \
      -wait "$SERVICE_START_WAIT_TIME" \
      -outfile "$CATALINA_OUT" \
      -errfile "$CATALINA_ERR" \
      -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 $?
    ;;
    stop    )
      "$JSVC" $JSVC_OPTS \
      -stop \
      -pidfile "$CATALINA_PID" \
      -classpath "$CLASSPATH" \
      -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \
      -Dcatalina.base="$CATALINA_BASE" \
      -Dcatalina.home="$CATALINA_HOME" \
      -Djava.io.tmpdir="$CATALINA_TMP" \
      $CATALINA_MAIN
      exit $?
    ;;
    version  )
      "$JSVC" \
      -java-home "$JAVA_HOME" \
      -pidfile "$CATALINA_PID" \
      -classpath "$CLASSPATH" \
      -errfile "&2" \
      -version \
      -check \
      $CATALINA_MAIN
      if [ "$?" = 0 ]; then
        "$JAVA_BIN" \
        -classpath "$CATALINA_HOME/lib/catalina.jar" \
        org.apache.catalina.util.ServerInfo
      fi
      exit $?
    ;;
    *       )
      echo "Unknown command: \`$1'"
      echo "Usage: $PROGRAM ( commands ... )"
      echo "commands:"
      echo "  run               Start Tomcat without detaching from console"
      echo "  start             Start Tomcat"
      echo "  stop              Stop Tomcat"
      echo "  version           What version of commons daemon and Tomcat"
      echo "                    are you running?"
      exit 1
    ;;
esac
==========================================================

$CATALINA_BASE/bin/setenv.sh

最後に起動引数シェル。ここはjsvcやjavaの引数を記載する。以下例です。

==========================================================
#stdout (defaults to $CATALINA_BASE/logs/catalina-daemon.out)
#Use the value '&2' to simulate '1>&2'
export CATALINA_OUT=

#stderr (defaults to $CATALINA_BASE/logs/catalina-daemon.out)
#Use the value '&1' to simulate '2>&1'
export CATALINA_ERR=

#java.io.tmpdir (defaults to $CATALINA_BASE/temp)
export CATALINA_TMP=

#wait waittime seconds for the service to start
#waittime should multiple of 10 (min=10)
export SERVICE_START_WAIT_TIME=10

#jsvc options
export JSVC_OPTS=

#jsvc verbosely print debugging information
#export JSVC_OPTS="$JSVC_OPTS -debug"

# jsvc working directory
export JSVC_OPTS="$JSVC_OPTS -cwd $CATALINA_BASE"

export JAVA_OPTS=" \
           -server \
           -DTOMCATID=tomcat \
           -verbose:gc \
           -Xms256m -Xmx256m \
           -XX:PermSize=64m -XX:MaxPermSize=128m \
           -XX:+HeapDumpOnOutOfMemoryError \
           -XX:+PrintGCDetails \
           -XX:+PrintGCTimeStamps

export CLASSPATH=
export CATALINA_OPTS=
==========================================================

※ポイントは、gcログ出力は指定せず、標準出力に出すようにしておくこと。ファイル指定すると
 gcログはjsvcのreopenが効かなくて困る。

あとはjsvcはなんとなくbinディレクトにコピーしておく(パス名長いし、実行モジュールは一か所に)。



4.起動

# service tomcat start

で実行してみる。エラーになったり、成功したり。調べてみると、Tomcatが起動完了するまでの
時間が10秒以上かかることがあり、その際にtimeoutとなっていたみたい。ただしそれでもtomcat
は起動しているようですが。。いずれにしてもエラーは気持ち悪いので、setenv.shの中の
SERVICE_START_WAIT_TIMEを60(1分)にすることで、エラーは解消された。

ちなみに起動後のプロセスを見るとこんな感じ

# ps -ef|grep jsv[c]

root      2437     1  0 16:19 ?        00:00:00 jsvc.exec -cwd /var/tomcat -java-home /opt/java/jdk1.7.0_45 -user tomcat -pidfile /var/run/tomcat -wait 60 -outfile /var/tomcat/logs/catalina-daemon.out -errfile /var/tomcat/logs/catalina-daemon.err -classpath /opt/tomcat/apache-tomcat-7.0.47/bin/bootstrap.jar:/opt/tomcat/apache-tomcat-7.0.47/bin/commons-daemon.jar:/opt/tomcat/apache-tomcat-7.0.47/bin/tomcat-juli.jar -Djava.util.logging.config.file=/var/tomcat/conf/logging.properties -server -DTOMCATID=tomcat -verbose:gc -Xms256m -Xmx256m -XX:PermSize=64m -XX:MaxPermSize=128m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/var/tomcat/6/drpcbase/logs/gc.log -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs= -Dcatalina.base=/var/tomcat -Dcatalina.home=/opt/tomcat/apache-tomcat-7.0.47 -Djava.io.tmpdir=/var/tomcat/temp org.apache.catalina.startup.Bootstrap

tomcat    2438  2437  4 16:19 ?        00:00:03 jsvc.exec -cwd /var/tomcat -java-home /opt/java/jdk1.7.0_45 -user tomcat -pidfile /var/run/tomcat -wait 60 -outfile /var/tomcat/logs/catalina-daemon.out -errfile /var/tomcat/logs/catalina-daemon.err -classpath /opt/tomcat/apache-tomcat-7.0.47/bin/bootstrap.jar:/opt/tomcat/apache-tomcat-7.0.47/bin/commons-daemon.jar:/opt/tomcat/apache-tomcat-7.0.47/bin/tomcat-juli.jar -Djava.util.logging.config.file=/var/tomcat/conf/logging.properties -server -DTOMCATID=tomcat -verbose:gc -Xms256m -Xmx256m -XX:PermSize=64m -XX:MaxPermSize=128m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/var/tomcat/6/drpcbase/logs/gc.log -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs= -Dcatalina.base=/var/tomcat -Dcatalina.home=/opt/tomcat/apache-tomcat-7.0.47 -Djava.io.tmpdir=/var/tomcat/temp org.apache.catalina.startup.Bootstrap

どうも親プロセスと子プロセスで同じ引数で起動されるみたいですね(今度ソースをみてみよう)。

5.ログローテーション

まず現状のファイルアクセスを確認してみる。

# lsof |grep jsvc|grep catalina-daemon

jsvc  2437  root  1w    REG  253,0    13923   17039949 /var/tomcat/logs/catalina-daemon.out
jsvc  2437  root  2w    REG  253,0      2016   17040504 /var/tomcat/logs/catalina-daemon.err
jsvc  2438  tomcat  1w  REG  253,0  13923   17039949 /var/tomcat/logs/catalina-daemon.out
jsvc  2438  tomcat  2w  REG  253,0  2016   17040504 /var/tomcat/logs/catalina-daemon.err

となってます。親プロセスも子プロセスも、catalina-daemon.outとcatalina-daemon.errをopenして
ますね。これを移動してみます。

# mkdir /var/tomcat/logs/old
# mv /var/tomcat/logs/*.* /var/tomcat/logs/old/
# lsof |grep jsvc|grep catalina-daemon

jsvc 2437 root 1w REG 253,0    13923   17039949 /var/tomcat/logs/old/catalina-daemon.out
jsvc 2437 root 2w REG 253,0     2016   17040504 /var/tomcat/logs/old/catalina-daemon.err
jsvc 2438 tomcat 1w REG 253,0 13923 17039949 /var/tomcat/logs/old/catalina-daemon.out
jsvc 2438 tomcat 2w REG 253,0 2016  17040504 /var/tomcat/logs/old/catalina-daemon.err

全てold以下を参照が引っ張られてますね。これでreopenをしてみると、、

# service tomcat reopen
# lsof |grep jsvc|grep catalina-daemon

jsvc 2437 root 1w REG 253,0    13923   17039949 /var/tomcat/logs/old/catalina-daemon.out
jsvc 2437 root 2w REG 253,0     2016   17040504 /var/tomcat/logs/old/catalina-daemon.err
jsvc 2438 tomcat 1w REG 253,0        0   17040554 /var/tomcat/logs/catalina-daemon.out
jsvc 2438 tomcat 2w REG 253,0        0   17040557 /var/tomcat/logs/catalina-daemon.err

ん?子プロセスは無事切り替わりましたが、、親プロセスがまだold配下をopenしっぱなしですね。
ということで、Tomcatに標準出力、標準エラー出力をするアプリを仕込んで出力してみたところ、
親プロセスがオープンしているログ(old配下)には何も出力されていませんが、子プロセスのほう
にはきっちり出力されていました(OutOfMemoryも発生させて同様でした)。

という意味では、あまり弊害はなさそうですが、、、(jsvcプロセス自体が何か出力する際に使われるのか??)なぞは調べが付かなかった。。。また今度。

(2014/2/15)
別件でもう少し調べてみたところ、、標準出力以外のtomcatのログ(アクセスログとか)は切替わっていないようでした。

# lsof |grep 31141|grep logs

jsvc 31141 tomcat 1w  REG 253,2  774 2621517 /var/tomcat/logs/catalina.out
jsvc 31141 tomcat 2w  REG 253,2  774 2621517 /var/tomcat/logs/catalina.out
jsvc 31141 tomcat 11w REG 253,2 3850 2621505 /var/tomcat/logs/catalina.2014-02-15.log (deleted)
jsvc 31141 tomcat 12w REG 253,2 240 2621514 /var/tomcat/logs/localhost.2014-02-15.log (deleted)
jsvc 31141 tomcat 13w REG 253,2    0 2621515 /var/tomcat/logs/manager.2014-02-15.log (deleted)
jsvc 31141 tomcat 14w REG 253,2    0 2621516 /var/tomcat/logs/host-manager.2014-02-15.log (deleted)
jsvc 31141 tomcat 63w REG 253,2 410 2621520 /var/tomcat/logs/localhost_access_log.2014-02-15.txt (deleted)

こんな感じ。標準出力、エラー出力が切り替え対象ってことですかね。まぁ当然と言えば当然か。他のファイルはそもそも日付ベースでローテーションかかってますし、、別で対応すればよいということですかね。



 

2013年11月4日月曜日

Windows8 Proにvargrantを入れてみる(その2)

前回はvagrantで仮想OSを起動するところまで実施。Hyper-Vとの共存で手こずった。
その後何かと触っていると気になった点を挙げておこう。

・ゲストOSにnetworkを追加してみる

 今回ネットワークはデフォルトのフォワード構成を使っているわけですが、フォワードだと何かを
 面倒なので、ブリッジモードで通常のネットワークにつながるNICを追加してみる。

 1.VirtualBoxのオプション追加

 2.Vagrantfileを修正
  mitty# cd ~/vagrant/svr11
  mitty# vim Vagrantfile
   ===
  config.vm.network :public_network
   ===
  mitty#

 これで起動時にeth1が追加される。DHCP環境であれば、eth1にアサインされたIPでアクセスを
 することができる。

 (2013/11/16)
 IPを固定にするには、以下のように修正すればよいことがわかりました。

   ===
  config.vm.network :public_network ,ip: "x.x.x.x"


   ===

 
 これでTeraTermでもいけますね。便利。

・作業状態の保存を試みる

 vagrantで起動した仮想OSの作業を中断したい時(hibernate)、ゲストOSをsuspendした状態で、
 ホストOSの再起動をしてみると、なぜか再起動後にゲストOSが認識できなくなる(VirtualBoxに
 は残っているが、vagrantコマンドでは認識しない)。
 無理やりvagrant upで起動すると新規でゲストOSが起動される。。VirtualBox上に構築されている
 OSをvagrantに取り込む方法もわからないため、、再構築するしかない。
 (誰か教えてほしい・・)

 ちなみにホストOS停止前に、ゲストOSを停止した場合は、今のところ問題はないようです。

 これだと作業途中を保存できないんだよな~

 (2013/11/06)
 取り込む方法がありました。vagrantによって構築したゲストOSだけかもしれませんが、、

 svr11が起動できなくなったと想します。

 1.ゲストOSのIDを確認

 mitty# cd ~/VirtualBox\ VMs/svr11_default_1383543354
 mitty# less *.vbox

  <VirtualBox xmlns="http://www.innotek.de/VirtualBox-settings" version="1.12-windows">
    <Machine uuid="{4c9d39f8-3e2e-4eab-89f3-74c952d624b0}"  
  ・
  ・
  ・

 上記のMachineタグのuuid属性の値を確認します。

 2.svr11とゲストOSのIDの紐づけ

 mitty# cd ~/vagrant/svr11/.vagrant/machines/default/virtualbox
 mitty# echo 4c9d39f8-3e2e-4eab-89f3-74c952d624b0 > id
  mitty# cd ~/vagrant/svr11/

  mitty# vagrant up

 起動できれば終了!

・vagrantコマンドのデバッグ

 mitty# VAGRANT_LOG=INFO vagrant up


ゲストOSをある時点までrollbackするためのplug-inの「sahara」を入れてみる。

 
 1.saharaのインストール

 mitty#  vagrant plugin install sahara

 Installing the 'sahara' plugin. This can take a few minutes...
 Installed the plugin 'sahara (0.0.16)'!


 2.sandboxを有効にする
 sandboxにしたい環境に移動し、on(有効)にする。

 mitty#  cd ~/vagrant/svr11
 mitty#  vagrant sandbox on

 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%


 mitty#  vagrant sandbox status

 [default] Sandbox mode is on

 3.rollback/commitを試す

 ・svr11の書き込みをrollback



 mitty#  cd ~/vagrant/svr11
 mitty#  vagrant sandbox on
 mitty#  ssh svr11
  # touch a
  # logout
 mitty#  vagrant sandbox rollback
  
 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

 mitty#
 mitty#  ssh svr11
 #  ls
 #

 なくなった。成功。ちなみに

 mitty#  vagrant sandbox status

 [default] Sandbox mode is on

 sandboxは有効な状態のままでした。

 ・svr12の書き込みをcommit


 mitty#  ssh svr11
  # touch a
  # logout
 mitty#  vagrant sandbox commit

 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

 mitty#

 成功はしたものの、時間がかかる。suspend/haltしておくと早い。

 4.sandboxを無効にする

 mitty# vagrant sandbox off


 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

 mitty#

 ちなみに変更したのちにcommit/rollbackをしないまま、offにすると、commitされたことになる
 ようです。他のサイトではrollbackと書かれていたりしたので、Versionによって動きが異なるかも
 しれません(要注意)。

ゲストOSをsnapshot取得のためのplug-inの「vagrant-vbox-snapshot」を入れてみる。

 1.vagrant-vbox-snapshotのインストール

 mitty# vagrant plugin install vagrant-vbox-snapshot

 Installing the 'vagrant-vbox-snapshot' plugin. This can take a few minutes...

 Installed the plugin 'vagrant-vbox-snapshot (0.0.4)'!

 2.snapshotを取得してみる

 snapshotに名前が付けられるので、「init」という名前で作成してみる。


 mitty#  cd ~/vagrant/svr11
 mitty# vagrant snapshot take init


 Taking snapshot init
 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

 mitty# vagrant snapshot list 

 Listing snapshots for 'default':
   Name: init (UUID: ce8054c3-0914-4548-a72b-d929cfda5589) *

 mitty#  

 initという名前のスナップショットがあることがわかる。

 3.snapshotを戻してみる

 最後に取得したsnapshotに戻してみる。


 mitty#  ssh svr11

 # touch e
  # logout
 mitty# vagrant snapshot back


 0%...10%...20%...30%...40%...50%...Restoring snapshot ce8054c3-0914-4548-a72b-d929cfda5589
 60%...70%...80%...90%...100%
 Starting restored VM
 [default] Resuming suspended VM...
 [default] Booting VM...

 mitty#  ssh svr11
 #  ls
 # a b c d

 eがなくなった。戻ったっということだ。ちなみにsnapshot(init)は残ったままだ。

 4.snapshotを任意の時点に戻してみる

 mitty#  ssh svr11

 # touch e
 # logout

 mitty# vagrant snapshot take modified

 Taking snapshot modified
 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

 mitty# vagrant snapshot list

 Listing snapshots for 'default':
   Name: init (UUID: ce8054c3-0914-4548-a72b-d929cfda5589)
      Name: modified (UUID: 314b3d67-c4e5-4d40-a030-fa6e2f919c6b) *

 2回目のsnapshot(modified)を取得した。

 mitty#  ssh svr11

 # touch f
 # logout
  
 まずはsnapshot(modified)へリストアしてみる。

 mitty# vagrant snapshot go modified

 Powering off machine a7c0eae6-677d-4322-a8f5-9c4a1b6f9b22
 0%...10%...20%...30%...40%...50%...Restoring snapshot 314b3d67-c4e5-4d40-a030-fa6e2f919c6b
 60%...70%...80%...90%...100%
 Starting restored VM
 [default] Resuming suspended VM...
 [default] Booting VM...

 mitty#  ssh svr11

 # ls
 a b c d e
  # logout

 fがなくなっており、modifiedの時点まで戻ったことが確認できた。さらに、initの時点まで
 戻してみる。

 mitty# vagrant snapshot list

 Listing snapshots for 'default':
   Name: init (UUID: ce8054c3-0914-4548-a72b-d929cfda5589)
      Name: modified (UUID: 314b3d67-c4e5-4d40-a030-fa6e2f919c6b) *

 mitty# vagrant snapshot go init

 Powering off machine a7c0eae6-677d-4322-a8f5-9c4a1b6f9b22
 0%...10%...20%...30%...40%...50%...Restoring snapshot ce8054c3-0914-4548-a72b-d929cfda5589
 60%...70%...80%...90%...100%
 Starting restored VM
 [default] Resuming suspended VM...
 [default] Booting VM...

 mitty#  ssh svr11

 # ls
 a b c d
 # logout

 おぉー、もどった。

 mitty# vagrant snapshot list

 Listing snapshots for 'default':
   Name: init (UUID: ce8054c3-0914-4548-a72b-d929cfda5589)
      Name: modified (UUID: 314b3d67-c4e5-4d40-a030-fa6e2f919c6b) *

 なるほど。modifiedはまだ残ったままですね。
 
 mitty#  ssh svr11

 # touch g
 # logout
  
 mitty# vagrant snapshot take modified

 Taking snapshot modified2
 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

 mitty# vagrant snapshot list

 Listing snapshots for 'default':
    Name: init (UUID: ce8054c3-0914-4548-a72b-d929cfda5589)
       Name: modified (UUID: 314b3d67-c4e5-4d40-a030-fa6e2f919c6b)
       Name: modified2 (UUID: 031418ce-57a7-4313-ac43-339a7f148d64) *

 mitty# vagrant snapshot go modified
 
 Powering off machine a7c0eae6-677d-4322-a8f5-9c4a1b6f9b22
 0%...10%...20%...30%...40%...50%...Restoring snapshot 314b3d67-c4e5-4d40-a030-fa6e2f919c6b
 60%...70%...80%...90%...100%
 Starting restored VM
 [default] Resuming suspended VM...
 [default] Booting VM...

 mitty# vagrant snapshot list

 Listing snapshots for 'default':
    Name: init (UUID: ce8054c3-0914-4548-a72b-d929cfda5589)
       Name: modified (UUID: 314b3d67-c4e5-4d40-a030-fa6e2f919c6b) *
       Name: modified2 (UUID: 031418ce-57a7-4313-ac43-339a7f148d64)

 となった。modifiedのところに*が付いた。これは最新のsnapshotということだろう。
  

chef solo + knife soloはまたの機会に。

tips:minttyにvimなどのツールを入れよう

vagrantの環境構築をするために作ったminttyで、使い勝手をよくするために、vimとかをインストールする。

mintty# mingw-get update
mintty# mingw-get upgrade
mintty# mingw-get install msys-coreutils msys-man msys-tar msys-gzip msys-wget msys-zip  msys-unzip msys-vim

ちなみにインストールできるツールは

mintty# mingw-get list

で確認ができる。以上。