Tomcat only reads Log4j.properties when restarted

Asked

Viewed 379 times

4

Until recently I made file changes log4j.properties (ex: change the level of the Testemb class) and simply redeploy the application. Now, the changes only take effect when I restart Tomcat.

I wonder what happened?

Log4j.properties

log4j.rootCategory = WARN, console
log4j.category.console = WARN
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{dd-MM-yyyy HH:mm:ss} %p %c:%L (%M) %m%n 

log4j.logger.br.com.nilson.control.TesteMB=INFO
  • Tomcat7.0.47
  • Log4j 1.2.16
  • It is a difficult problem to diagnose the distance, but do the following test: (1) start the Tomcat and the application, (2) generate some logs, (3) stop the application (stop) keeping the Tomcat running and finally (4) see if the log file can be deleted (deleted from disk). My suspicion is that there may be some static log reference that is not being finalized.

  • Yes, it may well be a classloader Leak. log4j.properties is usually loaded by classloader.

  • I agree with @Elias . Tomcat’s Log4j must be conflicting with your application’s log4j.

2 answers

1


Apparently, I was able to solve my problem using a Log4j initializer

public class Log4jConfigLoader extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    public void init() throws ServletException {
        super.init();
        try {
            URL url = Loader.getResource("log4j.properties");
            PropertyConfigurator.configure(url);
        } catch (Exception e) {
            System.out.println("Could not start log4.properties monitor");
        }
    }
}

WEB.INF

<servlet>
    <servlet-name>log4j-init</servlet-name>
    <servlet-class>br.com.uniondata.servlet.Log4jConfigLoader</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

1

It is possible to do as follows:

To make Log4j reload your configuration file automatically when it undergoes changes, you can do this with the configureAndWatch method. But the default boot procedure does not use configureAndWatch (if you just put the .properties file in the classpath). That way you can write little code for Log4j to do this. The solution I found was the implementation of a Tomcat Lifecyclelistener.

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.log4j.LogManager;
import org.apache.log4j.PropertyConfigurator;

public class Log4JInitializer implements LifecycleListener
{
    private String propertiesFile;

    public String getPropertiesFile()
    {
        return this.propertiesFile;
    }

    public void setPropertiesFile(String propertiesFile)
    {
        this.propertiesFile = propertiesFile;
    }

    @Override
    public void lifecycleEvent(LifecycleEvent event)
    {
        if (Lifecycle.BEFORE_START_EVENT.equals(event.getType()))
            initializeLog4j();
    }

    private void initializeLog4j()
    {
        //Log4j monitora o arquivo para mudanças
        PropertyConfigurator.configureAndWatch(propertiesFile);

        // shutdown log4j (e na thread monitor) no shutdown
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                LogManager.shutdown();
            }
        });
    }
}

EDIT

monitor "BEFORE_START_EVENT", and when this happens (which is once by Tomcat booting) I boot Log4j using the configureAndWatch method. Also don’t forget to set up a clean Shutdown Hook Log4j thread created to query the configuration file for changes (I could also have chosen to listen to Tomcat’s "AFTER_STOP_EVENT" instead).

This package is in a jar. Put it in the Tomcat classpath, and now you can configure it in your Tomcat serverl.xml.

thus:

<Server>
   <Listener className="Log4JInitializer" propertiesFile="/path/to/log4j.properties"/>
</Server>
  • Where do I set up this Switch? I tried to include it in the WEB.INF but it doesn’t seem to be triggered.

  • I edited with the server.xml settings

  • I think this is not the best way, because apparently I will have a log4j.properties for all my server’s apps, no?

  • The log is application. Not server. So yes, you would have to configure the log4J for each application normally.

  • Got it. then the properties will grow according to the amount of apps.

  • That’s right. for every Voce application you can make a specialized system

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.