You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Jeff Drew <je...@gmail.com> on 2006/04/15 01:38:08 UTC

inheritance dilemma

Some code I'm writing runs in two different environments.  In one
environment, I'm using log4j. In the other environment, the code calls that
environment's logging system.  Therefore, I need to subclass log4j's Logger
so that I can implement an interface required by the other logging system.
I have a solution working with one big drawback.  The %F and %L specfied in
the Appender's Conversion Pattern always return the same file and line
number of my log4j subclass, not the class that originated the logging
event.

Is there a better solution to my inheritance dilemma? Or is there some way
to pass log4j the file and line number arguments?

Thanks!

/* The Log interface is specified by the non-log4j environment.  The methods
have the same name as log4j. */
public class LoggerX extends Logger implements Log {
    /**
     * @param arg0
     */
    public LoggerX( String arg0 ) {
        super( arg0 );
        parent = super.getLogger( arg0 );
    }

    static int       logEnvironment = 0;

    final static int ENVIRONMENT_1            = 0;

    final static int ENVIRONMENT_2       = 1;

    // the log4j logger returned by super.getLogger
    Logger           parent         = null;

    public  static LoggerX getLoggerForEnv( String arg0 ) {
        switch ( logEnvironment ) {
            case ENVIRONMENT_1 :
                return ( LoggerX ) OtherEnvironment.getLogger( );

            case ENVIRONMENT_2 :
                System.out.println( "creating new ENVIRONMENT_2 logger" );
                return new LoggerX( arg0 );

            default :
                System.out.println( "************ UNKNOWN LOGGER TYPE: " +
logEnvironment + " *************" );
        }
        return null;
    }

   /* this call produces the same file and line number regardless of the
caller.  I know why, but I don't have a solution.  */
    public boolean info(String arg0) {
        parent.info( arg0);
    }

   public static void setEnvironmentTo1() {
        logEnvironment = ENVIRONMENT_1;
    }

    public static void setEnvironmentTo2() {
        logEnvironment = ENVIRONMENT_2;
    }
}

Re: inheritance dilemma

Posted by Jeff Drew <je...@gmail.com>.
Thank you for the explanation and the help.  I now have working code and
knowledge of why it works.

