Solved

log4j - log message shown in different log files

Posted on 2007-03-21
22
712 Views
Last Modified: 2008-02-01
I have a old java application using the following to create the log file called, schedule.log
=======================
public class CreateLog4J
{
   protected void LaunchLogFile() throws Exception
   {
    // Log layout handler
    schedulerLogger.setLevel(Level.INFO);
    schedulerLayout   = new SimpleLayout();
    schedulerAppender = new ConsoleAppender(schedulerLayout);
    schedulerLogger.addAppender(schedulerAppender);
    schedulerLogger.addAppender(new FileAppender(schedulerLayout, "scheduler.log"));
   }
   
  public static Logger schedulerLogger = Logger.getLogger("scheduler.log");
  Appender      schedulerAppender;
  SimpleLayout  schedulerLayout;
 
}
=========================
For further enhancement, we have created a log4j.xml file to create another log file called, payroll.log,
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
       
  <appender name="appender" class="org.apache.log4j.FileAppender">
    <param name="File" value="payroll.log"/>
    <param name="Append" value="false"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
    </layout>
  </appender>

  <root>
    <priority value ="debug"/>
    <appender-ref ref="appender"/>
  </root>

</log4j:configuration>

==========================
The problem is

The log message supposed to send to the schedule.log goes to the payroll.log

for example:
the below line is to send the log message to schedule.log
cl.schedulerLogger.info(sdf.format(new Date()) + " - Scheduler is currently up and running on terminal " + terminal_no);

======================
Notes: log4j.xml resides in the root folder
0
Comment
Question by:LeanMoreTryMore
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 13
  • 8
22 Comments
 
LVL 92

Expert Comment

by:objects
ID: 18768416
>    protected void LaunchLogFile() throws Exception

does that method actually get called.
0
 

Author Comment

by:LeanMoreTryMore
ID: 18768810
The LaunchLogFile gets called from the main program and i expect the log messge only send to schedule.log instead of both schedule.log and payroll.log
0
 
LVL 92

Expert Comment

by:objects
ID: 18768830
>   public static Logger schedulerLogger = Logger.getLogger("scheduler.log");

that gets called *before* LaunchLogFile gets called so will reference logger from config file
0
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 

Author Comment

by:LeanMoreTryMore
ID: 18768895
Many thanks object. it does make sense.

