Solved

log4j - log message shown in different log files

Posted on 2007-03-21
22
696 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
  • 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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 

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

Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Weekend adv creator 3 39
factorial example 4 41
runtime exception 2 30
Android development question 2 38
For customizing the look of your lightweight component and making it look opaque like it was made of plastic.  This tip assumes your component to be of rectangular shape and completely opaque.   (CODE)
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
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 …
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …

832 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