On 4/17/06, Jacob Kjome <ho...@visi.com> wrote:
>
> At 10:16 AM 4/16/2006, you wrote:
> >Thanks Jake,
> >
> >It makes sense to me.  I just want to confirm that I'm creating an
> instance
> >of LoggerX for each FQCN, just as I usually call Logger.getLogger to use
> >log4j directly. correct?
> >
>
> I'm not 100% sure I'm understanding your question?  I'll try to
> clarify.  The FQCN has nothing to do with the current
> loggerName.  Instead, it is a static final value that represents the
> fully qualified class name of the LoggerX class.  The FQCN does not
> ever change.  It has nothing to do with logger instances.  When you
> log, the FQCN is passed along to the called logging method.  This
> allows Log4j to properly parse stack traces to determine which method
> was called, in the case where that is specified in the pattern for
> the appender.  It lets Log4j know that it is not the call from the
> wrapper class that is the method to be shown, but from the class
> using the wrapper class.
>
> Jake
>
>
> >Thanks again,
> >
> >Jeff
> >
> >On 4/15/06, Jacob Kjome <ho...@visi.com> wrote:
> >>
> >>
> >> No,
> >>
> >> FQCN only comes into play when you log something.  It should be...
> >>
> >> public LoggerX(String loggerName) {
> >>      logger = Logger.getLogger(loggerName);
> >> }
> >>
> >> Then, as in the example I provided, you would do this in the debug()
> >> method...
> >>
> >> public final void debug(String message, Throwable th) {
> >>       logger.log(FQCN, Level.DEBUG, message, th);
> >> }
> >>
> >> You will need to create methods for each level you want to log to,
> >> equivalent to the debug() example I have provided.
> >>
> >> Make sense?
> >>
> >> Jake
> >>
> >> At 07:39 AM 4/15/2006, you wrote:
> >> >Jake,
> >> >So the constructor should read:
> >> >
> >> >
> >> >    public LoggerX(String FQCN)  {
> >> >        logger = Logger.getLogger(FQCN);
> >> >    }
> >> >
> >> >correct?
> >> >
> >> >Thanks
> >> >
> >> >Jeff
> >> >
> >> >On 4/14/06, Jacob Kjome <ho...@visi.com> wrote:
> >> >>
> >> >>
> >> >> Whoops, I didn't mean to expose the Logger in the constructor.  I
> >> >> meant that to be a Class or a String and then create the logger
> >> >> inside the constructor.  Anyway, you get the idea.
> >> >>
> >> >> Jake
> >> >>
> >> >> At 08:34 PM 4/14/2006, you wrote:
> >> >> >
> >> >> >You shouldn't be extending Logger, but wrapping it.  When you log,
> >> >> >pass the fully qualified class name (FQCN) of your wrapper to the
> >> >> >logger methods and your line numbers will work just fine.  For
> >> >> instance...
> >> >> >
> >> >> >public class LoggerX implements Log {
> >> >> >     /*
> >> >> >      * Constant for name of class to use when recording caller
> >> >> >      * of log method. Appending a dot at the end is recommended
> >> >> practice.
> >> >> >      */
> >> >> >     private static final String FQCN = LoggerX.class.getName() +
> ".";
> >> >> >
> >> >> >     private final Logger logger;
> >> >> >
> >> >> >     public LoggerX(Logger delegate)  {
> >> >> >         logger = delegate;
> >> >> >     }
> >> >> >
> >> >> >     public boolean isDebugEnabled() {
> >> >> >         return logger.isDebugEnabled();
> >> >> >     }
> >> >> >
> >> >> >     public final void debug(String message) {
> >> >> >         logger.log(FQCN, Level.DEBUG, message, null);
> >> >> >     }
> >> >> >
> >> >> >     ....
> >> >> >     ....
> >> >> >     ....
> >> >> >}
> >> >> >
> >> >> >
> >> >> >Jake
> >> >> >
> >> >> >At 06:38 PM 4/14/2006, you wrote:
> >> >> > >Some code I'm writing runs in two different environments.  In one
> >> >> > >environment, I'm using log4j. In the other environment, the code
> >> calls
> >> >> that
> >> >> > >environment's logging system.  Therefore, I need to subclass
> log4j's
> >> >> Logger
> >> >> > >so that I can implement an interface required by the other
> logging
> >> >> system.
> >> >> > >I have a solution working with one big drawback.  The %F and %L
> >> >> specfied in
> >> >> > >the Appender's Conversion Pattern always return the same file and
> >> line
> >> >> > >number of my log4j subclass, not the class that originated the
> >> logging
> >> >> > >event.
> >> >> > >
> >> >> > >Is there a better solution to my inheritance dilemma? Or is there
> >> some
> >> >> way
> >> >> > >to pass log4j the file and line number arguments?
> >> >> > >
> >> >> > >Thanks!
> >> >> > >
> >> >> > >/* The Log interface is specified by the non-log4j
> >> >> environment.  The methods
> >> >> > >have the same name as log4j. */
> >> >> > >public class LoggerX extends Logger implements Log {
> >> >> > >    /**
> >> >> > >     * @param arg0
> >> >> > >     */
> >> >> > >    public LoggerX( String arg0 ) {
> >> >> > >        super( arg0 );
> >> >> > >        parent = super.getLogger( arg0 );
> >> >> > >    }
> >> >> > >
> >> >> > >    static int       logEnvironment = 0;
> >> >> > >
> >> >> > >    final static int ENVIRONMENT_1            = 0;
> >> >> > >
> >> >> > >    final static int ENVIRONMENT_2       = 1;
> >> >> > >
> >> >> > >    // the log4j logger returned by super.getLogger
> >> >> > >    Logger           parent         = null;
> >> >> > >
> >> >> > >    public  static LoggerX getLoggerForEnv( String arg0 ) {
> >> >> > >        switch ( logEnvironment ) {
> >> >> > >            case ENVIRONMENT_1 :
> >> >> > >                return ( LoggerX ) OtherEnvironment.getLogger( );
> >> >> > >
> >> >> > >            case ENVIRONMENT_2 :
> >> >> > >                System.out.println( "creating new ENVIRONMENT_2
> >> logger"
> >> >> );
> >> >> > >                return new LoggerX( arg0 );
> >> >> > >
> >> >> > >            default :
> >> >> > >                System.out.println( "************ UNKNOWN LOGGER
> >> TYPE:
> >> >> " +
> >> >> > >logEnvironment + " *************" );
> >> >> > >        }
> >> >> > >        return null;
> >> >> > >    }
> >> >> > >
> >> >> > >   /* this call produces the same file and line number regardless
> of
> >> >> the
> >> >> > >caller.  I know why, but I don't have a solution.  */
> >> >> > >    public boolean info(String arg0) {
> >> >> > >        parent.info( arg0);
> >> >> > >    }
> >> >> > >
> >> >> > >   public static void setEnvironmentTo1() {
> >> >> > >        logEnvironment = ENVIRONMENT_1;
> >> >> > >    }
> >> >> > >
> >> >> > >    public static void setEnvironmentTo2() {
> >> >> > >        logEnvironment = ENVIRONMENT_2;
> >> >> > >    }
> >> >> > >}
> >> >> >
> >> >> >
> >> >>
> >---------------------------------------------------------------------
> >> >> >To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> >> >> >For additional commands, e-mail: log4j-user-help@logging.apache.org
> >> >> >
> >> >> >
> >> >> >
> >> >>
> >> >>
> >> >>
> ---------------------------------------------------------------------
> >> >> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> >> >> For additional commands, e-mail: log4j-user-help@logging.apache.org
> >> >>
> >> >>
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> >> For additional commands, e-mail: log4j-user-help@logging.apache.org
> >>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-user-help@logging.apache.org
>
>

Re: inheritance dilemma

Posted by Jacob Kjome <ho...@visi.com>.
At 10:16 AM 4/16/2006, you wrote:
 >Thanks Jake,
 >
 >It makes sense to me.  I just want to confirm that I'm creating an instance
 >of LoggerX for each FQCN, just as I usually call Logger.getLogger to use
 >log4j directly. correct?
 >

I'm not 100% sure I'm understanding your question?  I'll try to 
clarify.  The FQCN has nothing to do with the current 
loggerName.  Instead, it is a static final value that represents the 
fully qualified class name of the LoggerX class.  The FQCN does not 
ever change.  It has nothing to do with logger instances.  When you 
log, the FQCN is passed along to the called logging method.  This 
allows Log4j to properly parse stack traces to determine which method 
was called, in the case where that is specified in the pattern for 
the appender.  It lets Log4j know that it is not the call from the 
wrapper class that is the method to be shown, but from the class 
using the wrapper class.

