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
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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: inheritance dilemma
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 <[EMAIL PROTECTED]> 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: inheritance dilemma
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: [EMAIL PROTECTED] >For additional commands, e-mail: [EMAIL PROTECTED] > > > - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]