Announcement Announcement Module
Collapse
No announcement yet.
Logging: With or without tomcat using the same log configuration Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Logging: With or without tomcat using the same log configuration

    Perhaps I'm a bit slow, but I'll ask the question anyway.

    I've managed to configure my application to use Log4J when it is deployed to Tomcat by making the following changes to my web.xml:

    Code:
    	<!--
    	  - Key of the system property that should specify the root directory of this
    	  - web app. Applied by WebAppRootListener or Log4jConfigListener.
    	-->
    	<context-param>
    		<param-name>webAppRootKey</param-name>
    		<param-value>cw.root</param-value>
    	</context-param>
    
    	<!--
    	  - Location of the Log4J config file, for initialization and refresh checks.
    	  - Applied by Log4jConfigListener.
    	  -->
    	<context-param>
    		<param-name>log4jConfigLocation</param-name>
    		<param-value>/WEB-INF/log4j.properties</param-value>
    	</context-param>


    When I fire up Tomcat, logging works just the way I've specified in my log4j.properties file.

    My log4j.properties file is in my WEB-INF directory, where I think web application configuration files belong.

    Copying log4j.properties somewhere else seems like bad practice.

    Moving log4j.properties would break my Tomcat logging.

    So far, so good.

    Now the problem.

    I've got unit tests and scheduled jobs that Maven2 runs insidethe Spring container but outside the servlet container.

    In one of my tests, I get an instance of org.apache.commons.logging.Log:

    Code:
    	private Log log = LogFactory.getLog(getClass());
    and write to the log file:

    Code:
    log.debug("Some debug text here");
    And I get nothing.

    It's a bit of a catch-22. I can't find the source of a problem because I don't have logging enabled. But I can't enable logging outside Tomcat because something (possibly obvious) is eluding me.

    I've spent the better part of 2 days trying to figure out how to get logging to work with my tests and my automated jobs without breaking my logging in Tomcat.

    Any help is greatly appreciated.

  • #2
    Just create another log4.properties in the classpath of the running unit tests. That shuold be enough.

    Furthermore:
    Placing the log4.properties within your webapplication is not always the best practice. For as far as I know, the Log4jConfigListener detects changes to your log4.properties and that may be of use when you temporairly want to change your logging level.
    When deployed to a production environment you usually use WARN as a regular level, but when you have problems, you may want to switch to DEBUG.
    When the log4.properties is in your webapplication, this means you have to re-deploy you application just to change the log level

    Comment


    • #3
      Thanks for the response, momania.

      Since I'm using Maven2, I added a new folder src/main/resources to the project, then added the folder to the list of testResources:

      Code:
      <testResources>
      	<testResource>
      		<directory>src/main/webapp</directory>
      		<includes>
      			<include>**/*.xml</include>
      			<include>**/*.properties</include>
      		</includes>
      	</testResource>
      	<testResource>
      		<directory>src/main/resources</directory>
      		<includes>
      			<include>**/*.xml</include>
      			<include>**/*.properties</include>
      		</includes>
      	</testResource>
      </testResources>
      I copied my log4j.properties file to my new folder. Here's what it looks like, btw:

      Code:
      # For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
      # For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
      log4j.rootLogger=INFO, stdout, logfile
      
      log4j.appender.stdout=org.apache.log4j.ConsoleAppender
      log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
      log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
      
      log4j.appender.logfile=org.apache.log4j.RollingFileAppender
      #log4j.appender.logfile.File=${cw.root}/WEB-INF/cw_interface.log
      log4j.appender.logfile.File=C:/work/workspace/compliance_wire/debug.log
      log4j.appender.logfile.MaxFileSize=10MB
      
      # Keep three backup files.
      log4j.appender.logfile.MaxBackupIndex=3
      
      # Pattern to output: date priority [category] - message
      log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
      log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
      I did a 'mvn clean test' and watched maven execute my tests.

      I peeked in the target/classes directory, and I see that log4j.properties was copied to the classpath by maven.

      Looks like I'm making progress. Progress is good.

      Now to see if it worked... BAH!

      There's no new log file where my copied log4j.properties file says it should be.

      ::scratches head::

      Am I still missing something obvious?

      Comment


      • #4
        If the log4j.properties file is on the classpath and you've set the right log levels I don't see why it wouldn't work............

        Comment


        • #5
          Originally posted by karldmoore View Post
          If the log4j.properties file is on the classpath and you've set the right log levels I don't see why it wouldn't work............
          Indeed, but remember it has to be at the root of the classpath, so not hidden in any folder.

          Comment


          • #6
            If I understand your situation correctly, you could also set a system property when running junit tests:
            -Dlog4j.configuration=file:/path/to/webapp/WEB-INF/log4j.properties

            Comment


            • #7
              I'm not sure why it's not working, but I will tell you what has worked for me:

              1) Create a src/main/resources/log4j.properties: this is the one that gets packaged as part of the war (in WEB-INF/classes)

              2) Create a src/test/resources/log4j.properties: this is the one that gets picked up for logging unit tests

              With the above configuration, it requires the following change to the web.xml:
              Code:
              <context-param>
                <param-name>log4jConfigLocation</param-name>
                <param-value>/WEB-INF/classes/log4j.properties</param-value>
              </context-param>
              In addition, you can remove the <testResources> element from your pom.xml; the above configuration is (I think) standard.

              This works out well because I have my src/main/resources/log4j.properties outputting to a file within $CATALINA_HOME/logs, while having my src/test/resources/log4j.properties outputting to a file within my project.

              Not sure if that will work, but like I said, it does for me...

              Good luck!

              Comment


              • #8
                a sugestion.
                not sure if this would help.
                try to use a log file that is relative to the current directory.
                instead of
                Code:
                log4j.appender.logfile.File=C:/work/workspace/compliance_wire/debug.log
                try
                Code:
                log4j.appender.logfile.File=debug.log
                just a suggestion

                Comment


                • #9
                  Hmmm...

                  First, I tried Arthur's suggestion and added created log4j.properties file in 'src/test/resources'. I even moved all of my Spring test *-context.xml files to that directory. Maven runs my tests and picks up my context files just fine, but no test log was created anywhere on my machine.

                  I tried passing the log file location to maven with a

                  Code:
                  mvn -Dlog4j.configuration=file:C:/work/workspace/compliance_wire/src/test/resources/log4j.properties clean site
                  No log file with this approach either.

                  I tried using a file relative to the current directory, instead of using an absolute path.

                  Still, nothing different happened there for me.

                  Finally, I tried standing on my desk at work and screaming at the top of my lungs.

                  I then did another clean-compile-test and still saw no log file for my tests. Screaming didn't seem to get things working for me either, and I think I scared someone's kid.

                  Is this supposed to be such a PITA or am I just missing something?

                  Let's recap it one more time, shall we?

                  Currently I have my test log4j.properties file here:

                  Code:
                  /src/test/resources/log4j.properties

                  Here's my test log4j.properties file:

                  Code:
                  # For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
                  # For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
                  log4j.rootLogger=DEBUG, application, jms
                  
                  log4j.appender.stdout=org.apache.log4j.ConsoleAppender
                  log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
                  log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
                  
                  #JMS Appender
                  log4j.appender.jms=org.apache.log4j.RollingFileAppender
                  log4j.appender.jms.MaxFileSize=10MB
                  log4j.appender.jms.File=test_jms.log
                  log4j.appender.jms.layout=org.apache.log4j.PatternLayout
                  log4j.appender.jms.layout.ConversionPattern=%d %p [%c] - %m%n
                  
                  
                  #Application Appender
                  log4j.appender.application=org.apache.log4j.RollingFileAppender
                  log4j.appender.application.File=log4j.appender.logfile.File=test_servlet.log
                  log4j.appender.application.MaxFileSize=10MB
                  log4j.appender.application.layout=org.apache.log4j.PatternLayout
                  log4j.appender.application.layout.ConversionPattern=%d %p [%c] - %m%n
                  
                  #Filters
                  log4j.category.org.apache.commons.digester=WARN
                  log4j.category.org.springframework=INFO
                  log4j.category.org.hibernate=INFO
                  log4j.category.org.hibernate=INFO
                  log4j.category.org.apache.activemq=DEBUG
                  
                  # Keep three backup files.
                  log4j.appender.logfile.MaxBackupIndex=3

                  And... yeah.

                  Any (further) help is greatly appreciated.

                  Comment


                  • #10
                    Originally posted by elusivemel View Post
                    I tried passing the log file location to maven with a

                    Code:
                    mvn -Dlog4j.configuration=file:C:/work/workspace/compliance_wire/src/test/resources/log4j.properties clean site
                    No log file with this approach either.
                    Did you configure your maven file to start a new jvm when running tests? If that's the case you might have to set the property where the tests are run, not when maven is started.

                    Comment


                    • #11
                      Originally posted by manifoldronin View Post
                      Did you configure your maven file to start a new jvm when running tests? If that's the case you might have to set the property where the tests are run, not when maven is started.
                      I looked at my pom.xml and I'm not creating a new JVM for each test. I wanted to reuse the same application context for all of my tests instead of reloading it before every test.

                      Here's that part of my pom.xml


                      Code:
                      <plugin>
                      	<artifactId>maven-surefire-plugin</artifactId>
                      	<executions>
                      		<execution>
                      			<id>surefire-it</id>
                      			<phase>integration-test</phase>
                      			<goals>
                      				<goal>test</goal>
                      			</goals>
                      		</execution>
                      	</executions>
                      	<configuration>
                      		<systemProperties>
                      			<property>
                      				<name>cactus.contextURL</name>
                      				<value>
                      					http://localhost:8080/${artifactId}
                      				</value>
                      			</property>
                      		</systemProperties>
                      	</configuration>
                      </plugin>


                      Any further help is greatly appreciated.

                      Comment

                      Working...
                      X