Solved

log4j - log message shown in different log files

Posted on 2007-03-21
22
692 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
How to simplify a groovy script that reads a WS because the result being sent back is simpler 1 46
eclipse shortcuts 9 45
oracle 11g 23 49
servlet example issue 6 31
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:

910 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now