How do i resolve this? please advise
==================
      public static void main(String[] args) {
         userName  = args[0];
         pwd       = args[1];
         dbName    = args[2];

         try {
           int dbConnOk = Utilities.SQLJdbConnection(userName, pwd, dbName);          
         }  
         catch (Exception e) {
           e.printStackTrace();
           System.exit(1);            
         }
      }

      private UTeventScheduler() throws Exception  {
        if ((ml.checkFileSize() > 1500000) && (ml.renameFile()))  ml.deleteLogfile();      
        cl.LaunchLogFile();
.
.
.
0
 
LVL 92

Expert Comment

by:objects
ID: 18768916
looks like u need to change CreateLog4J class and assign schedulerLogger inside the method

0
 

Accepted Solution

by:
iXian_ earned 300 total points
ID: 18768943
Log4J loggers are hierarchal, with each logger being given a name separated by periods, similar to fully qualified java class names, for example:

    Logger log1 = Logger.getLogger("com.acme.foobar.Scheduler");
    Logger log2 = Logger.getLogger("com.acme.logthis");
    Logger log3 = Logger.getLogger("com.acme.payroll.Calculator");
    Logger log3 = Logger.getLogger("com.acme.payroll.Deposit");

Note that although the logger names could (and typically do) represent java class names, they can be anything, although levels in the hierarchy are represented as periods.  In the examples above, com.acme.foobar is a parent of com.acme.foobar.Scheduler, com.acme is a parent of all three, etc.
The "root" level is the top of the hierarchy, and a catchall for everything.  

Log4J appenders are attached to hierarchy levels, and log messages generated by any loggers at that level or below.  In your log4j.xml configuration file (presumably in the root of a directory or JAR file in your classpath), your code example specifies that the payroll.log file appender should log all events under root, including anything being generated by the "scheduler.log" logger.  Multiple appenders may log an event, and in your code example, the messages should be logging to both the payroll.log appender attached to the root level, and the scheduler.log appender attached at the "scheduler.log" level.  

Also, in your example, it seems that you're naming your logger "scheduler.log" when this is presumably where you want the log to go.  In general, you should use package/class names for your logger names, and map appenders to that naming hierarchy.

Here's an example of how you want to might want to create a logger:

    package com.acme.foobar;
    Class Scheduler {
        Logger log = Logger.getLogger("com.acme.foobar.Scheduler");
        public void method() {
           ...
           log.info("this is an informational message from the Scheduler class");
           ...
        }
    }

Here's an example that illustrates how they wire up.  Also here I show how you could move the configuration of the console appender out of the code and into configuration -- in general, you probably want to leave the configuration of your logging out of source
code.  

    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

      <!-- console appender for scheduler (and perhaps other stuff too) -->
      <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.SimpleLayout"/>
      </appender>

      <!-- payroll file appender -->
      <appender name="PayrollLogAppender" class="org.apache.log4j.FileAppender">
        <param name="File" value="payroll.log"/>
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
        </layout>
      </appender>

      <!-- everything info level or better goes to the console by default -->
      <root>
        <priority value="info"/>
        <appender-ref ref="schedulerAppender"/>
      </root>

      <!-- stuff under payroll namespace will also go to the payroll file -->
      <logger name="com.acme.payroll">
        <!-- Print only messages of level info or greater -->
        <level value="debug"/>
      </logger>

    </log4j:configuration>
0
 

Author Comment

by:LeanMoreTryMore
ID: 18768990

I dont want the payroll.log created after the payrol process is initiated from within the job scheduler.
schedule.log is created from job scheduler

any idea. please help
0
 
LVL 92

Expert Comment

by:objects
ID: 18768999
u need to modify CreateLog4J, don't see any way around it.
Why don't u get rid of it alltogether?
0
 

Author Comment

by:LeanMoreTryMore
ID: 18769006
ok. let say i get rid of the createLog4j class. so what can i do next
i only want to create the payroll.log file when the payroll process is initiated from within the scheduler
0
 
LVL 92

Expert Comment

by:objects
ID: 18769019
> i only want to create the payroll.log file when the payroll process is initiated from within the scheduler

not sure I follow, do you mean logging destination should change once payroll process is initiated?
0
 

Author Comment

by:LeanMoreTryMore
ID: 18769021
if i use the following log4j.xml file. how to do i create 2 log file. and most important is i only want to create the payroll.log file where the payroll process is initiated

The following is used to create the schedule.log file
=======================================================================
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
       
  <appender name="appender" class="org.apache.log4j.FileAppender">
    <param name="File" value="schedule.log"/>
    <param name="Append" value="false"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
    </layout>
  </appender>

  <root>
    <priority value ="debug"/>
    <appender-ref ref="appender"/>
  </root>

</log4j:configuration>
0
 
LVL 92

Expert Comment

by:objects
ID: 18769033
u create another appender for payroll.log (as u have in your question)
then define a seperate logger that uses that appender
0
 

Author Comment

by:LeanMoreTryMore
ID: 18769042
the scheduler will initiate the payroll process from within the job scheduler

scheduler will use the  Runtime.getRuntime().exec method to initiate the Payroll program

"C:\Java\jdk1.5\jre\bin\java.exe" -classpath "C:\corpdev6i\JavaAppl;C:\Java\jdk1.5\sqlj\lib\runtime12.jar;C:\Java\jdk1.5\lib\mail.jar;C:\Java\jdk1.5\lib\activation.jar;C:\Hibernate\hibernate-3.1\hibernate3.jar;C:\Hibernate\hibernate-3.1\lib\antlr-2.7.5H3.jar;C:\Hibernate\hibernate-3.1\lib\asm.jar;C:\Hibernate\hibernate-3.1\lib\asm-attrs.jar;C:\Hibernate\hibernate-3.1\lib\cglib-2.1.3.jar;C:\Hibernate\hibernate-3.1\lib\jaxen-1.1-beta-7.jar;C:\Hibernate\hibernate-3.1\lib\jdbc2_0-stdext.jar;C:\Hibernate\hibernate-3.1\lib\jta.jar;C:\Hibernate\hibernate-3.1\lib\log4j-1.2.11.jar;C:\Hibernate\hibernate-3.1\lib\commons-collections-2.1.1.jar;C:\Hibernate\hibernate-3.1\lib\commons-logging-1.0.4.jar;C:\Hibernate\hibernate-3.1\lib\xerces-2.6.2.jar;C:\Hibernate\hibernate-3.1\lib\xml-apis.jar;C:\Hibernate\hibernate-3.1\lib\ehcache-1.1.jar;C:\Hibernate\hibernate-3.1\lib\dom4j-1.6.1.jar;C:\Hibernate\hibernate-3.1\lib\jaas.jar;C:\Hibernate\hibernate-3.1\lib\classes12.jar;C:\Java\jdk1.5\jdbc\lib\ojdbc14dms.jar;C:\Java\jdk1.5\jdbc\lib\ocrs12.jar;C:\Java\jdk1.5\diagnostics\lib\ojdl.jar;C:\Java\jdk1.5\lib\dms.jar;C:\Java\jdk1.5\xdk\lib\xml.jar;C:\Java\jdk1.5\xdk\lib\xmlparserv2.jar"  dirHibernate.payroll Payroll Full null null gdev

Only the Payroll program is exected i want the payrol.log file being created
0
 

Author Comment

by:LeanMoreTryMore
ID: 18769044
would u give me a simple example using a seperate logger that uses that appender
0
 

Author Comment

by:LeanMoreTryMore
ID: 18769059
Can I change the log4j.xml like below
==========================================================================
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
       
  <appender name="appender" class="org.apache.log4j.FileAppender">
    <param name="File" value="schedule.log"/>
    <param name="Append" value="true"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
    </layout>
  </appender>

  <root>
    <priority value ="debug"/>
    <appender-ref ref="appender"/>
  </root>

  <appender name="PayrollAppender" class="org.apache.log4j.FileAppender">
    <param name="File" value="payroll.log"/>
    <param name="Append" value="false"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
    </layout>
  </appender>

  <root>
    <priority value ="debug"/>
    <appender-ref ref="PayrollAppender"/>
  </root>

</log4j:configuration>
0
 

Author Comment

by:LeanMoreTryMore
ID: 18769143
I change the log4j.xml like below

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

  <appender name="SchedulerAppender" class="org.apache.log4j.FileAppender">
    <param name="File" value="schedule.log"/>
    <param name="Append" value="true"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
    </layout>
  </appender>        

  <appender name="PayrollAppender" class="org.apache.log4j.FileAppender">
    <param name="File" value="Ppar.log"/>
    <param name="Append" value="false"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
    </layout>
  </appender>

  <root>
    <priority value ="debug"/>
    <appender-ref ref="SchedulerAppender"/>
  </root>

</log4j:configuration>
================================================================
HOw do i assign the SchedulerAppender?

public class Scheduler extends MailUtilities implements EvtConfig {
    // Protected variables to be used as IN parameters
   
    private static final Log log = LogFactory.getLog(Scheduler .class);
0
 

Author Comment

by:LeanMoreTryMore
ID: 18769168
Now my log4j.xml file like below:
===========================================================================
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

  <appender name="SchedulerAppender" class="org.apache.log4j.FileAppender">
    <param name="File" value="schedule.log"/>
    <param name="Append" value="true"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
    </layout>
  </appender>        

  <appender name="PayrollAppender" class="org.apache.log4j.FileAppender">
    <param name="File" value="Ppar.log"/>
    <param name="Append" value="false"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
    </layout>
  </appender>

  <root>
    <priority value ="debug"/>
    <appender-ref ref="SchedulerAppender"/>
  </root>

</log4j:configuration>
===============================================================================
My schedule program to use the logfacotry

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Scheduler extends MailUtilities implements EvtConfig {
    private static final Log log = LogFactory.getLog(UTeventScheduler.class);
.
.
    log.debug(" - Scheduler is currently up and running on terminal " + terminal_no);


========================================================================
I got the following error:

log4j:ERROR The content of element type "log4j:configuration" must match "(renderer*,appender*,(category|logger)*,root?,categoryFactory?)".

======================================================================
Why I got the above error
0
 
LVL 92

Expert Comment

by:objects
ID: 18769172
see the example posted above by iXian

to get logger use:

  public static final Logger schedulerLogger = Logger.getLogger(Scheduler.class);
0
 

Author Comment

by:LeanMoreTryMore
ID: 18769179
public static final Logger schedulerLogger = Logger.getLogger(Scheduler.class);

How do i know which appender it uses
0
 
LVL 92

Assisted Solution

by:objects
objects earned 200 total points
ID: 18769221
selects looger that matches name, and then logs to its appenders
0
 

Author Comment

by:LeanMoreTryMore
ID: 18776569
Thanks for both iXian and Object
0
 

Author Comment

by:LeanMoreTryMore
ID: 18776577
How do i split the point as the web page looks different as used to be?
0

Featured Post

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Suggested Courses

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question