Return-Path:
+ * Example:
+ *
+ * See comments on the root constructor
+ * for details on why constructors supplying an existing hierarchy
+ * should be used with caution.
+ *
+ *
+ * As this constructor provides a logger to be used as a fallback
+ * a subsequent
+ * As this constructor provides a logger to be used as a fallback
+ * a subsequent
+ *
+ * If the
+ * The configuration of the resulting
+ * Generally it is preferrable to
+ * DefaultLogKitManager
. It will use a new Hierarchy
.
+ * Creates a new LogKitLoggerManager
;
+ * one of the preferred constructors.
+ * Please also invoke enableLogging()
+ * to supply a fallback logger.
*/
public LogKitLoggerManager()
{
- this( new Hierarchy() );
+ this( (String)null, (Hierarchy)null, (String)null, (Logger)null, (Logger)null );
}
/**
- * Creates a new DefaultLogKitManager
with an existing Hierarchy
.
+ * Creates a new LogKitLoggerManager
;
+ * one of the preferred constructors.
+ * Please also invoke enableLogging()
+ * to supply a fallback logger.
+ *
+ * @param prefix to prepended to category name on each
+ * invocation of getLoggerForCategory()
.
*/
- public LogKitLoggerManager( final Hierarchy hierarchy )
+ public LogKitLoggerManager( final String prefix )
{
- this( null, hierarchy );
+ this( prefix, (Hierarchy)null, (String)null, (Logger)null, (Logger)null );
}
/**
- * Creates a new DefaultLogKitManager
using
- * specified logger name as root logger.
+ * Creates a new LogKitLoggerManager
;
+ * one of the preferred constructors,
+ * intended for the widest usage.
+ *
+ * Please also invoke enableLogging()
+ * to supply a fallback logger.
+ *
+ * LogKitLoggerManager l = new LogKitLoggerManager( "fortress", "system.logkit" );
+ * l.enableLogging( bootstrapLogger );
+ * l.configure( loggerManagerConfiguration );
+ *
+ *
+ * @param prefix to prepended to category name on each
+ * invocation of getLoggerForCategory()
.
+ * @param switchToCategory if this parameter is not null
+ * after start()
+ * LogKitLoggerManager
will start
+ * to log its own debug and error messages to
+ * a logger obtained via
+ * this.getLoggerForCategory( switchToCategory )
.
+ * Note that prefix will be prepended to
+ * the value of switchToCategory
also.
+ */
+ public LogKitLoggerManager( final String prefix, final String switchToCategory )
+ {
+ this( prefix, (Hierarchy)null, switchToCategory, (Logger)null, (Logger)null );
+ }
+
+ /**
+ * Creates a new LogKitLoggerManager
+ * with an existing Hierarchy
;
+ * use with caution.
+ *
+ * Please also invoke enableLogging()
+ * to supply a fallback logger.
+ * See comments on the root constructor
+ * for details on why constructors supplying an existing hierarchy
+ * should be used with caution.
+ *
+ * @param prefix to prepended to category name on each
+ * invocation of getLoggerForCategory()
.
+ * @param switchToCategory if this parameter is not null
+ * after start()
+ * LogKitLoggerManager
will start
+ * to log its own debug and error messages to
+ * a logger obtained via
+ * this.getLoggerForCategory( switchToCategory )
.
+ * Note that prefix will be prepended to
+ * the value of switchToCategory
also.
*/
- public LogKitLoggerManager( final String prefix )
+ public LogKitLoggerManager( final String prefix, final Hierarchy hierarchy,
+ final String switchToCategory )
{
- this( prefix, new Hierarchy() );
+ this( prefix, hierarchy, switchToCategory, (Logger)null, (Logger)null );
}
/**
- * Creates a new DefaultLogKitManager
with an existing Hierarchy
using
- * specified logger name as root logger.
+ * Creates a new LogKitLoggerManager
+ * with an existing Hierarchy
;
+ * use with caution.
+ *
+ * Please also invoke enableLogging()
+ * to supply a fallback logger.
+ * See comments on the root constructor
+ * for details on why constructors supplying an existing hierarchy
+ * should be used with caution.
*/
- public LogKitLoggerManager( final String prefix, final Hierarchy hierarchy )
+ public LogKitLoggerManager( final Hierarchy hierarchy )
{
- this( prefix, hierarchy,
- new LogKitLogger( hierarchy.getRootLogger() ) );
+ this( (String)null, hierarchy, (String)null, (Logger)null, (Logger)null );
}
/**
- * Creates a new DefaultLogKitManager
with an existing Hierarchy
using
- * specified logger name as root logger.
+ * Creates a new LogKitLoggerManager
+ * with an existing Hierarchy
;
+ * use with caution.
+ *
+ * Please also invoke enableLogging()
+ * to supply a fallback logger.
+ * See comments on the root constructor
+ * for details on why constructors supplying an existing hierarchy
+ * should be used with caution.
+ *
+ * @param prefix to prepended to category name on each
+ * invocation of getLoggerForCategory()
.
*/
- public LogKitLoggerManager( final String prefix, final Hierarchy hierarchy,
- final Logger defaultLogger )
+ public LogKitLoggerManager( final String prefix, final Hierarchy hierarchy )
{
- this( prefix, hierarchy, defaultLogger, defaultLogger );
+ this( prefix, hierarchy, (String)null, (Logger)null, (Logger)null );
}
/**
- * Creates a new DefaultLogKitManager
with an existing Hierarchy
using
- * specified logger name as root logger.
+ * Creates a new LogKitLoggerManager
+ * with an existing Hierarchy
using
+ * specified logger name as a fallback logger and to
+ * forcibly override the root logger;
+ * compatibility constructor.
+ *
+ * The configuration for the ""
+ * category in the configuration will supply the defaults for
+ * all other categories, but getDefaultLogger()
+ * and getLoggerForCategory()
will still
+ * use logger supplied by this constructor.
+ *
+ * enableLogging()
stage is unnecessary.
+ * Moreover, it will fail.
+ *
+ * @param prefix to prepended to category name on each
+ * invocation of getLoggerForCategory()
.
+ * @param defaultOverrideAndFallback the logger used to
+ * a) forcibly
+ * override the root logger that will further be obtained from
+ * the configuration and b) as the fallback logger. Note that
+ * specifying a logger as this parameter crucially differs from
+ * supplying it via enableLogging()
. The logger
+ * supplied via enableLogging
will only be used
+ * as the fallback logger and to log messages during initialization
+ * while this constructor argument also has the described
+ * override semantics.
*/
public LogKitLoggerManager( final String prefix, final Hierarchy hierarchy,
- final Logger defaultLogger, final Logger logger )
+ final Logger defaultOverrideAndFallback )
{
- m_prefix = prefix;
- m_hierarchy = hierarchy;
- m_defaultLogger = defaultLogger;
- m_logger = logger;
+ this( prefix, hierarchy, (String)null,
+ defaultOverrideAndFallback, defaultOverrideAndFallback );
}
/**
- * Provide a logger.
+ * Creates a new LogKitLoggerManager
+ * with an existing Hierarchy
using
+ * specified loggers to forcibly override
+ * the default logger and to provide a fallback logger;
+ * compatibility constructor.
+ *
+ * See comments on the root constructor
+ * for details on why constructors supplying an existing hierarchy
+ * should be used with caution.
+ * enableLogging()
stage is unnecessary.
+ * Moreover, it will fail.
*
- * @param logger the logger
- **/
- public void enableLogging( final Logger logger )
+ * @param prefix to prepended to category name on each
+ * invocation of getLoggerForCategory()
.
+ * @param defaultLoggerOverride the logger to be used to forcibly
+ * override the root logger that will further be obtained from
+ * the configuration
+ * @param fallbackLogger the logger to as a fallback logger
+ * (passing non-null as this argument eliminates the need
+ * to invoke enableLogging()
)
+ */
+ public LogKitLoggerManager( final String prefix, final Hierarchy hierarchy,
+ final Logger defaultLoggerOverride,
+ final Logger fallbackLogger )
{
- m_logger = logger;
+ this( prefix, hierarchy, (String)null, defaultLoggerOverride, fallbackLogger );
}
/**
- * Retrieves a Logger from a category name. Usually
- * the category name refers to a configuration attribute name. If
- * this LogKitManager does not have the match the default Logger will
- * be returned and a warning is issued.
+ *
+ *
+ * Creates a new LogKitLoggerManager
;
+ * "root" constructor invoked by all other constructors.
+ * hierarchy
parameter is not null
+ * this instructs this constructor to use an existing hierarchy
+ * instead of creating a new one. This also disables removing
+ * the default log target configured by the Hierarchy()
+ * constructor (this target logs to System.out
) and
+ * installing our own ErrorHandler
for our
+ * Hierarchy
(the default ErrorHandler
+ * writes to System.err
).
+ * Hierarchy
+ * is a combination of the original configuraiton that
+ * existed when this Hierarchy
was handled to us
+ * and the configuration supplied to use via configure()
.
+ * LogTarget
s for those categories for which a
+ * configuration node has been supplied in the configuration
+ * supplied via configure()
are replaced during
+ * the configure()
process. LogTargets
+ * for those categories for which configuration nodes have
+ * not been supplied are left as they were. A special case
+ * is when a node in configuration for a category exists but
+ * it does not enlist log targets. In this case the original
+ * targets if any are left as they were.
+ *
+ *
+ *
+ * That's why it is preferrable to pass Hierarchy
be configured
+ * from top to bottom via the configurationErrorHandler
reporting
+ * errors via the fallback logger (supplied either as
+ * the fallbackLogger
to this constructor or
+ * via the enableLogging()
method) installednull
+ * for the hierarchy
parameter of this constructor
+ * or, which is easier to read but has the same effect, to
+ * invoke a constructor which does not accept a Hierarchy
+ * argument.
+ *
The defaultLoggerOverride
and fallbackLogger
+ * are a special case too. defaultLoggerOverride
+ * forcibly overrides
+ * the root logger configured via configure()
.
+ * As there is little reason to take away users's freedom to configure
+ * whatever he likes as the default logger, it is preferrable to pass
+ * null
for this parameter or better still to invoke
+ * a constructor without Logger
parameters at all.
There is nothing wrong with passing fallbackLogger
+ * via this constructor, but as this constructor is not convinient to
+ * be invoked (too many arguments, some of them likely to be null) and the
+ * {@link #LogKitLogger(java.lang.String,org.apache.log.Hierarchy,org.apache.framework.logger.Logger}
+ * constructor is broken
+ * in using its Logger
argument both as
+ * fallbackLogger
(which is okay) and as
+ * a defaultLoggerOverride
(which is probably not
+ * desired for the reasons given above) it is preferrable not to
+ * specify a logger
+ * as a constructor argument but rather supply it via
+ * enableLogging()
call, like this happens with all
+ * other normal Avalon components after all.
+ *
+ * @param prefix to prepended to category name on each
+ * invocation of getLoggerForCategory()
.
+ * @param switchToCategory if this parameter is not null
+ * after start()
+ * LogKitLoggerManager
will start
+ * to log its own debug and error messages to
+ * a logger obtained via
+ * this.getLoggerForCategory( switchToCategory )
.
+ * Note that prefix will be prepended to
+ * the value of switchToCategory
also.
+ * @param defaultLoggerOverride the logger to be used to
+ * forcibly override
+ * the root logger that would further be obtained from
+ * the configuration
+ * @param fallbackLogger the logger to as a fallback logger
+ * (passing non-null as this argument eliminates the need
+ * to invoke enableLogging()
)
*/
- public final Logger getLoggerForCategory( final String categoryName )
+ public LogKitLoggerManager( final String prefix, final Hierarchy hierarchy,
+ final String switchToCategory,
+ final Logger defaultLoggerOverride,
+ final Logger fallbackLogger )
{
- final String fullCategoryName = getFullCategoryName( m_prefix, categoryName );
-
- final Logger logger = (Logger)m_loggers.get( fullCategoryName );
+ super( prefix, switchToCategory, defaultLoggerOverride );
+ m_prefix = prefix;
- if( null != logger )
+ if ( hierarchy == null )
{
- if( m_logger.isDebugEnabled() )
- {
- m_logger.debug( "Logger for category " + fullCategoryName + " returned" );
- }
- return logger;
+ m_hierarchy = new Hierarchy();
+ m_hierarchy.getRootLogger().unsetLogTargets( true );
+ m_errorHandler = new OurErrorHandler( getLogger() );
+ m_hierarchy.setErrorHandler( m_errorHandler );
}
-
- if( m_logger.isDebugEnabled() )
+ else
{
- m_logger.debug( "Logger for category " + fullCategoryName + " not defined in "
- + "configuration. New Logger created and returned" );
+ m_hierarchy = hierarchy;
}
- return new LogKitLogger( m_hierarchy.getLoggerFor( fullCategoryName ) );
- }
-
- public final Logger getDefaultLogger()
- {
- return m_defaultLogger;
+ if ( fallbackLogger != null )
+ {
+ this.enableLogging( fallbackLogger );
+ }
}
/**
@@ -223,6 +416,16 @@
}
/**
+ * Actually create a logger for the given category.
+ * The result will be cached by
+ * AbstractLoggerManager.getLoggerForCategory()
.
+ */
+ protected Logger doGetLoggerForCategory( final String fullCategoryName )
+ {
+ return new LogKitLogger( m_hierarchy.getLoggerFor( fullCategoryName ) );
+ }
+
+ /**
* Reads a configuration object and creates the category mapping.
*
* @param configuration The configuration object.
@@ -242,7 +445,13 @@
setupLoggers( targetManager,
m_prefix,
category,
+ true,
categories.getAttributeAsBoolean( "additive", false ) );
+
+ /**
+ * This is the last configuration stage, if we to initialize() or start()
+ * we would call it from that method.
+ */
}
/**
@@ -256,7 +465,7 @@
{
final DefaultLogTargetFactoryManager targetFactoryManager = new DefaultLogTargetFactoryManager();
- ContainerUtil.enableLogging( targetFactoryManager, m_logger );
+ ContainerUtil.enableLogging( targetFactoryManager, getLogger() );
try
{
@@ -284,7 +493,7 @@
{
final DefaultLogTargetManager targetManager = new DefaultLogTargetManager();
- ContainerUtil.enableLogging( targetManager, m_logger );
+ ContainerUtil.enableLogging( targetManager, getLogger() );
if( targetManager instanceof LogTargetFactoryManageable )
{
@@ -297,50 +506,21 @@
}
/**
- * Generates a full category name given a prefix and category. Either may be
- * null.
- *
- * @param prefix Prefix or parent category.
- * @param category Child category name.
- */
- private final String getFullCategoryName( String prefix, String category )
- {
- if( ( null == prefix ) || ( prefix.length() == 0 ) )
- {
- if( category == null )
- {
- return "";
- }
- else
- {
- return category;
- }
- }
- else
- {
- if( ( null == category ) || ( category.length() == 0 ) )
- {
- return prefix;
- }
- else
- {
- return prefix + org.apache.log.Logger.CATEGORY_SEPARATOR + category;
- }
- }
- }
-
- /**
* Setup Loggers
*
* @param categories [] The array object of configurations for categories.
+ * @param root shows if we're processing the root of the configuration
* @throws ConfigurationException if the configuration is malformed
*/
private final void setupLoggers( final LogTargetManager targetManager,
final String parentCategory,
final Configuration[] categories,
+ boolean root,
final boolean defaultAdditive )
throws ConfigurationException
{
+ boolean rootLoggerAlive = false;
+
for( int i = 0; i < categories.length; i++ )
{
final String category = categories[ i ].getAttribute( "name" );
@@ -360,19 +540,20 @@
}
}
- if( "".equals( category ) && logTargets.length > 0 )
+ if( root && "".equals( category ) && logTargets.length > 0 )
{
m_hierarchy.setDefaultPriority( Priority.getPriorityForName( loglevel ) );
m_hierarchy.setDefaultLogTargets( logTargets );
+ rootLoggerAlive = true;
}
final String fullCategory = getFullCategoryName( parentCategory, category );
final org.apache.log.Logger logger = m_hierarchy.getLoggerFor( fullCategory );
m_loggers.put( fullCategory, new LogKitLogger( logger ) );
- if( m_logger.isDebugEnabled() )
+ if( getLogger().isDebugEnabled() )
{
- m_logger.debug( "added logger for category " + fullCategory );
+ getLogger().debug( "added logger for category " + fullCategory );
}
logger.setPriority( Priority.getPriorityForName( loglevel ) );
logger.setLogTargets( logTargets );
@@ -381,9 +562,16 @@
final Configuration[] subCategories = categories[ i ].getChildren( "category" );
if( null != subCategories )
{
- setupLoggers( targetManager, fullCategory, subCategories, defaultAdditive );
+ setupLoggers( targetManager, fullCategory, subCategories, false, defaultAdditive );
}
}
+
+ if ( root && !rootLoggerAlive )
+ {
+ final String message = "No log targets configured for the root logger.";
+
+ throw new ConfigurationException( message );
+ }
}
public void dispose()
@@ -397,6 +585,70 @@
( (Closeable)target ).close();
}
+ }
+ }
+
+ private static class OurErrorHandler implements ErrorHandler
+ {
+ /**
+ * This will be initialized to an instance of LoggerSwitch.SwitchingLogger;
+ * that is really reliable.
+ */
+ private Logger m_reliableLogger;
+ private boolean m_wasError = false;
+ /**
+ * Access to this variable is not synchronized. Justification: it is only
+ * intended to be accessed from postConfigure when only one thread
+ * is assumed to be using the whole LogKitLoggerManager.
+ */
+ public boolean getWasError() { return m_wasError; }
+
+ OurErrorHandler( final Logger reliableLogger )
+ {
+ if ( reliableLogger == null )
+ {
+ throw new NullPointerException( "reliableLogger" );
+ }
+ m_reliableLogger = reliableLogger;
+ }
+
+ public void error( final String message, final Throwable throwable, final LogEvent event )
+ {
+ // let them know if they are interested
+ m_wasError = true;
+ // let them know we're not OK
+ m_reliableLogger.fatalError( message, throwable );
+
+ // transmit the original error
+ final Priority p = event.getPriority();
+ final String nestedMessage = "nested log event: " + event.getMessage();
+
+ if ( p == Priority.DEBUG )
+ {
+ m_reliableLogger.debug( nestedMessage, event.getThrowable() );
+ }
+ else if ( p == Priority.INFO )
+ {
+ m_reliableLogger.info( nestedMessage, event.getThrowable() );
+ }
+ else if ( p == Priority.WARN )
+ {
+ m_reliableLogger.warn( nestedMessage, event.getThrowable() );
+ }
+ else if ( p == Priority.ERROR )
+ {
+ m_reliableLogger.error( nestedMessage, event.getThrowable() );
+ }
+ else if ( p == Priority.FATAL_ERROR)
+ {
+ m_reliableLogger.fatalError( nestedMessage, event.getThrowable() );
+ }
+ else
+ {
+ /** This just plainly can't happen :-)*/
+ m_reliableLogger.error( "unrecognized priority " + nestedMessage,
+ event.getThrowable() );
+ }
}
}
}
1.16 +69 -60 avalon-excalibur/logger/src/java/org/apache/avalon/excalibur/logger/Log4JLoggerManager.java
Index: Log4JLoggerManager.java
===================================================================
RCS file: /home/cvs/avalon-excalibur/logger/src/java/org/apache/avalon/excalibur/logger/Log4JLoggerManager.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- Log4JLoggerManager.java 27 May 2003 07:30:27 -0000 1.15
+++ Log4JLoggerManager.java 10 Jun 2003 08:29:37 -0000 1.16
@@ -63,26 +63,15 @@
* leaves that as an excercise for Log4J's construction.
*
* @author Berin Loritsch
+ * @author Anton Tagunov
* @version CVS $Revision$ $Date$
* @since 4.1
*/
-public class Log4JLoggerManager
+public class Log4JLoggerManager extends AbstractLoggerManager
implements LoggerManager, LogEnabled
{
- /** Map for name to logger mapping */
- private final Map m_loggers = new HashMap();
-
- /** The root logger to configure */
- //private String m_prefix;
-
/** The hierarchy private to Log4JManager */
- private LoggerRepository m_hierarchy;
-
- /** The default logger used for this system */
- private final Logger m_defaultLogger;
-
- /** The logger used to log output from the logger manager. */
- private Logger m_logger;
+ private final LoggerRepository m_hierarchy;
/**
* Creates a new DefaultLog4JManager
. It will use a new Hierarchy
.
@@ -97,7 +86,7 @@
*/
public Log4JLoggerManager( final LoggerRepository hierarchy )
{
- this( null, hierarchy );
+ this( (String) null, hierarchy, (String) null, (Logger) null, (Logger) null );
}
/**
@@ -106,7 +95,7 @@
*/
public Log4JLoggerManager( final String prefix )
{
- this( prefix, LogManager.getLoggerRepository() );
+ this( prefix, (LoggerRepository) null, (String) null, (Logger) null, (Logger) null );
}
/**
@@ -116,8 +105,16 @@
public Log4JLoggerManager( final String prefix,
final LoggerRepository hierarchy )
{
- this( prefix, hierarchy,
- new Log4JLogger( hierarchy.getRootLogger() ) );
+ this( prefix, hierarchy, (String) null, (Logger) null, (Logger) null );
+ }
+
+ /**
+ * Creates a new DefaultLog4JManager
using
+ * specified logger name as root logger.
+ */
+ public Log4JLoggerManager( final String prefix, final String switchToCategory )
+ {
+ this( prefix, (LoggerRepository) null, switchToCategory, (Logger) null, (Logger) null );
}
/**
@@ -126,9 +123,9 @@
*/
public Log4JLoggerManager( final String prefix,
final LoggerRepository hierarchy,
- final Logger defaultLogger )
+ final String switchToCategory )
{
- this( prefix, hierarchy, defaultLogger, defaultLogger );
+ this( prefix, hierarchy, switchToCategory, (Logger) null, (Logger) null );
}
/**
@@ -137,63 +134,75 @@
*/
public Log4JLoggerManager( final String prefix,
final LoggerRepository hierarchy,
- final Logger defaultLogger,
- final Logger logger )
+ final Logger defaultLogger )
{
- //m_prefix = prefix;
- m_hierarchy = hierarchy;
- m_defaultLogger = defaultLogger;
- m_logger = logger;
+ this( prefix, hierarchy, (String) null, defaultLogger, defaultLogger );
}
/**
- * Provide a logger.
- *
- * @param logger the logger
- **/
- public void enableLogging( final Logger logger )
+ * Creates a new DefaultLog4JManager
with an existing Hierarchy
using
+ * specified logger name as root logger.
+ */
+ public Log4JLoggerManager( final String prefix,
+ final LoggerRepository hierarchy,
+ final Logger defaultLogger,
+ final Logger logger )
{
- m_logger = logger;
+ this( prefix, hierarchy, (String) null, defaultLogger, logger );
}
/**
- * Retrieves a Logger from a category name. Usually
- * the category name refers to a configuration attribute name. If
- * this Log4JManager does not have the match the default Logger will
- * be returned and a warning is issued.
- *
- * @param categoryName The category name of a configured Logger.
- * @return the Logger.
+ * Creates a new DefaultLog4JManager
.
+ * @param prefix to prepend to every category name on
+ * getLoggerForCategory()
+ * @param hierarchy a Log4J LoggerRepository to run with
+ * @param switchToCategory if this parameter is not null
+ * after start()
+ * LogKitLoggerManager
will start
+ * to log its own debug and error messages to
+ * a logger obtained via
+ * this.getLoggerForCategory( switchToCategory )
.
+ * Note that prefix will be prepended to
+ * the value of switchToCategory
also.
+ * @param defaultLogger the logger to override the default
+ * logger configured by Log4J; probably should be
+ * null to allow users set up whatever logger they
+ * like as the root logger via Log4J configuration
+ * @param logger the logger to log our own initialization
+ * messages (currently we have none) and to log
+ * errors (currently this functionality is not used
+ * either)
*/
- public final Logger getLoggerForCategory( final String categoryName )
+ public Log4JLoggerManager( final String prefix,
+ final LoggerRepository hierarchy,
+ final String switchToCategory,
+ final Logger defaultLogger,
+ final Logger logger )
{
- Logger logger = (Logger)m_loggers.get( categoryName );
+ super( prefix, switchToCategory, defaultLogger );
- if( null != logger )
+ if ( hierarchy == null )
{
- if( m_logger.isDebugEnabled() )
- {
- final String message =
- "Logger for category " + categoryName + " returned";
- m_logger.debug( message );
- }
- return logger;
+ // is this an analog of new Hierarchy() or an
+ // analog of Hierarchy.getDefaultHierarchy()?
+ // we should have an analog of new Hierarchy() here
+ // I guess - Anton Tagunov
+ m_hierarchy = LogManager.getLoggerRepository();
}
-
- if( m_logger.isDebugEnabled() )
+ else
{
- final String message = "Logger for category " + categoryName +
- " not defined in configuration. New Logger created and returned";
- m_logger.debug( message );
+ m_hierarchy = hierarchy;
}
- logger = new Log4JLogger( m_hierarchy.getLogger( categoryName ) );
- m_loggers.put( categoryName, logger );
- return logger;
+ if ( logger != null )
+ {
+ this.enableLogging( logger );
+ }
}
- public final Logger getDefaultLogger()
+ /* Actaully create the Logger */
+ protected Logger doGetLoggerForCategory( final String fullCategoryName )
{
- return m_defaultLogger;
+ return new Log4JLogger( m_hierarchy.getLogger( fullCategoryName ) );
}
}
1.5 +23 -1 avalon-excalibur/logger/src/java/org/apache/avalon/excalibur/logger/Log4JConfLoggerManager.java
Index: Log4JConfLoggerManager.java
===================================================================
RCS file: /home/cvs/avalon-excalibur/logger/src/java/org/apache/avalon/excalibur/logger/Log4JConfLoggerManager.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Log4JConfLoggerManager.java 27 May 2003 07:30:27 -0000 1.4
+++ Log4JConfLoggerManager.java 10 Jun 2003 08:29:37 -0000 1.5
@@ -70,6 +70,28 @@
extends Log4JLoggerManager
implements Configurable
{
+ /**
+ * Work around a weird compilation problem. Can not call
+ * the constructor from fortress/ContextManager, get a
+ * file org\apache\log4j\spi\LoggerRepository.class not found
+ * new Log4JConfLoggerManager( lmDefaultLoggerName, lmLoggerName );
+ */
+
+ public static Log4JConfLoggerManager newInstance( final String prefix,
+ final String switchToCategory )
+ {
+ return new Log4JConfLoggerManager( prefix, switchToCategory );
+ }
+
+ public Log4JConfLoggerManager( final String prefix, final String switchToCategory )
+ {
+ super( prefix, switchToCategory );
+ }
+
+ public Log4JConfLoggerManager()
+ {
+ }
+
public void configure( final Configuration configuration )
throws ConfigurationException
{
1.1 avalon-excalibur/logger/src/java/org/apache/avalon/excalibur/logger/AbstractLoggerManager.java
Index: AbstractLoggerManager.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
must not be used to endorse or promote products derived from this software
without prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation. For more information on the
Apache Software Foundation, please see getLogger()
and live with it.
* The Logger
supplied via enableLogging
* will be used both as the "initial" and as the "fallback" logger.
*
start()
the messages logger via
* getLogger().xxx()
will go to this loggerstart
* a recursive invocation of getLogger().xxx()
will be detected
* the message will be logged via the initial logger as a fallback.start()
.
*/
private String m_switchTo;
/** safeguards against double enableLogging()
invocation. */
private boolean m_enableLoggingInvoked = false;
/** safeguards against double start()
invocation. */
private boolean m_startInvoked = false;
/**
* The logger used to be returned from getDefaultLogger()
* and getLoggerForCategory("")
,
* if one has been forcibly set via a constructor.
*/
final private Logger m_defaultLoggerOverride;
/**
* Derived LoggerManager implementations should obtain
* a logger to log their own messages via this call.
* It is also safe to log messages about logging failures
* via this logger as it safeguards internally gainst
* recursion.
*/
protected Logger getLogger()
{
return m_logger;
}
/**
* Initializes AbstractLoggerManager.
* @param prefix the prefix to prepended to the category name
* on each invocation of getLoggerForCategory before
* passing the category name on to the underlying logging
* system (currently LogKit or Log4J).
* @param switchTo fuel for the start()
method;
* if null start()
will do nothing;
* if empty start()
will switch to
* getLoggerForCategory("")
.
*/
public AbstractLoggerManager( final String prefix, final String switchTo,
Logger defaultLoggerOverride )
{
m_prefix = prefix;
m_switchTo = switchTo;
m_switch = new LoggerSwitch( null, null );
m_logger = m_switch.get();
m_defaultLoggerOverride = defaultLoggerOverride;
}
/**
* Accept the logger we shall use as the initial and the fallback logger.
*/
public void enableLogging( final Logger fallbackLogger )
{
if ( m_enableLoggingInvoked )
{
throw new IllegalStateException( "enableLogging() already called" );
}
m_switch.setFallback( fallbackLogger );
m_enableLoggingInvoked = true;
}
/**
* Get a logger from ourselves and pass it to m_switch
.
*/
public void start()
{
if ( m_startInvoked )
{
throw new IllegalStateException( "start() already invoked" );
}
if ( m_switchTo != null )
{
if ( m_logger.isDebugEnabled() )
{
final String message = "LogKitLoggerManager: switching logging to " +
"this.getLoggerForCategory('" +
getFullCategoryName( m_prefix, m_switchTo) + "').";
m_logger.debug( message );
}
final Logger ourOwn = this.getLoggerForCategory( m_switchTo );
if ( ourOwn == null )
{
throw new NullPointerException( "ourOwn" );
}
m_switch.setPreferred( ourOwn );
if ( m_logger.isDebugEnabled() )
{
final String message = "LogKitLoggerManager: have switched logging to " +
"this.getLoggerForCategory('" +
getFullCategoryName( m_prefix, m_switchTo) + "').";
m_logger.debug( message );
}
}
else
{
if ( m_logger.isDebugEnabled() )
{
final String message = "LogKitLoggerManager: m_switchTo is null, " +
"no switch of our own logging.";
m_logger.debug( message );
}
}
m_startInvoked = true;
}
/** Startable.stop() empty implementation. */
public void stop(){}
/**
* Generates a full category name given a prefix and category. Either may be
* null.
*
* @param prefix Prefix or parent category.
* @param category Child category name.
*/
protected final String getFullCategoryName( String prefix, String category )
{
if( ( null == prefix ) || ( prefix.length() == 0 ) )
{
if( category == null )
{
return "";
}
else
{
return category;
}
}
else
{
if( ( null == category ) || ( category.length() == 0 ) )
{
return prefix;
}
else
{
return prefix + org.apache.log.Logger.CATEGORY_SEPARATOR + category;
}
}
}
/**
* Retruns the logger for the ""
category.
*/
public final Logger getDefaultLogger()
{
return getLoggerForCategory( null );
}
/**
* Actually create a logger wrapping underlying logger
* backed implementation for a give category. Bypasses the caching.
* Derived LoggerManager implementations should provide an implementation
* of this method.
*/
protected abstract Logger doGetLoggerForCategory( final String fullCategoryName );
/**
* Retrieves a Logger from a category name. Usually
* the category name refers to a configuration attribute name. If
* this LogKitManager does not have the match the default Logger will
* be returned and a warning is issued.
*/
public final Logger getLoggerForCategory( final String categoryName )
{
if ( m_defaultLoggerOverride != null &&
( categoryName == null || categoryName.length() == 0 ) )
{
return m_defaultLoggerOverride;
}
final String fullCategoryName = getFullCategoryName( m_prefix, categoryName );
final Logger logger;
final Logger newLogger;
synchronized( m_loggers )
{
logger = (Logger)m_loggers.get( fullCategoryName );
if ( logger == null )
{
newLogger = doGetLoggerForCategory( fullCategoryName );
m_loggers.put( fullCategoryName, newLogger );
}
else
{
/* Let's have no "variable might not have been initialized". */
newLogger = null;
}
}
if( null != logger )
{
if( m_logger.isDebugEnabled() )
{
m_logger.debug( "Logger for category " + fullCategoryName + " returned" );
}
return logger;
}
if( m_logger.isDebugEnabled() )
{
m_logger.debug( "Logger for category " + fullCategoryName + " not defined in "
+ "configuration. New Logger created and returned" );
}
return newLogger;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org