Jake


 >Thanks again,
 >
 >Jeff
 >
 >On 4/15/06, Jacob Kjome <ho...@visi.com> wrote:
 >>
 >>
 >> No,
 >>
 >> FQCN only comes into play when you log something.  It should be...
 >>
 >> public LoggerX(String loggerName) {
 >>      logger = Logger.getLogger(loggerName);
 >> }
 >>
 >> Then, as in the example I provided, you would do this in the debug()
 >> method...
 >>
 >> public final void debug(String message, Throwable th) {
 >>       logger.log(FQCN, Level.DEBUG, message, th);
 >> }
 >>
 >> You will need to create methods for each level you want to log to,
 >> equivalent to the debug() example I have provided.
 >>
 >> Make sense?
 >>
 >> Jake
 >>
 >> At 07:39 AM 4/15/2006, you wrote:
 >> >Jake,
 >> >So the constructor should read:
 >> >
 >> >
 >> >    public LoggerX(String FQCN)  {
 >> >        logger = Logger.getLogger(FQCN);
 >> >    }
 >> >
 >> >correct?
 >> >
 >> >Thanks
 >> >
 >> >Jeff
 >> >
 >> >On 4/14/06, Jacob Kjome <ho...@visi.com> wrote:
 >> >>
 >> >>
 >> >> Whoops, I didn't mean to expose the Logger in the constructor.  I
 >> >> meant that to be a Class or a String and then create the logger
 >> >> inside the constructor.  Anyway, you get the idea.
 >> >>
 >> >> Jake
 >> >>
 >> >> At 08:34 PM 4/14/2006, you wrote:
 >> >> >
 >> >> >You shouldn't be extending Logger, but wrapping it.  When you log,
 >> >> >pass the fully qualified class name (FQCN) of your wrapper to the
 >> >> >logger methods and your line numbers will work just fine.  For
 >> >> instance...
 >> >> >
 >> >> >public class LoggerX implements Log {
 >> >> >     /*
 >> >> >      * Constant for name of class to use when recording caller
 >> >> >      * of log method. Appending a dot at the end is recommended
 >> >> practice.
 >> >> >      */
 >> >> >     private static final String FQCN = LoggerX.class.getName() + ".";
 >> >> >
 >> >> >     private final Logger logger;
 >> >> >
 >> >> >     public LoggerX(Logger delegate)  {
 >> >> >         logger = delegate;
 >> >> >     }
 >> >> >
 >> >> >     public boolean isDebugEnabled() {
 >> >> >         return logger.isDebugEnabled();
 >> >> >     }
 >> >> >
 >> >> >     public final void debug(String message) {
 >> >> >         logger.log(FQCN, Level.DEBUG, message, null);
 >> >> >     }
 >> >> >
 >> >> >     ....
 >> >> >     ....
 >> >> >     ....
 >> >> >}
 >> >> >
 >> >> >
 >> >> >Jake
 >> >> >
 >> >> >At 06:38 PM 4/14/2006, you wrote:
 >> >> > >Some code I'm writing runs in two different environments.  In one
 >> >> > >environment, I'm using log4j. In the other environment, the code
 >> calls
 >> >> that
 >> >> > >environment's logging system.  Therefore, I need to subclass log4j's
 >> >> Logger
 >> >> > >so that I can implement an interface required by the other logging
 >> >> system.
 >> >> > >I have a solution working with one big drawback.  The %F and %L
 >> >> specfied in
 >> >> > >the Appender's Conversion Pattern always return the same file and
 >> line
 >> >> > >number of my log4j subclass, not the class that originated the
 >> logging
 >> >> > >event.
 >> >> > >
 >> >> > >Is there a better solution to my inheritance dilemma? Or is there
 >> some
 >> >> way
 >> >> > >to pass log4j the file and line number arguments?
 >> >> > >
 >> >> > >Thanks!
 >> >> > >
 >> >> > >/* The Log interface is specified by the non-log4j
 >> >> environment.  The methods
 >> >> > >have the same name as log4j. */
 >> >> > >public class LoggerX extends Logger implements Log {
 >> >> > >    /**
 >> >> > >     * @param arg0
 >> >> > >     */
 >> >> > >    public LoggerX( String arg0 ) {
 >> >> > >        super( arg0 );
 >> >> > >        parent = super.getLogger( arg0 );
 >> >> > >    }
 >> >> > >
 >> >> > >    static int       logEnvironment = 0;
 >> >> > >
 >> >> > >    final static int ENVIRONMENT_1            = 0;
 >> >> > >
 >> >> > >    final static int ENVIRONMENT_2       = 1;
 >> >> > >
 >> >> > >    // the log4j logger returned by super.getLogger
 >> >> > >    Logger           parent         = null;
 >> >> > >
 >> >> > >    public  static LoggerX getLoggerForEnv( String arg0 ) {
 >> >> > >        switch ( logEnvironment ) {
 >> >> > >            case ENVIRONMENT_1 :
 >> >> > >                return ( LoggerX ) OtherEnvironment.getLogger( );
 >> >> > >
 >> >> > >            case ENVIRONMENT_2 :
 >> >> > >                System.out.println( "creating new ENVIRONMENT_2
 >> logger"
 >> >> );
 >> >> > >                return new LoggerX( arg0 );
 >> >> > >
 >> >> > >            default :
 >> >> > >                System.out.println( "************ UNKNOWN LOGGER
 >> TYPE:
 >> >> " +
 >> >> > >logEnvironment + " *************" );
 >> >> > >        }
 >> >> > >        return null;
 >> >> > >    }
 >> >> > >
 >> >> > >   /* this call produces the same file and line number regardless of
 >> >> the
 >> >> > >caller.  I know why, but I don't have a solution.  */
 >> >> > >    public boolean info(String arg0) {
 >> >> > >        parent.info( arg0);
 >> >> > >    }
 >> >> > >
 >> >> > >   public static void setEnvironmentTo1() {
 >> >> > >        logEnvironment = ENVIRONMENT_1;
 >> >> > >    }
 >> >> > >
 >> >> > >    public static void setEnvironmentTo2() {
 >> >> > >        logEnvironment = ENVIRONMENT_2;
 >> >> > >    }
 >> >> > >}
 >> >> >
 >> >> >
 >> >> >---------------------------------------------------------------------
 >> >> >To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
 >> >> >For additional commands, e-mail: log4j-user-help@logging.apache.org
 >> >> >
 >> >> >
 >> >> >
 >> >>
 >> >>
 >> >> ---------------------------------------------------------------------
 >> >> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
 >> >> For additional commands, e-mail: log4j-user-help@logging.apache.org
 >> >>
 >> >>
 >>
 >>
 >> ---------------------------------------------------------------------
 >> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
 >> For additional commands, e-mail: log4j-user-help@logging.apache.org
 >>
 >>


