2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 // Contibutors: Alex Blewitt <Alex.Blewitt@ioshq.com>
19 // Markus Oestreicher <oes@zurich.ibm.com>
20 // Frank Hoering <fhr@zurich.ibm.com>
21 // Nelson Minar <nelson@media.mit.edu>
22 // Jim Cakalic <jim_cakalic@na.biomerieux.com>
23 // Avy Sharell <asharell@club-internet.fr>
24 // Ciaran Treanor <ciaran@xelector.com>
25 // Jeff Turner <jeff@socialchange.net.au>
26 // Michael Horwitz <MHorwitz@siemens.co.za>
27 // Calvin Chan <calvin.chan@hic.gov.au>
28 // Aaron Greenhouse <aarong@cs.cmu.edu>
29 // Beat Meier <bmeier@infovia.com.ar>
30 // Colin Sampaleanu <colinml1@exis.com>
32 package org.apache.log4j;
34 import org.apache.log4j.spi.AppenderAttachable;
35 import org.apache.log4j.spi.LoggingEvent;
36 import org.apache.log4j.spi.LoggerRepository;
37 import org.apache.log4j.spi.HierarchyEventListener;
38 import org.apache.log4j.helpers.NullEnumeration;
39 import org.apache.log4j.helpers.AppenderAttachableImpl;
41 import java.util.Enumeration;
42 import java.util.MissingResourceException;
43 import java.util.ResourceBundle;
44 import java.util.Vector;
48 * <font color="#AA2222"><b>This class has been deprecated and
49 * replaced by the {@link Logger} <em>subclass</em></b></font>. It
50 * will be kept around to preserve backward compatibility until mid
53 * <p><code>Logger</code> is a subclass of Category, i.e. it extends
54 * Category. In other words, a logger <em>is</em> a category. Thus,
55 * all operations that can be performed on a category can be
56 * performed on a logger. Internally, whenever log4j is asked to
57 * produce a Category object, it will instead produce a Logger
58 * object. Log4j 1.2 will <em>never</em> produce Category objects but
59 * only <code>Logger</code> instances. In order to preserve backward
60 * compatibility, methods that previously accepted category objects
61 * still continue to accept category objects.
63 * <p>For example, the following are all legal and will work as
67 // Deprecated form:
68 Category cat = Category.getInstance("foo.bar")
70 // Preferred form for retrieving loggers:
71 Logger logger = Logger.getLogger("foo.bar")
74 * <p>The first form is deprecated and should be avoided.
76 * <p><b>There is absolutely no need for new client code to use or
77 * refer to the <code>Category</code> class.</b> Whenever possible,
78 * please avoid referring to it or using it.
80 * <p>See the <a href="../../../../manual.html">short manual</a> for an
81 * introduction on this class.
83 * See the document entitled <a href="http://www.qos.ch/logging/preparingFor13.html">preparing
84 * for log4j 1.3</a> for a more detailed discussion.
86 * @author Ceki Gülcü
87 * @author Anders Kristensen
89 public class Category implements AppenderAttachable {
92 The hierarchy where categories are attached to by default.
96 //final Hierarchy defaultHierarchy = new Hierarchy(new
97 // RootCategory(Level.DEBUG));
100 The name of this category.
102 protected String name;
105 The assigned level of this category. The
106 <code>level</code> variable need not be assigned a value in
107 which case it is inherited form the hierarchy. */
108 volatile protected Level level;
111 The parent of this category. All categories have at least one
112 ancestor which is the root category. */
113 volatile protected Category parent;
116 The fully qualified name of the Category class. See also the
118 private static final String FQCN = Category.class.getName();
120 protected ResourceBundle resourceBundle;
122 // Categories need to know what Hierarchy they are in
123 protected LoggerRepository repository;
126 AppenderAttachableImpl aai;
128 /** Additivity is set to true by default, that is children inherit
129 the appenders of their ancestors by default. If this variable is
130 set to <code>false</code> then the appenders found in the
131 ancestors of this category are not used. However, the children
132 of this category will inherit its appenders, unless the children
133 have their additivity flag set to <code>false</code> too. See
134 the user manual for more details. */
135 protected boolean additive = true;
138 This constructor created a new <code>Category</code> instance and
141 <p>It is intended to be used by sub-classes only. You should not
142 create categories directly.
144 @param name The name of the category.
147 Category(String name) {
152 Add <code>newAppender</code> to the list of appenders of this
155 <p>If <code>newAppender</code> is already in the list of
156 appenders, then it won't be added again.
160 void addAppender(Appender newAppender) {
162 aai = new AppenderAttachableImpl();
164 aai.addAppender(newAppender);
165 repository.fireAddAppenderEvent(this, newAppender);
169 If <code>assertion</code> parameter is <code>false</code>, then
170 logs <code>msg</code> as an {@link #error(Object) error} statement.
172 <p>The <code>assert</code> method has been renamed to
173 <code>assertLog</code> because <code>assert</code> is a language
174 reserved word in JDK 1.4.
177 @param msg The message to print if <code>assertion</code> is
182 void assertLog(boolean assertion, String msg) {
190 Call the appenders in the hierrachy starting at
191 <code>this</code>. If no appenders could be found, emit a
194 <p>This method calls all the appenders inherited from the
195 hierarchy circumventing any evaluation of whether to log or not
196 to log the particular log request.
198 @param event the event to log. */
200 void callAppenders(LoggingEvent event) {
203 for(Category c = this; c != null; c=c.parent) {
204 // Protected against simultaneous call to addAppender, removeAppender,...
207 writes += c.aai.appendLoopOnAppenders(event);
216 repository.emitNoAppenderWarning(this);
221 Close all attached appenders implementing the AppenderAttachable
226 void closeNestedAppenders() {
227 Enumeration enumeration = this.getAllAppenders();
228 if(enumeration != null) {
229 while(enumeration.hasMoreElements()) {
230 Appender a = (Appender) enumeration.nextElement();
231 if(a instanceof AppenderAttachable) {
239 Log a message object with the {@link Level#DEBUG DEBUG} level.
241 <p>This method first checks if this category is <code>DEBUG</code>
242 enabled by comparing the level of this category with the {@link
243 Level#DEBUG DEBUG} level. If this category is
244 <code>DEBUG</code> enabled, then it converts the message object
245 (passed as parameter) to a string by invoking the appropriate
246 {@link org.apache.log4j.or.ObjectRenderer}. It then proceeds to call all the
247 registered appenders in this category and also higher in the
248 hierarchy depending on the value of the additivity flag.
250 <p><b>WARNING</b> Note that passing a {@link Throwable} to this
251 method will print the name of the <code>Throwable</code> but no
252 stack trace. To print a stack trace use the {@link #debug(Object,
253 Throwable)} form instead.
255 @param message the message object to log. */
257 void debug(Object message) {
258 if(repository.isDisabled(Level.DEBUG_INT)) {
261 if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {
262 forcedLog(FQCN, Level.DEBUG, message, null);
268 Log a message object with the <code>DEBUG</code> level including
269 the stack trace of the {@link Throwable} <code>t</code> passed as
272 <p>See {@link #debug(Object)} form for more detailed information.
274 @param message the message object to log.
275 @param t the exception to log, including its stack trace. */
277 void debug(Object message, Throwable t) {
278 if(repository.isDisabled(Level.DEBUG_INT)) {
281 if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {
282 forcedLog(FQCN, Level.DEBUG, message, t);
287 Log a message object with the {@link Level#ERROR ERROR} Level.
289 <p>This method first checks if this category is <code>ERROR</code>
290 enabled by comparing the level of this category with {@link
291 Level#ERROR ERROR} Level. If this category is <code>ERROR</code>
292 enabled, then it converts the message object passed as parameter
293 to a string by invoking the appropriate {@link
294 org.apache.log4j.or.ObjectRenderer}. It proceeds to call all the
295 registered appenders in this category and also higher in the
296 hierarchy depending on the value of the additivity flag.
298 <p><b>WARNING</b> Note that passing a {@link Throwable} to this
299 method will print the name of the <code>Throwable</code> but no
300 stack trace. To print a stack trace use the {@link #error(Object,
301 Throwable)} form instead.
303 @param message the message object to log */
305 void error(Object message) {
306 if(repository.isDisabled(Level.ERROR_INT)) {
309 if(Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel())) {
310 forcedLog(FQCN, Level.ERROR, message, null);
315 Log a message object with the <code>ERROR</code> level including
316 the stack trace of the {@link Throwable} <code>t</code> passed as
319 <p>See {@link #error(Object)} form for more detailed information.
321 @param message the message object to log.
322 @param t the exception to log, including its stack trace. */
324 void error(Object message, Throwable t) {
325 if(repository.isDisabled(Level.ERROR_INT)) {
328 if(Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel())) {
329 forcedLog(FQCN, Level.ERROR, message, t);
336 If the named category exists (in the default hierarchy) then it
337 returns a reference to the category, otherwise it returns
340 @deprecated Please use {@link LogManager#exists} instead.
345 Logger exists(String name) {
346 return LogManager.exists(name);
350 Log a message object with the {@link Level#FATAL FATAL} Level.
352 <p>This method first checks if this category is <code>FATAL</code>
353 enabled by comparing the level of this category with {@link
354 Level#FATAL FATAL} Level. If the category is <code>FATAL</code>
355 enabled, then it converts the message object passed as parameter
356 to a string by invoking the appropriate
357 {@link org.apache.log4j.or.ObjectRenderer}. It
358 proceeds to call all the registered appenders in this category and
359 also higher in the hierarchy depending on the value of the
362 <p><b>WARNING</b> Note that passing a {@link Throwable} to this
363 method will print the name of the Throwable but no stack trace. To
364 print a stack trace use the {@link #fatal(Object, Throwable)} form
367 @param message the message object to log */
369 void fatal(Object message) {
370 if(repository.isDisabled(Level.FATAL_INT)) {
373 if(Level.FATAL.isGreaterOrEqual(this.getEffectiveLevel())) {
374 forcedLog(FQCN, Level.FATAL, message, null);
379 Log a message object with the <code>FATAL</code> level including
380 the stack trace of the {@link Throwable} <code>t</code> passed as
383 <p>See {@link #fatal(Object)} for more detailed information.
385 @param message the message object to log.
386 @param t the exception to log, including its stack trace. */
388 void fatal(Object message, Throwable t) {
389 if(repository.isDisabled(Level.FATAL_INT)) {
392 if(Level.FATAL.isGreaterOrEqual(this.getEffectiveLevel())) {
393 forcedLog(FQCN, Level.FATAL, message, t);
399 This method creates a new logging event and logs the event
400 without further checks. */
402 void forcedLog(String fqcn, Priority level, Object message, Throwable t) {
403 callAppenders(new LoggingEvent(fqcn, this, level, message, t));
408 Get the additivity flag for this Category instance.
411 boolean getAdditivity() {
416 Get the appenders contained in this category as an {@link
417 Enumeration}. If no appenders can be found, then a {@link NullEnumeration}
420 @return Enumeration An enumeration of the appenders in this category. */
423 Enumeration getAllAppenders() {
425 return NullEnumeration.getInstance();
427 return aai.getAllAppenders();
432 Look for the appender named as <code>name</code>.
434 <p>Return the appender with that name if in the list. Return
435 <code>null</code> otherwise. */
438 Appender getAppender(String name) {
439 if(aai == null || name == null) {
443 return aai.getAppender(name);
447 Starting from this category, search the category hierarchy for a
448 non-null level and return it. Otherwise, return the level of the
451 <p>The Category class is designed so that this method executes as
455 Level getEffectiveLevel() {
456 for(Category c = this; c != null; c=c.parent) {
457 if(c.level != null) {
461 return null; // If reached will cause an NullPointerException.
466 * @deprecated Please use the the {@link #getEffectiveLevel} method
470 Priority getChainedPriority() {
471 for(Category c = this; c != null; c=c.parent) {
472 if(c.level != null) {
476 return null; // If reached will cause an NullPointerException.
481 Returns all the currently defined categories in the default
482 hierarchy as an {@link java.util.Enumeration Enumeration}.
484 <p>The root category is <em>not</em> included in the returned
487 @deprecated Please use {@link LogManager#getCurrentLoggers()} instead.
491 Enumeration getCurrentCategories() {
492 return LogManager.getCurrentLoggers();
497 Return the default Hierarchy instance.
499 @deprecated Please use {@link LogManager#getLoggerRepository()} instead.
505 LoggerRepository getDefaultHierarchy() {
506 return LogManager.getLoggerRepository();
510 Return the the {@link Hierarchy} where this <code>Category</code>
511 instance is attached.
513 @deprecated Please use {@link #getLoggerRepository} instead.
517 LoggerRepository getHierarchy() {
522 Return the the {@link LoggerRepository} where this
523 <code>Category</code> is attached.
527 LoggerRepository getLoggerRepository() {
533 * @deprecated Make sure to use {@link Logger#getLogger(String)} instead.
537 Category getInstance(String name) {
538 return LogManager.getLogger(name);
542 * @deprecated Please make sure to use {@link Logger#getLogger(Class)} instead.
546 Category getInstance(Class clazz) {
547 return LogManager.getLogger(clazz);
552 Return the category name. */
561 Returns the parent of this category. Note that the parent of a
562 given category may change during the lifetime of the category.
564 <p>The root category will return <code>null</code>.
570 Category getParent() {
576 Returns the assigned {@link Level}, if any, for this Category.
578 @return Level - the assigned Level, can be <code>null</code>.
587 @deprecated Please use {@link #getLevel} instead.
591 Level getPriority() {
597 * @deprecated Please use {@link Logger#getRootLogger()} instead.
603 return LogManager.getRootLogger();
607 Return the <em>inherited</em> {@link ResourceBundle} for this
610 <p>This method walks the hierarchy to find the appropriate
611 resource bundle. It will return the resource bundle attached to
612 the closest ancestor of this category, much like the way
613 priorities are searched. In case there is no bundle in the
614 hierarchy then <code>null</code> is returned.
618 ResourceBundle getResourceBundle() {
619 for(Category c = this; c != null; c=c.parent) {
620 if(c.resourceBundle != null) {
621 return c.resourceBundle;
624 // It might be the case that there is no resource bundle
629 Returns the string resource coresponding to <code>key</code> in
630 this category's inherited resource bundle. See also {@link
633 <p>If the resource cannot be found, then an {@link #error error}
634 message will be logged complaining about the missing resource.
637 String getResourceBundleString(String key) {
638 ResourceBundle rb = getResourceBundle();
639 // This is one of the rare cases where we can use logging in order
640 // to report errors from within log4j.
642 //if(!hierarchy.emittedNoResourceBundleWarning) {
643 //error("No resource bundle has been set for category "+name);
644 //hierarchy.emittedNoResourceBundleWarning = true;
650 return rb.getString(key);
652 catch(MissingResourceException mre) {
653 error("No resource is associated with key \""+key+"\".");
660 Log a message object with the {@link Level#INFO INFO} Level.
662 <p>This method first checks if this category is <code>INFO</code>
663 enabled by comparing the level of this category with {@link
664 Level#INFO INFO} Level. If the category is <code>INFO</code>
665 enabled, then it converts the message object passed as parameter
666 to a string by invoking the appropriate
667 {@link org.apache.log4j.or.ObjectRenderer}. It
668 proceeds to call all the registered appenders in this category and
669 also higher in the hierarchy depending on the value of the
672 <p><b>WARNING</b> Note that passing a {@link Throwable} to this
673 method will print the name of the Throwable but no stack trace. To
674 print a stack trace use the {@link #info(Object, Throwable)} form
677 @param message the message object to log */
679 void info(Object message) {
680 if(repository.isDisabled(Level.INFO_INT)) {
683 if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel())) {
684 forcedLog(FQCN, Level.INFO, message, null);
689 Log a message object with the <code>INFO</code> level including
690 the stack trace of the {@link Throwable} <code>t</code> passed as
693 <p>See {@link #info(Object)} for more detailed information.
695 @param message the message object to log.
696 @param t the exception to log, including its stack trace. */
698 void info(Object message, Throwable t) {
699 if(repository.isDisabled(Level.INFO_INT)) {
702 if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel())) {
703 forcedLog(FQCN, Level.INFO, message, t);
708 Is the appender passed as parameter attached to this category?
711 boolean isAttached(Appender appender) {
712 if(appender == null || aai == null) {
715 return aai.isAttached(appender);
720 * Check whether this category is enabled for the <code>DEBUG</code>
723 * <p> This function is intended to lessen the computational cost of
724 * disabled log debug statements.
726 * <p> For some <code>cat</code> Category object, when you write,
728 * cat.debug("This is entry number: " + i );
731 * <p>You incur the cost constructing the message, concatenatiion in
732 * this case, regardless of whether the message is logged or not.
734 * <p>If you are worried about speed, then you should write
736 * if(cat.isDebugEnabled()) {
737 * cat.debug("This is entry number: " + i );
741 * <p>This way you will not incur the cost of parameter
742 * construction if debugging is disabled for <code>cat</code>. On
743 * the other hand, if the <code>cat</code> is debug enabled, you
744 * will incur the cost of evaluating whether the category is debug
745 * enabled twice. Once in <code>isDebugEnabled</code> and once in
746 * the <code>debug</code>. This is an insignificant overhead
747 * since evaluating a category takes about 1%% of the time it
748 * takes to actually log.
750 * @return boolean - <code>true</code> if this category is debug
751 * enabled, <code>false</code> otherwise.
754 boolean isDebugEnabled() {
755 if(repository.isDisabled( Level.DEBUG_INT)) {
758 return Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel());
762 Check whether this category is enabled for a given {@link
763 Level} passed as parameter.
765 See also {@link #isDebugEnabled}.
767 @return boolean True if this category is enabled for <code>level</code>.
770 boolean isEnabledFor(Priority level) {
771 if(repository.isDisabled(level.level)) {
774 return level.isGreaterOrEqual(this.getEffectiveLevel());
778 Check whether this category is enabled for the info Level.
779 See also {@link #isDebugEnabled}.
781 @return boolean - <code>true</code> if this category is enabled
782 for level info, <code>false</code> otherwise.
785 boolean isInfoEnabled() {
786 if(repository.isDisabled(Level.INFO_INT)) {
789 return Level.INFO.isGreaterOrEqual(this.getEffectiveLevel());
794 Log a localized message. The user supplied parameter
795 <code>key</code> is replaced by its localized version from the
798 @see #setResourceBundle
802 void l7dlog(Priority priority, String key, Throwable t) {
803 if(repository.isDisabled(priority.level)) {
806 if(priority.isGreaterOrEqual(this.getEffectiveLevel())) {
807 String msg = getResourceBundleString(key);
808 // if message corresponding to 'key' could not be found in the
809 // resource bundle, then default to 'key'.
813 forcedLog(FQCN, priority, msg, t);
817 Log a localized and parameterized message. First, the user
818 supplied <code>key</code> is searched in the resource
819 bundle. Next, the resulting pattern is formatted using
820 {@link java.text.MessageFormat#format(String,Object[])} method with the
821 user supplied object array <code>params</code>.
826 void l7dlog(Priority priority, String key, Object[] params, Throwable t) {
827 if(repository.isDisabled(priority.level)) {
830 if(priority.isGreaterOrEqual(this.getEffectiveLevel())) {
831 String pattern = getResourceBundleString(key);
833 if(pattern == null) {
836 msg = java.text.MessageFormat.format(pattern, params);
838 forcedLog(FQCN, priority, msg, t);
843 This generic form is intended to be used by wrappers.
846 void log(Priority priority, Object message, Throwable t) {
847 if(repository.isDisabled(priority.level)) {
850 if(priority.isGreaterOrEqual(this.getEffectiveLevel())) {
851 forcedLog(FQCN, priority, message, t);
856 This generic form is intended to be used by wrappers.
859 void log(Priority priority, Object message) {
860 if(repository.isDisabled(priority.level)) {
863 if(priority.isGreaterOrEqual(this.getEffectiveLevel())) {
864 forcedLog(FQCN, priority, message, null);
870 This is the most generic printing method. It is intended to be
871 invoked by <b>wrapper</b> classes.
873 @param callerFQCN The wrapper class' fully qualified class name.
874 @param level The level of the logging request.
875 @param message The message of the logging request.
876 @param t The throwable of the logging request, may be null. */
878 void log(String callerFQCN, Priority level, Object message, Throwable t) {
879 if(repository.isDisabled(level.level)) {
882 if(level.isGreaterOrEqual(this.getEffectiveLevel())) {
883 forcedLog(callerFQCN, level, message, t);
888 * LoggerRepository forgot the fireRemoveAppenderEvent method,
889 * if using the stock Hierarchy implementation, then call its fireRemove.
890 * Custom repositories can implement HierarchyEventListener if they
891 * want remove notifications.
892 * @param appender appender, may be null.
894 private void fireRemoveAppenderEvent(final Appender appender) {
895 if (appender != null) {
896 if (repository instanceof Hierarchy) {
897 ((Hierarchy) repository).fireRemoveAppenderEvent(this, appender);
898 } else if (repository instanceof HierarchyEventListener) {
899 ((HierarchyEventListener) repository).removeAppenderEvent(this, appender);
905 Remove all previously added appenders from this Category
908 <p>This is useful when re-reading configuration information.
912 void removeAllAppenders() {
914 Vector appenders = new Vector();
915 for (Enumeration iter = aai.getAllAppenders(); iter != null && iter.hasMoreElements();) {
916 appenders.add(iter.nextElement());
918 aai.removeAllAppenders();
919 for(Enumeration iter = appenders.elements(); iter.hasMoreElements();) {
920 fireRemoveAppenderEvent((Appender) iter.nextElement());
928 Remove the appender passed as parameter form the list of appenders.
934 void removeAppender(Appender appender) {
935 if(appender == null || aai == null) {
938 boolean wasAttached = aai.isAttached(appender);
939 aai.removeAppender(appender);
941 fireRemoveAppenderEvent(appender);
946 Remove the appender with the name passed as parameter form the
952 void removeAppender(String name) {
953 if(name == null || aai == null) {
956 Appender appender = aai.getAppender(name);
957 aai.removeAppender(name);
958 if (appender != null) {
959 fireRemoveAppenderEvent(appender);
964 Set the additivity flag for this Category instance.
968 void setAdditivity(boolean additive) {
969 this.additive = additive;
973 Only the Hiearchy class can set the hiearchy of a
974 category. Default package access is MANDATORY here. */
976 void setHierarchy(LoggerRepository repository) {
977 this.repository = repository;
981 Set the level of this Category. If you are passing any of
982 <code>Level.DEBUG</code>, <code>Level.INFO</code>,
983 <code>Level.WARN</code>, <code>Level.ERROR</code>,
984 <code>Level.FATAL</code> as a parameter, you need to case them as
987 <p>As in <pre> logger.setLevel((Level) Level.DEBUG); </pre>
990 <p>Null values are admitted. */
992 void setLevel(Level level) {
998 Set the level of this Category.
1000 <p>Null values are admitted.
1002 @deprecated Please use {@link #setLevel} instead.
1005 void setPriority(Priority priority) {
1006 this.level = (Level) priority;
1011 Set the resource bundle to be used with localized logging
1012 methods {@link #l7dlog(Priority,String,Throwable)} and {@link
1013 #l7dlog(Priority,String,Object[],Throwable)}.
1018 void setResourceBundle(ResourceBundle bundle) {
1019 resourceBundle = bundle;
1023 Calling this method will <em>safely</em> close and remove all
1024 appenders in all the categories including root contained in the
1027 <p>Some appenders such as {@link org.apache.log4j.net.SocketAppender}
1028 and {@link AsyncAppender} need to be closed before the
1029 application exists. Otherwise, pending logging events might be
1032 <p>The <code>shutdown</code> method is careful to close nested
1033 appenders before closing regular appenders. This is allows
1034 configurations where a regular appender is attached to a category
1035 and again to a nested appender.
1037 @deprecated Please use {@link LogManager#shutdown()} instead.
1044 LogManager.shutdown();
1049 Log a message object with the {@link Level#WARN WARN} Level.
1051 <p>This method first checks if this category is <code>WARN</code>
1052 enabled by comparing the level of this category with {@link
1053 Level#WARN WARN} Level. If the category is <code>WARN</code>
1054 enabled, then it converts the message object passed as parameter
1055 to a string by invoking the appropriate
1056 {@link org.apache.log4j.or.ObjectRenderer}. It
1057 proceeds to call all the registered appenders in this category and
1058 also higher in the hieararchy depending on the value of the
1061 <p><b>WARNING</b> Note that passing a {@link Throwable} to this
1062 method will print the name of the Throwable but no stack trace. To
1063 print a stack trace use the {@link #warn(Object, Throwable)} form
1066 @param message the message object to log. */
1068 void warn(Object message) {
1069 if(repository.isDisabled( Level.WARN_INT)) {
1073 if(Level.WARN.isGreaterOrEqual(this.getEffectiveLevel())) {
1074 forcedLog(FQCN, Level.WARN, message, null);
1079 Log a message with the <code>WARN</code> level including the
1080 stack trace of the {@link Throwable} <code>t</code> passed as
1083 <p>See {@link #warn(Object)} for more detailed information.
1085 @param message the message object to log.
1086 @param t the exception to log, including its stack trace. */
1088 void warn(Object message, Throwable t) {
1089 if(repository.isDisabled(Level.WARN_INT)) {
1092 if(Level.WARN.isGreaterOrEqual(this.getEffectiveLevel())) {
1093 forcedLog(FQCN, Level.WARN, message, t);