Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.0.1
    • Fix Version/s: 1.0.4
    • Component/s: Jsvc
    • Labels:
      None
    • Environment:

      Linux PC i686 Fedora Core 6

      Description

      Currently, tomcat does not support proper log rotation for
      the standard output and error files produced when -outfile
      and -errfile are used at startup. The following patch
      1) upgrades jsvc-unix.c to support proper log rotation using SIGUSR1
      2) fixes a minor bug with arguments.c where the -procname argument
      can't be used because it was added after the check for the end
      of arguments
      3) some minor warnings due to missing or incorrect function declarations.

      ===================== cut here =======================
      diff -ru jsvc-src/native/arguments.c jsvc-src-logrotate/native/arguments.c
      — jsvc-src/native/arguments.c 2005-05-17 06:13:39.000000000 -0700
      +++ jsvc-src-logrotate/native/arguments.c 2007-02-27 12:00:37.000000000 -0800
      @@ -186,16 +186,17 @@
      } else if (strstr(argv[x],"-ea")==argv[x])

      { args->opts[args->onum++]=strdup(argv[x]); - }

      else if (strstr(argv[x],"-")==argv[x])

      { - log_error("Invalid option %s",argv[x]); - return(NULL); - }

      else if (strcmp(argv[x],"-procname") == 0) {
      args->procname = optional(argc, argv, x++);
      if(args->procname == NULL)

      { log_error("Invalid process name specified"); return (NULL); }

      +
      + } else if (strstr(argv[x],"-")==argv[x])

      { + log_error("Invalid option %s",argv[x]); + return(NULL); + }

      else

      { args->clas=strdup(argv[x]); break; @@ -248,7 +249,6 @@ }

      if (log_debug_flag==true)

      { - char *temp; log_debug("+-- DUMPING PARSED COMMAND LINE ARGUMENTS --------------"); diff -ru jsvc-src/native/dso.h jsvc-src-logrotate/native/dso.h --- jsvc-src/native/dso.h 2005-05-17 06:13:39.000000000 -0700 +++ jsvc-src-logrotate/native/dso.h 2007-02-27 10:52:18.000000000 -0800 @@ -25,3 +25,4 @@ dso_handle dso_link(const char *pth); bool dso_unlink(dso_handle lib); void *dso_symbol(dso_handle lib, const char *nam); +char *dso_error(void); diff -ru jsvc-src/native/java.c jsvc-src-logrotate/native/java.c --- jsvc-src/native/java.c 2005-05-17 06:13:39.000000000 -0700 +++ jsvc-src-logrotate/native/java.c 2007-02-27 10:53:55.000000000 -0800 @@ -45,7 +45,7 @@ else main_shutdown(); }

      /* Automaticly restart when the JVM crashes */
      -static void java_abort123()
      +static void java_abort123(void)

      { exit(123); }

      diff -ru jsvc-src/native/jsvc-unix.c jsvc-src-logrotate/native/jsvc-unix.c
      — jsvc-src/native/jsvc-unix.c 2005-05-17 06:13:39.000000000 -0700
      +++ jsvc-src-logrotate/native/jsvc-unix.c 2007-02-27 14:34:01.000000000 -0800
      @@ -39,7 +39,9 @@
      static bool doreload=false;
      static void (*handler_int)(int)=NULL;
      static void (*handler_hup)(int)=NULL;
      +static void (*handler_usr1)(int)=NULL;
      static void (*handler_trm)(int)=NULL;
      +static void set_output(char *, char *, uid_t, gid_t);

      static void handler(int sig) {
      switch (sig)

      { @@ -74,6 +76,12 @@ break; }

      + case SIGUSR1:

      { + log_debug("Caught SIGUSR1: Reopening logs"); + set_output(NULL,NULL,-1,-1); + break; + }

      +
      default: {
      log_debug("Caught unknown signal %d",sig);
      break;
      @@ -232,6 +240,9 @@
      #endif
      static void controller(int sig) {
      switch (sig) {
      + case SIGUSR1:
      + log_debug("Reopening logs");
      + set_output(NULL,NULL,-1,-1);
      case SIGTERM:
      case SIGINT:
      case SIGHUP:
      @@ -514,6 +525,7 @@

      /* Install signal handlers */
      handler_hup=signal_set(SIGHUP,handler);
      + handler_usr1=signal_set(SIGUSR1,handler);
      handler_trm=signal_set(SIGTERM,handler);
      handler_int=signal_set(SIGINT,handler);
      controlled = getpid();
      @@ -565,7 +577,25 @@
      /**

      • Redirect stdin, stdout, stderr.
        */
        -static void set_output(char *outfile, char *errfile) {
        +static void set_output(char *outfile_arg, char *errfile_arg,
        + uid_t uid_arg, gid_t gid_arg) {
        + static char *outfile=NULL;
        + static char *errfile=NULL;
        + static uid_t uid=0;
        + static gid_t gid=0;
        + if (outfile_arg!=NULL) { + outfile=(char *)realloc((void *)outfile, strlen(outfile_arg)+1); + strcpy(outfile,outfile_arg); + }

        + if (errfile_arg!=NULL)

        { + errfile=(char *)realloc((void *)errfile, strlen(errfile_arg)+1); + strcpy(errfile,errfile_arg); + }

        + if (uid_arg != -1)
        + uid = uid_arg;
        + if (gid_arg != -1)
        + gid = gid_arg;
        +
        freopen("/dev/null", "r", stdin);
        log_debug("redirecting stdout to %s and stderr to %s",outfile,errfile);

      @@ -579,10 +609,12 @@
      }
      if(strcmp(outfile, "&2") != 0)

      { loc_freopen(outfile, "a", stdout); + chown(outfile,uid,gid); }

      if(strcmp(errfile,"&1") != 0)

      { loc_freopen(errfile, "a", stderr); + chown(errfile,uid,gid); }

      else

      { close(2); dup(1); @@ -678,7 +710,7 @@ #endif }
      • set_output(args->outfile, args->errfile);
        + set_output(args->outfile, args->errfile,uid,gid);

      /* We have to fork: this process will become the controller and the other
      will be the child */
      @@ -693,6 +725,7 @@
      SetTerm(cygwincontroller);
      #endif
      signal(SIGHUP,controller);
      + signal(SIGUSR1,controller);
      signal(SIGTERM,controller);
      signal(SIGINT,controller);

      1. jsvc_reopen_usr1.diff
        2 kB
        Damien Raude-Morvan

        Issue Links

          Activity

          Hide
          Priscilla Muriithi added a comment -

          I have installed version 1.0.7 but apparently I can't get catalina.out to rotate. The above Red Hat script breaks. Would you please attach a diff file on this post for the code?

          Thanks,

          Show
          Priscilla Muriithi added a comment - I have installed version 1.0.7 but apparently I can't get catalina.out to rotate. The above Red Hat script breaks. Would you please attach a diff file on this post for the code? Thanks,
          Hide
          Mladen Turk added a comment -

          Applied to the trunk. Will be part of 1.0.4
          Thanks.

          Show
          Mladen Turk added a comment - Applied to the trunk. Will be part of 1.0.4 Thanks.
          Hide
          Damien Raude-Morvan added a comment -

          I've updated the patch to apply on current 1.0.3 release.
          Would you please review it and apply it to current trunk ?

          Show
          Damien Raude-Morvan added a comment - I've updated the patch to apply on current 1.0.3 release. Would you please review it and apply it to current trunk ?
          Hide
          Mladen Turk added a comment -

          Please attach a patch (diff -u) as a file to this case.
          Copy/paste in comment window breaks all formatting and basically makes the patch unusable.

          Show
          Mladen Turk added a comment - Please attach a patch (diff -u) as a file to this case. Copy/paste in comment window breaks all formatting and basically makes the patch unusable.
          Hide
          Mike Polek added a comment -

          Patch is against release 1.0.1
          If I need to create a patch against the current trunk or a particular branch,
          please let me know.

          Show
          Mike Polek added a comment - Patch is against release 1.0.1 If I need to create a patch against the current trunk or a particular branch, please let me know.
          Hide
          Mike Polek added a comment -

          Note that because the pid in the PIDFILE is the child pid and not the parent,
          and since both need to receive a signal in order to close and reopen their logs,
          the USR1 signal MUST be sent to the parent.

          kill -USR1 `pidof $PROCESSNAME`

          will send the signal to both, which works ok. Ideally the PIDFILE would
          contain the controller process's pid, since it forwards all signals
          to the child anyway.

          For a RedHat style script, you can use something like

          1. Source function library.
            if [ -x /etc/init.d/functions ]; then
            . /etc/rc.d/init.d/functions
            else
            failure() { echo '[FAILED]'; return 1; }

            success()

            { echo '[ OK ]'; return 0; }

            fi

          PORT=8009
          PROCESSNAME=$(basename $0)
          PROCESSNAME=$

          {PROCESSNAME#[SK][[0-9][0-9]}

          shopt -s extglob
          PROCESSBASE=$

          {PROCESSNAME%%_+([0-9])}

          shopt -u extglob
          if [[ "$PROCESSBASE" != "$PROCESSNAME" ]]; then
          PORT=${PROCESSNAME#$

          {PROCESSBASE}

          _}
          fi
          PIDFILE=/var/run/$PROCESSNAME.pid
          RETVAL=0

          #

          1. Adapt the following lines to your configuration
            JAVA_HOME=/opt/java
            CATALINA_HOME=/opt/tomcat
            CATALINA_BASE=/opt/$PROCESSBASE
            TOMCAT_USER=apache
            TMP_DIR=$CATALINA_BASE/temp
            LOG_DIR=$CATALINA_BASE/logs
            OUTFILE=$LOG_DIR/catalina.$PORT.out
            ERRFILE=$LOG_DIR/catalina.$PORT.err
            #OUTFILE=SYSLOG1
            #ERRFILE=SYSLOG2
            JAVA_OPTS="-Xss2m -Xms32m -Xmx1024m"
            CLASSPATH=\
            $JAVA_HOME/lib/tools.jar:\
            $CATALINA_HOME/bin/commons-daemon.jar:\
            $CATALINA_HOME/bin/bootstrap.jar

          function start ()

          { # # Start Tomcat # echo -n "Starting $PROCESSBASE (Tomcat on port $PORT): " if [ -e $PIDFILE ] && kill -0 `cat $PIDFILE` >&/dev/null; then echo "PID file found. Not starting daemon." return fi $CATALINA_HOME/bin/jsvc \ -user $TOMCAT_USER \ -home $JAVA_HOME \ -Dcatalina.home=$CATALINA_HOME \ -Dcatalina.base=$CATALINA_BASE \ -Djava.io.tmpdir=$TMP_DIR \ -Dtomcat.server.port=$PORT \ -outfile $OUTFILE \ -errfile $ERRFILE \ -pidfile $PIDFILE \ -procname $PROCESSNAME \ $JAVA_OPTS \ $CATALINA_OPTS \ -cp $CLASSPATH \ org.apache.catalina.startup.Bootstrap # # To get a verbose JVM #-verbose \ # To get a debug of jsvc. #-debug \ RETVAL=$? [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$PROCESSNAME [ $RETVAL -eq 0 ] && success || failure echo }

          function stop ()

          { # # Stop Tomcat # echo -n "Shutting down $PROCESSNAME (Tomcat on port $PORT): " if [ ! -f $PIDFILE ]; then echo echo -n "no PID file found" killproc $PROCESSNAME RETVAL=$? else PID=`cat $PIDFILE` kill $PID RETVAL=$? fi # Remove PID and LOCK files [ $RETVAL -eq 0 ] && rm -f $PIDFILE /var/lock/subsys/$PROCESSNAME # Wait until process is really really dead, or pid file may hang around on restart let count=10 while kill -0 $PID >& /dev/null; do let count-- if (( count < 1 )); then echo "UNABLE TO KILL PROCESS WITH PID '$PID'" kill -9 $PID >& /dev/null RETVAL=$? break fi sleep 1 done [ $RETVAL -eq 0 ] && success || failure echo }

          case "$1" in
          start)
          start
          ;;

          stop)
          stop
          ;;

          restart)
          stop
          start
          ;;

          condrestart)
          if [ -f $PIDFILE ]; then
          stop
          start
          fi
          ;;

          reload)
          if [ -f $PIDFILE ]; then
          PID=`cat $PIDFILE`
          kill -HUP $PID
          RETVAL=$?
          fi
          ;;

          logreopen)
          if [ -f $PIDFILE ]; then
          kill -USR1 `pidof $PROCESSNAME`
          RETVAL=$?
          fi
          ;;

          status)
          status $PROCESSNAME
          RETVAL=$?
          ;;

          *)
          echo "Usage $(basename $0)

          {start|stop|restart|condrestart|reload|logreopen|status}

          "
          ;;

          esac

          exit $RETVAL

          Show
          Mike Polek added a comment - Note that because the pid in the PIDFILE is the child pid and not the parent, and since both need to receive a signal in order to close and reopen their logs, the USR1 signal MUST be sent to the parent. kill -USR1 `pidof $PROCESSNAME` will send the signal to both, which works ok. Ideally the PIDFILE would contain the controller process's pid, since it forwards all signals to the child anyway. For a RedHat style script, you can use something like Source function library. if [ -x /etc/init.d/functions ]; then . /etc/rc.d/init.d/functions else failure() { echo '[FAILED]'; return 1; } success() { echo '[ OK ]'; return 0; } fi PORT=8009 PROCESSNAME=$(basename $0) PROCESSNAME=$ {PROCESSNAME#[SK][[0-9][0-9]} shopt -s extglob PROCESSBASE=$ {PROCESSNAME%%_+([0-9])} shopt -u extglob if [[ "$PROCESSBASE" != "$PROCESSNAME" ]]; then PORT=${PROCESSNAME#$ {PROCESSBASE} _} fi PIDFILE=/var/run/$PROCESSNAME.pid RETVAL=0 # Adapt the following lines to your configuration JAVA_HOME=/opt/java CATALINA_HOME=/opt/tomcat CATALINA_BASE=/opt/$PROCESSBASE TOMCAT_USER=apache TMP_DIR=$CATALINA_BASE/temp LOG_DIR=$CATALINA_BASE/logs OUTFILE=$LOG_DIR/catalina.$PORT.out ERRFILE=$LOG_DIR/catalina.$PORT.err #OUTFILE=SYSLOG1 #ERRFILE=SYSLOG2 JAVA_OPTS="-Xss2m -Xms32m -Xmx1024m" CLASSPATH=\ $JAVA_HOME/lib/tools.jar:\ $CATALINA_HOME/bin/commons-daemon.jar:\ $CATALINA_HOME/bin/bootstrap.jar function start () { # # Start Tomcat # echo -n "Starting $PROCESSBASE (Tomcat on port $PORT): " if [ -e $PIDFILE ] && kill -0 `cat $PIDFILE` >&/dev/null; then echo "PID file found. Not starting daemon." return fi $CATALINA_HOME/bin/jsvc \ -user $TOMCAT_USER \ -home $JAVA_HOME \ -Dcatalina.home=$CATALINA_HOME \ -Dcatalina.base=$CATALINA_BASE \ -Djava.io.tmpdir=$TMP_DIR \ -Dtomcat.server.port=$PORT \ -outfile $OUTFILE \ -errfile $ERRFILE \ -pidfile $PIDFILE \ -procname $PROCESSNAME \ $JAVA_OPTS \ $CATALINA_OPTS \ -cp $CLASSPATH \ org.apache.catalina.startup.Bootstrap # # To get a verbose JVM #-verbose \ # To get a debug of jsvc. #-debug \ RETVAL=$? [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$PROCESSNAME [ $RETVAL -eq 0 ] && success || failure echo } function stop () { # # Stop Tomcat # echo -n "Shutting down $PROCESSNAME (Tomcat on port $PORT): " if [ ! -f $PIDFILE ]; then echo echo -n "no PID file found" killproc $PROCESSNAME RETVAL=$? else PID=`cat $PIDFILE` kill $PID RETVAL=$? fi # Remove PID and LOCK files [ $RETVAL -eq 0 ] && rm -f $PIDFILE /var/lock/subsys/$PROCESSNAME # Wait until process is really really dead, or pid file may hang around on restart let count=10 while kill -0 $PID >& /dev/null; do let count-- if (( count < 1 )); then echo "UNABLE TO KILL PROCESS WITH PID '$PID'" kill -9 $PID >& /dev/null RETVAL=$? break fi sleep 1 done [ $RETVAL -eq 0 ] && success || failure echo } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; condrestart) if [ -f $PIDFILE ]; then stop start fi ;; reload) if [ -f $PIDFILE ]; then PID=`cat $PIDFILE` kill -HUP $PID RETVAL=$? fi ;; logreopen) if [ -f $PIDFILE ]; then kill -USR1 `pidof $PROCESSNAME` RETVAL=$? fi ;; status) status $PROCESSNAME RETVAL=$? ;; *) echo "Usage $(basename $0) {start|stop|restart|condrestart|reload|logreopen|status} " ;; esac exit $RETVAL
          Hide
          Mike Polek added a comment -

          By adding support for log rotation, logging to syslog would be unnecessary.
          issue DAEMON-95 can replace issue DAEMON-80

          Show
          Mike Polek added a comment - By adding support for log rotation, logging to syslog would be unnecessary. issue DAEMON-95 can replace issue DAEMON-80

            People

            • Assignee:
              Mladen Turk
              Reporter:
              Mike Polek
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development