---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Re: inheritance dilemma

Posted by Jeff Drew <je...@gmail.com>.
Thanks Jake,

It makes sense to me.  I just want to confirm that I'm creating an instance
of LoggerX for each FQCN, just as I usually call Logger.getLogger to use
log4j directly. correct?

Thanks again,

Jeff

On 4/15/06, Jacob Kjome <ho...@visi.com> wrote:
>
>
> No,
>
> FQCN only comes into play when you log something.  It should be...
>
> public LoggerX(String loggerName) {
>      logger = Logger.getLogger(loggerName);
> }
>
> Then, as in the example I provided, you would do this in the debug()
> method...
>
> public final void debug(String message, Throwable th) {
>       logger.log(FQCN, Level.DEBUG, message, th);
> }
>
> You will need to create methods for each level you want to log to,
> equivalent to the debug() example I have provided.
>
> Make sense?
>
> Jake
>
> At 07:39 AM 4/15/2006, you wrote:
> >Jake,
> >So the constructor should read:
> >
> >
> >    public LoggerX(String FQCN)  {
> >        logger = Logger.getLogger(FQCN);
> >    }
> >
> >correct?
> >
> >Thanks
> >
> >Jeff
> >
> >On 4/14/06, Jacob Kjome <ho...@visi.com> wrote:
> >>
> >>
> >> Whoops, I didn't mean to expose the Logger in the constructor.  I
> >> meant that to be a Class or a String and then create the logger
> >> inside the constructor.  Anyway, you get the idea.
> >>
> >> Jake
> >>
> >> At 08:34 PM 4/14/2006, you wrote:
> >> >
> >> >You shouldn't be extending Logger, but wrapping it.  When you log,
> >> >pass the fully qualified class name (FQCN) of your wrapper to the
> >> >logger methods and your line numbers will work just fine.  For
> >> instance...
> >> >
> >> >public class LoggerX implements Log {
> >> >     /*
> >> >      * Constant for name of class to use when recording caller
> >> >      * of log method. Appending a dot at the end is recommended
> >> practice.
> >> >      */
> >> >     private static final String FQCN = LoggerX.class.getName() + ".";
> >> >
> >> >     private final Logger logger;
> >> >
> >> >     public LoggerX(Logger delegate)  {
> >> >         logger = delegate;
> >> >     }
> >> >
> >> >     public boolean isDebugEnabled() {
> >> >         return logger.isDebugEnabled();
> >> >     }
> >> >
> >> >     public final void debug(String message) {
> >> >         logger.log(FQCN, Level.DEBUG, message, null);
> >> >     }
> >> >
> >> >     ....
> >> >     ....
> >> >     ....
> >> >}
> >> >
> >> >
> >> >Jake
> >> >
> >> >At 06:38 PM 4/14/2006, you wrote:
> >> > >Some code I'm writing runs in two different environments.  In one
> >> > >environment, I'm using log4j. In the other environment, the code
> calls
> >> that
> >> > >environment's logging system.  Therefore, I need to subclass log4j's
> >> Logger
> >> > >so that I can implement an interface required by the other logging
> >> system.
> >> > >I have a solution working with one big drawback.  The %F and %L
> >> specfied in
> >> > >the Appender's Conversion Pattern always return the same file and
> line
> >> > >number of my log4j subclass, not the class that originated the
> logging
> >> > >event.
> >> > >
> >> > >Is there a better solution to my inheritance dilemma? Or is there
> some
> >> way
> >> > >to pass log4j the file and line number arguments?
> >> > >
> >> > >Thanks!
> >> > >
> >> > >/* The Log interface is specified by the non-log4j
> >> environment.  The methods
> >> > >have the same name as log4j. */
> >> > >public class LoggerX extends Logger implements Log {
> >> > >    /**
> >> > >     * @param arg0
> >> > >     */
> >> > >    public LoggerX( String arg0 ) {
> >> > >        super( arg0 );
> >> > >        parent = super.getLogger( arg0 );
> >> > >    }
> >> > >
> >> > >    static int       logEnvironment = 0;
> >> > >
> >> > >    final static int ENVIRONMENT_1            = 0;
> >> > >
> >> > >    final static int ENVIRONMENT_2       = 1;
> >> > >
> >> > >    // the log4j logger returned by super.getLogger
> >> > >    Logger           parent         = null;
> >> > >
> >> > >    public  static LoggerX getLoggerForEnv( String arg0 ) {
> >> > >        switch ( logEnvironment ) {
> >> > >            case ENVIRONMENT_1 :
> >> > >                return ( LoggerX ) OtherEnvironment.getLogger( );
> >> > >
> >> > >            case ENVIRONMENT_2 :
> >> > >                System.out.println( "creating new ENVIRONMENT_2
> logger"
> >> );
> >> > >                return new LoggerX( arg0 );
> >> > >
> >> > >            default :
> >> > >                System.out.println( "************ UNKNOWN LOGGER
> TYPE:
> >> " +
> >> > >logEnvironment + " *************" );
> >> > >        }
> >> > >        return null;
> >> > >    }
> >> > >
> >> > >   /* this call produces the same file and line number regardless of
> >> the
> >> > >caller.  I know why, but I don't have a solution.  */
> >> > >    public boolean info(String arg0) {
> >> > >        parent.info( arg0);
> >> > >    }
> >> > >
> >> > >   public static void setEnvironmentTo1() {
> >> > >        logEnvironment = ENVIRONMENT_1;
> >> > >    }
> >> > >
> >> > >    public static void setEnvironmentTo2() {
> >> > >        logEnvironment = ENVIRONMENT_2;
> >> > >    }
> >> > >}
> >> >
> >> >
> >> >---------------------------------------------------------------------
> >> >To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> >> >For additional commands, e-mail: log4j-user-help@logging.apache.org
> >> >
> >> >
> >> >
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> >> For additional commands, e-mail: log4j-user-help@logging.apache.org
> >>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-user-help@logging.apache.org
>
>

