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