1 Reply Latest reply on Oct 4, 2011 7:34 PM by Brian Wallis

    Custom log4j Appender - activateOptions not called

    Brian Wallis Master

      I'm running JBoss 6.1.0.Final on JDK 1.6.0_26 (mac osx)

       

      I have a custom subclass of org.apache.log4j.FileAppender that implements a size and day rollover of log files (ie: 20M max size and rollover each day as well with a new name that includes the timestamp).

       

      This appender has been used elsewhere (in tomcat) quite successfully.

       

      The configuration is:

       

      {code}

          <log4j-appender class="au.com.infomedix.log.appender.Log4jDatedRollingLogFileAppender">

              <properties>

                  <property name="name">UDRFILE</property>

                  <property name="file">${web.app.data}/log/${jboss.server.name}.log</property>

                  <property name="maxFileSize">5mb</property>

                  <property name="maxLogFilePerDay">1000</property>

                  <property name="append">false</property>

              </properties>

              <error-manager>

                  <only-once />

              </error-manager>

              <formatter>

                  <pattern-formatter pattern="%d %r %-5p [%t] %c{2} - %s%E%n" />

              </formatter>

          </log4j-appender>

      {code}

       

      and this appender, UDRFILE, is added to the rootlogger.

       

      The appender is not being completely initialised. Being a subclass of FileAppender, it needs to have the AppenderSkeleton.activateOptions() method called after the calls to the setter methods to get the logfile writer initialised (activeateOptions() calls setFile() which opens the stream and sets the qw member variable).

       

      The result of not calling activateOptions is that the QuietWriter member of the appender (qw) is never initialised (and is null)

       

      As a nasty side effect of this, it causes an error when append() is called that then calls LogLog.error() which writes to STDERR. Unfortunatly jboss intercepts writes to STDERR (and STDOUT) and feeds them back into the logging subsystems. BANG.

       

      Is there a way to get this to work or should I give up now?  It seems to me that there is code missing in the jboss logger initialisation and it looks difficult to work around.

       

      I have seen this thread on a related but not quite the same issue. Log4j is the 1.2.16 version as comes with JBoss 6.1.

       

      thanks

        • 1. Re: Custom log4j Appender - activateOptions not called
          Brian Wallis Master

          To answer my own question...

           

          The configuration I gave in the post above is not correct, the following works after a hack to the log4j adapter...

           

          {code}

             <log4j-appender name="UDRFILE" class="au.com.infomedix.log.appender.Log4jDatedRollingLogFileAppender">

                  <properties>

                      <property name="name">UDRFILE</property>

                      <property name="file">${web.app.data}/log/${jboss.server.name}.log</property>

                      <property name="maxFileSize">50mb</property>

                      <property name="maxLogFilePerDay">1000</property>

                      <property name="append">true</property>

                      <property name="pattern">%d %r %-5p [%t] %c{2} - %m%n</property>

                  </properties>

                  <error-manager>

                      <only-once />

                  </error-manager>

              </log4j-appender>

          {code}

           

          Note that

          1. The appender name has to be in two places, as an attribute of the log4j-appender element and as a property. This is necessary as the attribute value in the log4j-adapter element is NOT passed through to the log4j appender via it's setName() method, properties are.
          2. The <formatter> element has been removed and a pattern property has been added using standard log4j pattern syntax. The formatter element did not setup the log4j appender's layout value (AppenderSkeleton.setLayout).
          3. I suspect the <error-manager> element does nothing for the log4j adapter but I haven't looked so I left it there, it doesn't break it at least.

           

          The changes I had to make to the log4j adapter are:

          1. I call LogLog.setQuietMode(true) in my constructor as LogLog.debug() et.al. calls seem to call back into the logging framework as they are writing to STDERR and STDOUT which are redirected to the jboss logs.
          2. I had to add a setPattern() method that creates a Layout object and then calls setLayout with it.
          3. I overrode the append method to check if the adapter had been initialised yet and call the activeateOptions() method if not.

           

          Now I have a working log4j adapter configured from jboss-logging.xml.

           

          I do hope all of this has been fixed/rewritten in jboss AS7!