Re: inheritance dilemma

Posted by Jacob Kjome <ho...@visi.com>.
No,

FQCN only comes into play when you log something.  It should be...

public LoggerX(String loggerName) {
     logger = Logger.getLogger(loggerName);
}

Then, as in the example I provided, you would do this in the debug() method...

public final void debug(String message, Throwable th) {
      logger.log(FQCN, Level.DEBUG, message, th);
}

You will need to create methods for each level you want to log to, 
equivalent to the debug() example I have provided.

Make sense?

Jake

At 07:39 AM 4/15/2006, you wrote:
 >Jake,
 >So the constructor should read:
 >
 >
 >    public LoggerX(String FQCN)  {
 >        logger = Logger.getLogger(FQCN);
 >    }
 >
 >correct?
 >
 >Thanks
 >
 >Jeff
 >
 >On 4/14/06, Jacob Kjome <ho...@visi.com> wrote:
 >>
 >>
 >> Whoops, I didn't mean to expose the Logger in the constructor.  I
 >> meant that to be a Class or a String and then create the logger
 >> inside the constructor.  Anyway, you get the idea.
 >>
 >> Jake
 >>
 >> At 08:34 PM 4/14/2006, you wrote:
 >> >
 >> >You shouldn't be extending Logger, but wrapping it.  When you log,
 >> >pass the fully qualified class name (FQCN) of your wrapper to the
 >> >logger methods and your line numbers will work just fine.  For
 >> instance...
 >> >
 >> >public class LoggerX implements Log {
 >> >     /*
 >> >      * Constant for name of class to use when recording caller
 >> >      * of log method. Appending a dot at the end is recommended
 >> practice.
 >> >      */
 >> >     private static final String FQCN = LoggerX.class.getName() + ".";
 >> >
 >> >     private final Logger logger;
 >> >
 >> >     public LoggerX(Logger delegate)  {
 >> >         logger = delegate;
 >> >     }
 >> >
 >> >     public boolean isDebugEnabled() {
 >> >         return logger.isDebugEnabled();
 >> >     }
 >> >
 >> >     public final void debug(String message) {
 >> >         logger.log(FQCN, Level.DEBUG, message, null);
 >> >     }
 >> >
 >> >     ....
 >> >     ....
 >> >     ....
 >> >}
 >> >
 >> >
 >> >Jake
 >> >
 >> >At 06:38 PM 4/14/2006, you wrote:
 >> > >Some code I'm writing runs in two different environments.  In one
 >> > >environment, I'm using log4j. In the other environment, the code calls
 >> that
 >> > >environment's logging system.  Therefore, I need to subclass log4j's
 >> Logger
 >> > >so that I can implement an interface required by the other logging
 >> system.
 >> > >I have a solution working with one big drawback.  The %F and %L
 >> specfied in
 >> > >the Appender's Conversion Pattern always return the same file and line
 >> > >number of my log4j subclass, not the class that originated the logging
 >> > >event.
 >> > >
 >> > >Is there a better solution to my inheritance dilemma? Or is there some
 >> way
 >> > >to pass log4j the file and line number arguments?
 >> > >
 >> > >Thanks!
 >> > >
 >> > >/* The Log interface is specified by the non-log4j
 >> environment.  The methods
 >> > >have the same name as log4j. */
 >> > >public class LoggerX extends Logger implements Log {
 >> > >    /**
 >> > >     * @param arg0
 >> > >     */
 >> > >    public LoggerX( String arg0 ) {
 >> > >        super( arg0 );
 >> > >        parent = super.getLogger( arg0 );
 >> > >    }
 >> > >
 >> > >    static int       logEnvironment = 0;
 >> > >
 >> > >    final static int ENVIRONMENT_1            = 0;
 >> > >
 >> > >    final static int ENVIRONMENT_2       = 1;
 >> > >
 >> > >    // the log4j logger returned by super.getLogger
 >> > >    Logger           parent         = null;
 >> > >
 >> > >    public  static LoggerX getLoggerForEnv( String arg0 ) {
 >> > >        switch ( logEnvironment ) {
 >> > >            case ENVIRONMENT_1 :
 >> > >                return ( LoggerX ) OtherEnvironment.getLogger( );
 >> > >
 >> > >            case ENVIRONMENT_2 :
 >> > >                System.out.println( "creating new ENVIRONMENT_2 logger"
 >> );
 >> > >                return new LoggerX( arg0 );
 >> > >
 >> > >            default :
 >> > >                System.out.println( "************ UNKNOWN LOGGER TYPE:
 >> " +
 >> > >logEnvironment + " *************" );
 >> > >        }
 >> > >        return null;
 >> > >    }
 >> > >
 >> > >   /* this call produces the same file and line number regardless of
 >> the
 >> > >caller.  I know why, but I don't have a solution.  */
 >> > >    public boolean info(String arg0) {
 >> > >        parent.info( arg0);
 >> > >    }
 >> > >
 >> > >   public static void setEnvironmentTo1() {
 >> > >        logEnvironment = ENVIRONMENT_1;
 >> > >    }
 >> > >
 >> > >    public static void setEnvironmentTo2() {
 >> > >        logEnvironment = ENVIRONMENT_2;
 >> > >    }
 >> > >}
 >> >
 >> >
 >> >---------------------------------------------------------------------
 >> >To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
 >> >For additional commands, e-mail: log4j-user-help@logging.apache.org
 >> >
 >> >
 >> >
 >>
 >>
 >> ---------------------------------------------------------------------
 >> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
 >> For additional commands, e-mail: log4j-user-help@logging.apache.org
 >>
 >>


---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Re: inheritance dilemma

Posted by Jeff Drew <je...@gmail.com>.
Jake,
So the constructor should read:


    public LoggerX(String FQCN)  {
        logger = Logger.getLogger(FQCN);
    }

correct?

Thanks

Jeff

On 4/14/06, Jacob Kjome <ho...@visi.com> wrote:
>
>
> Whoops, I didn't mean to expose the Logger in the constructor.  I
> meant that to be a Class or a String and then create the logger
> inside the constructor.  Anyway, you get the idea.
>
> Jake
>
> At 08:34 PM 4/14/2006, you wrote:
> >
> >You shouldn't be extending Logger, but wrapping it.  When you log,
> >pass the fully qualified class name (FQCN) of your wrapper to the
> >logger methods and your line numbers will work just fine.  For
> instance...
> >
> >public class LoggerX implements Log {
> >     /*
> >      * Constant for name of class to use when recording caller
> >      * of log method. Appending a dot at the end is recommended
> practice.
> >      */
> >     private static final String FQCN = LoggerX.class.getName() + ".";
> >
> >     private final Logger logger;
> >
> >     public LoggerX(Logger delegate)  {
> >         logger = delegate;
> >     }
> >
> >     public boolean isDebugEnabled() {
> >         return logger.isDebugEnabled();
> >     }
> >
> >     public final void debug(String message) {
> >         logger.log(FQCN, Level.DEBUG, message, null);
> >     }
> >
> >     ....
> >     ....
> >     ....
> >}
> >
> >
> >Jake
> >
> >At 06:38 PM 4/14/2006, you wrote:
> > >Some code I'm writing runs in two different environments.  In one
> > >environment, I'm using log4j. In the other environment, the code calls
> that
> > >environment's logging system.  Therefore, I need to subclass log4j's
> Logger
> > >so that I can implement an interface required by the other logging
> system.
> > >I have a solution working with one big drawback.  The %F and %L
> specfied in
> > >the Appender's Conversion Pattern always return the same file and line
> > >number of my log4j subclass, not the class that originated the logging
> > >event.
> > >
> > >Is there a better solution to my inheritance dilemma? Or is there some
> way
> > >to pass log4j the file and line number arguments?
> > >
> > >Thanks!
> > >
> > >/* The Log interface is specified by the non-log4j
> environment.  The methods
> > >have the same name as log4j. */
> > >public class LoggerX extends Logger implements Log {
> > >    /**
> > >     * @param arg0
> > >     */
> > >    public LoggerX( String arg0 ) {
> > >        super( arg0 );
> > >        parent = super.getLogger( arg0 );
> > >    }
> > >
> > >    static int       logEnvironment = 0;
> > >
> > >    final static int ENVIRONMENT_1            = 0;
> > >
> > >    final static int ENVIRONMENT_2       = 1;
> > >
> > >    // the log4j logger returned by super.getLogger
> > >    Logger           parent         = null;
> > >
> > >    public  static LoggerX getLoggerForEnv( String arg0 ) {
> > >        switch ( logEnvironment ) {
> > >            case ENVIRONMENT_1 :
> > >                return ( LoggerX ) OtherEnvironment.getLogger( );
> > >
> > >            case ENVIRONMENT_2 :
> > >                System.out.println( "creating new ENVIRONMENT_2 logger"
> );
> > >                return new LoggerX( arg0 );
> > >
> > >            default :
> > >                System.out.println( "************ UNKNOWN LOGGER TYPE:
> " +
> > >logEnvironment + " *************" );
> > >        }
> > >        return null;
> > >    }
> > >
> > >   /* this call produces the same file and line number regardless of
> the
> > >caller.  I know why, but I don't have a solution.  */
> > >    public boolean info(String arg0) {
> > >        parent.info( arg0);
> > >    }
> > >
> > >   public static void setEnvironmentTo1() {
> > >        logEnvironment = ENVIRONMENT_1;
> > >    }
> > >
> > >    public static void setEnvironmentTo2() {
> > >        logEnvironment = ENVIRONMENT_2;
> > >    }
> > >}
> >
> >
> >---------------------------------------------------------------------
> >To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> >For additional commands, e-mail: log4j-user-help@logging.apache.org
> >
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-user-help@logging.apache.org
>
>

Re: inheritance dilemma

Posted by Jacob Kjome <ho...@visi.com>.
Whoops, I didn't mean to expose the Logger in the constructor.  I 
meant that to be a Class or a String and then create the logger 
inside the constructor.  Anyway, you get the idea.

Jake

At 08:34 PM 4/14/2006, you wrote:
 >
 >You shouldn't be extending Logger, but wrapping it.  When you log,
 >pass the fully qualified class name (FQCN) of your wrapper to the
 >logger methods and your line numbers will work just fine.  For instance...
 >
 >public class LoggerX implements Log {
 >     /*
 >      * Constant for name of class to use when recording caller
 >      * of log method. Appending a dot at the end is recommended practice.
 >      */
 >     private static final String FQCN = LoggerX.class.getName() + ".";
 >
 >     private final Logger logger;
 >
 >     public LoggerX(Logger delegate)  {
 >         logger = delegate;
 >     }
 >
 >     public boolean isDebugEnabled() {
 >         return logger.isDebugEnabled();
 >     }
 >
 >     public final void debug(String message) {
 >         logger.log(FQCN, Level.DEBUG, message, null);
 >     }
 >
 >     ....
 >     ....
 >     ....
 >}
 >
 >
 >Jake
 >
 >At 06:38 PM 4/14/2006, you wrote:
 > >Some code I'm writing runs in two different environments.  In one
 > >environment, I'm using log4j. In the other environment, the code calls that
 > >environment's logging system.  Therefore, I need to subclass log4j's Logger
 > >so that I can implement an interface required by the other logging system.
 > >I have a solution working with one big drawback.  The %F and %L specfied in
 > >the Appender's Conversion Pattern always return the same file and line
 > >number of my log4j subclass, not the class that originated the logging
 > >event.
 > >
 > >Is there a better solution to my inheritance dilemma? Or is there some way
 > >to pass log4j the file and line number arguments?
 > >
 > >Thanks!
 > >
 > >/* The Log interface is specified by the non-log4j 
environment.  The methods
 > >have the same name as log4j. */
 > >public class LoggerX extends Logger implements Log {
 > >    /**
 > >     * @param arg0
 > >     */
 > >    public LoggerX( String arg0 ) {
 > >        super( arg0 );
 > >        parent = super.getLogger( arg0 );
 > >    }
 > >
 > >    static int       logEnvironment = 0;
 > >
 > >    final static int ENVIRONMENT_1            = 0;
 > >
 > >    final static int ENVIRONMENT_2       = 1;
 > >
 > >    // the log4j logger returned by super.getLogger
 > >    Logger           parent         = null;
 > >
 > >    public  static LoggerX getLoggerForEnv( String arg0 ) {
 > >        switch ( logEnvironment ) {
 > >            case ENVIRONMENT_1 :
 > >                return ( LoggerX ) OtherEnvironment.getLogger( );
 > >
 > >            case ENVIRONMENT_2 :
 > >                System.out.println( "creating new ENVIRONMENT_2 logger" );
 > >                return new LoggerX( arg0 );
 > >
 > >            default :
 > >                System.out.println( "************ UNKNOWN LOGGER TYPE: " +
 > >logEnvironment + " *************" );
 > >        }
 > >        return null;
 > >    }
 > >
 > >   /* this call produces the same file and line number regardless of the
 > >caller.  I know why, but I don't have a solution.  */
 > >    public boolean info(String arg0) {
 > >        parent.info( arg0);
 > >    }
 > >
 > >   public static void setEnvironmentTo1() {
 > >        logEnvironment = ENVIRONMENT_1;
 > >    }
 > >
 > >    public static void setEnvironmentTo2() {
 > >        logEnvironment = ENVIRONMENT_2;
 > >    }
 > >}
 >
 >
 >---------------------------------------------------------------------
 >To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
 >For additional commands, e-mail: log4j-user-help@logging.apache.org
 >
 >
 > 


---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Re: inheritance dilemma

Posted by Jacob Kjome <ho...@visi.com>.
You shouldn't be extending Logger, but wrapping it.  When you log, 
pass the fully qualified class name (FQCN) of your wrapper to the 
logger methods and your line numbers will work just fine.  For instance...

public class LoggerX implements Log {
     /*
      * Constant for name of class to use when recording caller
      * of log method. Appending a dot at the end is recommended practice.
      */
     private static final String FQCN = LoggerX.class.getName() + ".";

     private final Logger logger;

     public LoggerX(Logger delegate)  {
         logger = delegate;
     }

     public boolean isDebugEnabled() {
         return logger.isDebugEnabled();
     }

     public final void debug(String message) {
         logger.log(FQCN, Level.DEBUG, message, null);
     }

     ....
     ....
     ....
}


Jake

At 06:38 PM 4/14/2006, you wrote:
 >Some code I'm writing runs in two different environments.  In one
 >environment, I'm using log4j. In the other environment, the code calls that
 >environment's logging system.  Therefore, I need to subclass log4j's Logger
 >so that I can implement an interface required by the other logging system.
 >I have a solution working with one big drawback.  The %F and %L specfied in
 >the Appender's Conversion Pattern always return the same file and line
 >number of my log4j subclass, not the class that originated the logging
 >event.
 >
 >Is there a better solution to my inheritance dilemma? Or is there some way
 >to pass log4j the file and line number arguments?
 >
 >Thanks!
 >
 >/* The Log interface is specified by the non-log4j environment.  The methods
 >have the same name as log4j. */
 >public class LoggerX extends Logger implements Log {
 >    /**
 >     * @param arg0
 >     */
 >    public LoggerX( String arg0 ) {
 >        super( arg0 );
 >        parent = super.getLogger( arg0 );
 >    }
 >
 >    static int       logEnvironment = 0;
 >
 >    final static int ENVIRONMENT_1            = 0;
 >
 >    final static int ENVIRONMENT_2       = 1;
 >
 >    // the log4j logger returned by super.getLogger
 >    Logger           parent         = null;
 >
 >    public  static LoggerX getLoggerForEnv( String arg0 ) {
 >        switch ( logEnvironment ) {
 >            case ENVIRONMENT_1 :
 >                return ( LoggerX ) OtherEnvironment.getLogger( );
 >
 >            case ENVIRONMENT_2 :
 >                System.out.println( "creating new ENVIRONMENT_2 logger" );
 >                return new LoggerX( arg0 );
 >
 >            default :
 >                System.out.println( "************ UNKNOWN LOGGER TYPE: " +
 >logEnvironment + " *************" );
 >        }
 >        return null;
 >    }
 >
 >   /* this call produces the same file and line number regardless of the
 >caller.  I know why, but I don't have a solution.  */
 >    public boolean info(String arg0) {
 >        parent.info( arg0);
 >    }
 >
 >   public static void setEnvironmentTo1() {
 >        logEnvironment = ENVIRONMENT_1;
 >    }
 >
 >    public static void setEnvironmentTo2() {
 >        logEnvironment = ENVIRONMENT_2;
 >    }
 >}


---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Re: inheritance dilemma

Posted by James Stauffer <st...@gmail.com>.
Other options include using commons logging to allow switching the
implementation of making a log4j appender that passes to your other
logging system.

On 4/14/06, Jeff Drew <je...@gmail.com> wrote:
> Some code I'm writing runs in two different environments.  In one
> environment, I'm using log4j. In the other environment, the code calls that
> environment's logging system.  Therefore, I need to subclass log4j's Logger
> so that I can implement an interface required by the other logging system.
> I have a solution working with one big drawback.  The %F and %L specfied in
> the Appender's Conversion Pattern always return the same file and line
> number of my log4j subclass, not the class that originated the logging
> event.
>
> Is there a better solution to my inheritance dilemma? Or is there some way
> to pass log4j the file and line number arguments?
>
> Thanks!
>
> /* The Log interface is specified by the non-log4j environment.  The methods
> have the same name as log4j. */
> public class LoggerX extends Logger implements Log {
>     /**
>      * @param arg0
>      */
>     public LoggerX( String arg0 ) {
>         super( arg0 );
>         parent = super.getLogger( arg0 );
>     }
>
>     static int       logEnvironment = 0;
>
>     final static int ENVIRONMENT_1            = 0;
>
>     final static int ENVIRONMENT_2       = 1;
>
>     // the log4j logger returned by super.getLogger
>     Logger           parent         = null;
>
>     public  static LoggerX getLoggerForEnv( String arg0 ) {
>         switch ( logEnvironment ) {
>             case ENVIRONMENT_1 :
>                 return ( LoggerX ) OtherEnvironment.getLogger( );
>
>             case ENVIRONMENT_2 :
>                 System.out.println( "creating new ENVIRONMENT_2 logger" );
>                 return new LoggerX( arg0 );
>
>             default :
>                 System.out.println( "************ UNKNOWN LOGGER TYPE: " +
> logEnvironment + " *************" );
>         }
>         return null;
>     }
>
>    /* this call produces the same file and line number regardless of the
> caller.  I know why, but I don't have a solution.  */
>     public boolean info(String arg0) {
>         parent.info( arg0);
>     }
>
>    public static void setEnvironmentTo1() {
>         logEnvironment = ENVIRONMENT_1;
>     }
>
>     public static void setEnvironmentTo2() {
>         logEnvironment = ENVIRONMENT_2;
>     }
> }
>
>


--
James Stauffer
Are you good? Take the test at http://www.livingwaters.com/good/

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org