You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2021/12/23 16:25:41 UTC
[logging-log4j1] 01/01: This commit was manufactured by cvs2svn to create tag 'v1_2_10-recalled'.
This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to annotated tag v1_2_10-recalled
in repository https://gitbox.apache.org/repos/asf/logging-log4j1.git
commit d5aab726d1cf6bd113a7ddd708180918da29b5ef
Author: No Author <de...@apache.org>
AuthorDate: Fri Apr 29 17:39:41 2005 +0000
This commit was manufactured by cvs2svn to create tag
'v1_2_10-recalled'.
git-svn-id: https://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_10-recalled@311334 13f79535-47bb-0310-9956-ffa450edef68
---
BRANCHES | 61 +
INSTALL | 23 +-
bin/StartLogFactor5.sh | 20 +
bin/StartLogFactor5Console.bat | 24 +
bin/lcp.bat | 2 +
build.properties.sample | 12 +
build.xml | 151 +-
build/siteBuild.sh | 34 -
build/siteBuild.xml | 49 -
docs/FAQ.html | 1646 +++++++++++++-------
docs/{HISTORY => HISTORY.txt} | 165 +-
docs/critique.html | 294 ----
docs/deepExtension.html | 735 ---------
docs/images/ceki-72x101.gif | Bin 0 -> 7712 bytes
docs/images/chainsaw-fullscreen-small.jpg | Bin 0 -> 55917 bytes
docs/images/chainsaw-fullscreen.jpg | Bin 0 -> 208947 bytes
docs/images/coverSmall.png | Bin 0 -> 57875 bytes
docs/images/mark-72x99.gif | Bin 0 -> 2206 bytes
docs/images/psmith.jpg | Bin 0 -> 8052 bytes
docs/images/yshapira.bmp | Bin 0 -> 31514 bytes
docs/lf5/images/blue_on_white.gif | Bin 0 -> 908 bytes
docs/lf5/images/console_window.gif | Bin 0 -> 56097 bytes
docs/lf5/images/lf5.gif | Bin 0 -> 35277 bytes
docs/lf5/images/lf5_about.gif | Bin 0 -> 9451 bytes
docs/lf5/images/lf5_category_explorer.gif | Bin 0 -> 62477 bytes
docs/lf5/images/lf5_collapseall.gif | Bin 0 -> 62701 bytes
docs/lf5/images/lf5_colorchooser.gif | Bin 0 -> 62676 bytes
docs/lf5/images/lf5_compactview.gif | Bin 0 -> 53415 bytes
docs/lf5/images/lf5_configure.gif | Bin 0 -> 62471 bytes
docs/lf5/images/lf5_deselectall.gif | Bin 0 -> 65637 bytes
docs/lf5/images/lf5_detailedview.gif | Bin 0 -> 57900 bytes
docs/lf5/images/lf5_expandall.gif | Bin 0 -> 64917 bytes
docs/lf5/images/lf5_loglevels.gif | Bin 0 -> 62411 bytes
docs/lf5/images/lf5_logo.gif | Bin 0 -> 2398 bytes
docs/lf5/images/lf5_logo_small.gif | Bin 0 -> 970 bytes
docs/lf5/images/lf5_logtable.gif | Bin 0 -> 61525 bytes
docs/lf5/images/lf5_ndc_filtering.gif | Bin 0 -> 42345 bytes
docs/lf5/images/lf5_openfile.gif | Bin 0 -> 51140 bytes
docs/lf5/images/lf5_openurl.gif | Bin 0 -> 61066 bytes
docs/lf5/images/lf5_properties.gif | Bin 0 -> 52169 bytes
docs/lf5/images/lf5_recorddetail.gif | Bin 0 -> 55142 bytes
docs/lf5/images/lf5_remove_categories.gif | Bin 0 -> 66759 bytes
docs/lf5/images/lf5_search.gif | Bin 0 -> 59820 bytes
docs/lf5/images/lf5_selectall.gif | Bin 0 -> 65440 bytes
docs/lf5/images/lf5_small.gif | Bin 0 -> 19171 bytes
docs/lf5/images/lf5_standardview.gif | Bin 0 -> 54007 bytes
docs/lf5/images/lf5_view.gif | Bin 0 -> 63526 bytes
docs/lf5/images/small_right_arrow.gif | Bin 0 -> 76 bytes
docs/manual.html | 189 +--
docs/overview.html | 1 +
docs/praise.html | 266 ----
examples/MyPatternLayout.java | 8 +-
examples/NumberCruncherServer.java | 17 +-
examples/SortAlgo.java | 14 +-
examples/Trivial.java | 14 +-
.../InitUsingDefaultConfigurator.java | 126 ++
.../InitUsingLog4JProperties.java | 112 ++
.../lf5/InitUsingLog4JProperties/log4j.properties | 17 +
.../InitUsingMultipleAppenders.java | 137 ++
.../InitUsingMultipleAppenders/example.properties | 34 +
.../InitUsingPropertiesFile.java | 116 ++
.../lf5/InitUsingPropertiesFile/example.properties | 17 +
.../InitUsingXMLPropertiesFile.java | 110 ++
.../lf5/InitUsingXMLPropertiesFile/example.xml | 15 +
examples/lf5/OpeningLogFiles/sample.log | 184 +++
.../CustomizedLogLevels.java | 101 ++
.../UsingLogMonitorAdapter.java | 86 +
.../UsingSocketAppenders/UsingSocketAppenders.java | 132 ++
.../UsingSocketAppenders/socketclient.properties | 18 +
.../UsingSocketAppenders/socketserver.properties | 19 +
examples/lf5/index.html | 11 +
examples/mycat.bad | 14 +-
examples/mycat.good | 16 +-
examples/subclass/MyLogger.java | 10 -
examples/subclass/MyLoggerTest.java | 2 +-
slf4j.xml | 82 +
src/filtered-java/org/slf4j/LoggerFactory.java | 84 +
.../org/slf4j/LoggerFactoryAdapter.java | 60 +
src/filtered-java/org/slf4j/ULogger.java | 104 ++
src/filtered-java/org/slf4j/impl/JDK14Logger.java | 243 +++
.../org/slf4j/impl/JDK14LoggerFA.java | 74 +
.../org/slf4j/impl/MessageFormatter.java | 143 ++
src/filtered-java/org/slf4j/impl/NOPLogger.java | 200 +++
src/filtered-java/org/slf4j/impl/NOPLoggerFA.java | 58 +
src/filtered-java/org/slf4j/impl/SimpleLogger.java | 290 ++++
.../org/slf4j/impl/SimpleLoggerFA.java | 83 +
src/java/org/apache/log4j/Appender.java | 2 +-
src/java/org/apache/log4j/AppenderSkeleton.java | 31 +-
src/java/org/apache/log4j/AsyncAppender.java | 109 +-
src/java/org/apache/log4j/Category.java | 376 ++++-
src/java/org/apache/log4j/ConsoleAppender.java | 38 +-
.../org/apache/log4j/DailyRollingFileAppender.java | 112 +-
src/java/org/apache/log4j/FileAppender.java | 35 +-
src/java/org/apache/log4j/HTMLLayout.java | 14 +-
src/java/org/apache/log4j/LogManager.java | 140 +-
src/java/org/apache/log4j/Logger.java | 30 +-
src/java/org/apache/log4j/MDC.java | 21 +-
src/java/org/apache/log4j/NDC.java | 17 +-
src/java/org/apache/log4j/Priority.java | 47 +-
.../org/apache/log4j/PropertyConfigurator.java | 33 +-
src/java/org/apache/log4j/SimpleLayout.java | 2 +-
src/java/org/apache/log4j/TTCCLayout.java | 8 +-
src/java/org/apache/log4j/WriterAppender.java | 27 +-
.../org/apache/log4j/chainsaw/ControlPanel.java | 8 +-
.../org/apache/log4j/chainsaw/DetailPanel.java | 8 +-
.../org/apache/log4j/chainsaw/EventDetails.java | 4 +-
src/java/org/apache/log4j/chainsaw/ExitAction.java | 4 +-
.../org/apache/log4j/chainsaw/LoadXMLAction.java | 5 +-
.../org/apache/log4j/chainsaw/LoggingReceiver.java | 22 +-
src/java/org/apache/log4j/chainsaw/Main.java | 6 +-
.../org/apache/log4j/chainsaw/MyTableModel.java | 5 +-
.../org/apache/log4j/chainsaw/XMLFileHandler.java | 59 +-
.../org/apache/log4j/config/PropertyGetter.java | 2 +-
.../org/apache/log4j/config/PropertyPrinter.java | 20 +-
.../org/apache/log4j/config/PropertySetter.java | 9 +-
.../log4j/config/PropertySetterException.java | 9 +-
.../log4j/helpers/AppenderAttachableImpl.java | 4 +-
src/java/org/apache/log4j/helpers/BoundedFIFO.java | 4 +-
src/java/org/apache/log4j/helpers/Loader.java | 134 +-
.../org/apache/log4j/helpers/NullEnumeration.java | 4 +-
.../org/apache/log4j/helpers/OptionConverter.java | 8 +-
.../org/apache/log4j/helpers/PatternParser.java | 4 +-
.../org/apache/log4j/helpers/SyslogWriter.java | 4 +-
src/java/org/apache/log4j/helpers/Transform.java | 59 +-
src/java/org/apache/log4j/jdbc/JDBCAppender.java | 23 +-
src/java/org/apache/log4j/jmx/Agent.java | 4 +-
.../apache/log4j/jmx/HierarchyDynamicMBean.java | 2 +-
.../org/apache/log4j/jmx/LoggerDynamicMBean.java | 8 +-
src/java/org/apache/log4j/jmx/T.java | 22 -
src/java/org/apache/log4j/lf5/LF5Appender.java | 6 +-
src/java/org/apache/log4j/lf5/LogRecord.java | 2 +-
.../log4j/lf5/config/defaultconfig.properties | 16 +
.../apache/log4j/lf5/util/ProductProperties.java | 248 ---
.../apache/log4j/lf5/viewer/LogBrokerMonitor.java | 29 +-
.../log4j/lf5/viewer/LogFactor5AboutDialog.java | 136 --
.../categoryexplorer/CategoryNodeEditor.java | 6 +-
.../lf5/viewer/configure/ConfigurationManager.java | 3 +-
.../log4j/lf5/viewer/configure/MRUFileManager.java | 10 +-
.../apache/log4j/lf5/viewer/images/lf5_about.gif | Bin 23106 -> 0 bytes
.../log4j/lf5/viewer/images/lf5_small_icon.png | Bin 42566 -> 0 bytes
src/java/org/apache/log4j/net/JMSAppender.java | 261 +++-
src/java/org/apache/log4j/net/JMSSink.java | 125 +-
src/java/org/apache/log4j/net/SMTPAppender.java | 4 +-
.../org/apache/log4j/net/SimpleSocketServer.java | 55 +-
src/java/org/apache/log4j/net/SocketAppender.java | 107 +-
src/java/org/apache/log4j/net/SocketNode.java | 16 +-
src/java/org/apache/log4j/net/SocketServer.java | 6 +-
src/java/org/apache/log4j/net/SyslogAppender.java | 6 +-
src/java/org/apache/log4j/net/test/Loop.java | 6 +-
src/java/org/apache/log4j/net/test/SMTPMin.java | 6 +-
src/java/org/apache/log4j/net/test/SocketMin.java | 10 +-
src/java/org/apache/log4j/net/test/SyslogMin.java | 6 +-
.../org/apache/log4j/nt/NTEventLogAppender.java | 4 +-
src/java/org/apache/log4j/nt/test/NTMin.java | 6 +-
src/java/org/apache/log4j/or/DefaultRenderer.java | 2 +-
src/java/org/apache/log4j/or/ObjectRenderer.java | 2 +-
src/java/org/apache/log4j/or/RendererMap.java | 5 +-
.../org/apache/log4j/or/ThreadGroupRenderer.java | 2 +-
.../apache/log4j/performance/ConcatVsArray.java | 66 -
.../org/apache/log4j/performance/ListVsVector.java | 2 +-
src/java/org/apache/log4j/performance/Logging.java | 287 ----
.../org/apache/log4j/performance/NOPWriter.java | 53 +-
.../org/apache/log4j/performance/NewVsSetLen.java | 4 +-
.../org/apache/log4j/performance/NotLogging.java | 168 --
.../org/apache/log4j/performance/NullAppender.java | 13 +-
.../org/apache/log4j/performance/SystemTime.java | 2 +-
src/java/org/apache/log4j/performance/logging | 50 +
src/java/org/apache/log4j/performance/package.html | 20 +-
.../apache/log4j/performance/xml/logging201.xml | 36 +-
.../apache/log4j/performance/xml/logging202.xml | 36 +-
.../apache/log4j/performance/xml/logging203.xml | 36 +-
.../apache/log4j/performance/xml/logging204.xml | 38 +-
.../apache/log4j/performance/xml/logging205.xml | 38 +-
.../apache/log4j/performance/xml/logging206.xml | 38 +-
.../apache/log4j/performance/xml/logging207.xml | 34 +-
.../apache/log4j/performance/xml/logging220.xml | 23 +
.../apache/log4j/performance/xml/logging221.xml | 25 +
.../apache/log4j/performance/xml/logging222.xml | 24 +
.../apache/log4j/performance/xml/logging223.xml | 25 +
.../apache/log4j/performance/xml/logging224.xml | 25 +
.../apache/log4j/performance/xml/logging225.xml | 25 +
.../apache/log4j/performance/xml/logging226.xml | 25 +
.../apache/log4j/performance/xml/logging227.xml | 25 +
src/java/org/apache/log4j/spi/Configurator.java | 24 +-
src/java/org/apache/log4j/spi/Filter.java | 2 +-
.../org/apache/log4j/spi/LoggerRepository.java | 7 +-
src/java/org/apache/log4j/spi/LoggingEvent.java | 124 +-
src/java/org/apache/log4j/spi/RootCategory.java | 11 +-
src/java/org/apache/log4j/spi/RootLogger.java | 69 +
.../org/apache/log4j/spi/ThrowableInformation.java | 82 +-
.../org/apache/log4j/test/AsyncAppenderTest.java | 16 +-
src/java/org/apache/log4j/test/Base64.java | 105 --
.../org/apache/log4j/test/CategoryWrapper.java | 6 +-
.../log4j/test/ConfigurationFileParsing.java | 9 +-
src/java/org/apache/log4j/test/DRFATest.java | 4 +-
src/java/org/apache/log4j/test/DefaultInit.java | 4 +-
src/java/org/apache/log4j/test/DelayedLoop.java | 4 +-
src/java/org/apache/log4j/test/FQCNTest.java | 4 +-
src/java/org/apache/log4j/test/Finalize.java | 14 +-
src/java/org/apache/log4j/test/Hello.java | 4 +-
src/java/org/apache/log4j/test/L7D.java | 79 -
src/java/org/apache/log4j/test/MDCStress.java | 4 +-
.../org/apache/log4j/test/MultipleAppenders.java | 4 +-
src/java/org/apache/log4j/test/PatternTest.java | 9 +-
src/java/org/apache/log4j/test/ROFile.java | 4 +-
src/java/org/apache/log4j/test/Shallow.java | 22 +-
.../org/apache/log4j/test/ShortSocketServer.java | 7 +-
.../org/apache/log4j/test/StressAsyncAppender.java | 4 +-
src/java/org/apache/log4j/test/StressNDC.java | 175 ---
.../org/apache/log4j/test/SysoutConfigurator.java | 4 +-
.../log4j/varia/ExternallyRolledFileAppender.java | 7 +-
.../apache/log4j/varia/FallbackErrorHandler.java | 29 +-
.../org/apache/log4j/varia/LevelMatchFilter.java | 4 +-
.../org/apache/log4j/varia/LevelRangeFilter.java | 136 ++
src/java/org/apache/log4j/varia/NullAppender.java | 65 +
src/java/org/apache/log4j/varia/Roller.java | 4 +-
src/java/org/apache/log4j/varia/test/Loop.java | 4 +-
src/java/org/apache/log4j/xml/DOMConfigurator.java | 51 +-
.../org/apache/log4j/xml/Log4jEntityResolver.java | 44 +
src/java/org/apache/log4j/xml/XMLLayout.java | 180 ++-
.../org/apache/log4j/xml/examples/XMLSample.java | 6 +-
src/java/org/apache/log4j/xml/log4j.dtd | 19 +-
src/java/org/apache/log4j/xml/test/DOMTest.java | 15 +-
src/java/org/slf4j/LoggerFactory.java | 84 +
src/java/org/slf4j/LoggerFactoryAdapter.java | 60 +
src/java/org/slf4j/ULogger.java | 104 ++
src/java/org/slf4j/impl/Log4jLoggerFA.java | 58 +
src/java/org/slf4j/impl/MessageFormatter.java | 143 ++
src/java/org/slf4j/impl/NOPLogger.java | 200 +++
src/java/org/slf4j/impl/NOPLoggerFA.java | 58 +
src/java/org/slf4j/impl/SimpleLogger.java | 290 ++++
src/java/org/slf4j/impl/SimpleLoggerFA.java | 83 +
src/xdocs/contributors.xml | 12 +-
src/xdocs/documentation.xml | 74 +-
src/xdocs/download.xml | 81 +-
src/xdocs/index.xml | 15 +-
src/xdocs/lf5/configuration.xml | 114 ++
src/xdocs/lf5/examples.xml | 564 +++++++
src/xdocs/lf5/faq.xml | 45 +
src/xdocs/lf5/features.xml | 249 +++
src/xdocs/lf5/overview.xml | 76 +
src/xdocs/lf5/readingfiles.xml | 99 ++
src/xdocs/lf5/trouble.xml | 307 ++++
src/xdocs/plan.xml | 19 +-
src/xdocs/stylesheets/lf5.xml | 27 +
src/xdocs/stylesheets/project.xml | 2 +
tests/build.xml | 77 +-
tests/input/defaultInit3.properties | 7 +
tests/input/socketServer5.properties | 8 +
tests/input/socketServer6.properties | 8 +
tests/input/socketServer7.properties | 8 +
tests/input/socketServer8.properties | 8 +
tests/input/xml/defaultInit.xml | 17 +
tests/input/xml/fallback1.xml | 35 +
.../org/apache/log4j/AsyncAppenderTestCase.java | 52 +-
.../src/java/org/apache/log4j/LoggerTestCase.java | 14 +-
.../src/java/org/apache/log4j/MyPatternLayout.java | 8 +-
.../src/java/org/apache/log4j/StressCategory.java | 14 +-
.../src/java/org/apache/log4j/VectorAppender.java | 30 +-
.../org/apache/log4j/defaultInit/TestCase1.java | 45 +
.../org/apache/log4j/defaultInit/TestCase2.java | 49 +
.../org/apache/log4j/defaultInit/TestCase3.java | 49 +
.../org/apache/log4j/defaultInit/TestCase4.java | 50 +
.../apache/log4j/helpers/BoundedFIFOTestCase.java | 8 +-
.../apache/log4j/helpers/CyclicBufferTestCase.java | 8 +-
.../log4j/helpers/PatternParserTestCase.java | 121 ++
.../org/apache/log4j/net/ShortSocketServer.java | 18 +-
.../org/apache/log4j/net/SocketServerTestCase.java | 158 +-
.../apache/log4j/varia/ErrorHandlerTestCase.java | 109 ++
.../org/apache/log4j/xml/XMLLayoutTestCase.java | 30 +-
tests/witness/PatternParser_mdc | 12 +
tests/witness/socketServer.5 | 35 +
tests/witness/socketServer.6 | 35 +
tests/witness/socketServer.7 | 35 +
tests/witness/socketServer.8 | 35 +
tests/witness/xmlLayout.1 | 30 +-
tests/witness/xmlLayout.2 | 30 +-
tests/witness/xmlLayout.3 | 5 +
tests/witness/xmlLayout.null | 26 +
279 files changed, 10515 insertions(+), 4897 deletions(-)
diff --git a/BRANCHES b/BRANCHES
new file mode 100644
index 0000000..da0e39d
--- /dev/null
+++ b/BRANCHES
@@ -0,0 +1,61 @@
+
+Given that log4j 1.3 is not likely to be released before a few months,
+I have created a branch called v1_2-branch in our CVS repository. The
+branch was created by issuing the following command:
+
+cvs -d :ext:ceki@cvs.apache.org:/home/cvs rtag -b -r v1_2final v1_2-branch jakarta-log4j
+
+Using the 1.2 branch, we can incorporate patches to log4j version 1.2
+while version 1.3 continues to be developed on the main trunk. For
+example, we can officially release LogFactor5 (including
+documentation) already in log4j 1.2.1.
+
+The command to access the v1_2-branch is:
+
+cvs -d XYZ checkout -r v1_2-branch jakarta-log4j
+
+where XYZ is the remote repository name, that is
+":ext:ceki@cvs.apache.org:/home/cvs" for me.
+
+Alternatively, you can issue following update command from within any
+existing work copy.
+
+ cvs update -r v1_2-branch
+
+Working with branches is not completely trivial and requires a little
+coordination between committers, in particular in relation with branch
+merge operations. In order to avoid multiple merge conflicts, each
+time we merge from the 1.2 branch to the main trunk, we should tag the
+merged version on the 1.2 branch. Subsequent merges should use the tag
+referring to the latest merged version of the branch. Also do not
+forget to publicly announce a merge operation.
+
+I am suggesting that (1.2 -> trunk) merge operations be done in a
+concerted manner. Before doing a merge you tell everyone that you are
+going to do a merge, you execute the merge operation, and then tag the
+merged version on the 1.2 branch, for example v_1_2_-merged-bug666
+
+The *next* merge operation would be performed as
+
+ cvs update -j v_1_2_-merged-bug666 -j v1_2-branch
+
+from within a working copy of the *trunk*. This merge operation would
+obviously also need to be tagged. According to the CVS manual, this
+procedure eliminates the side effects of merging already merged
+changes.
+
+Bug fixes should and documentation improvements, should be made to the
+1.2 branch, not the trunk. I'll take care of merging the changes to
+the main trunk.
+
+If this sounds like mambo jumbo, I urge you to consult the CVS
+documentation and experiment with branches before hitting the log4j
+repository. Branches are not that complicated really although they
+require slightly more discipline on the part of committers. Do not
+hesitate to shout if you need help.
+
+If you have a better alternative for working with branches please let
+us know.
+
+--
+Ceki
\ No newline at end of file
diff --git a/INSTALL b/INSTALL
index cf4fd20..6463df2 100644
--- a/INSTALL
+++ b/INSTALL
@@ -11,7 +11,8 @@ Using log4j
version number, under PATH_OF_YOUR_CHOICE. We will refer to the
directory PATH_OF_YOUR_CHOICE/jakarta-log4j-VERSION/ as $LOG4J_HOME/.
-3) Add $LOG4J_HOME/dist/lib/log4j-1.2.jar to your CLASSPATH.
+3) Assuming you are using log4j version 1.2, add
+ $LOG4J_HOME/dist/lib/log4j-1.2.jar to your CLASSPATH,
4) You can now test your installation by first compiling the following
simple program.
@@ -47,7 +48,7 @@ JAR files
=========
The log4j distribution comes with one jar file: log4j-VERSION.jar
-under the $LOG4J_HOME/dist/lib/ directory.
+under the LOG4J_HOME/dist/lib/ directory.
This jar file contains all the class files of the log4j project,
except test cases and classes from the "examples" and
@@ -57,8 +58,7 @@ except test cases and classes from the "examples" and
log4j dependencies
==================
-The log4j distribution comes with pre-compiled classes. Log4j is based
-on JDK 1.1 with the following additional requirements:
+Log4j is based on JDK 1.1 with the following additional requirements:
----------------------------
Package org.apache.log4j.xml
@@ -82,7 +82,8 @@ on JDK 1.1 with the following additional requirements:
The SMTPAppender relies on the JavaMail API. It has been tested with
JavaMail API version 1.2. The JavaMail API requires the
- JavaBeans Activation Framework package. You can download the JavaMail API at:
+ JavaBeans Activation Framework package. You can download the
+ JavaMail API at:
http://java.sun.com/products/javamail/
@@ -104,8 +105,8 @@ on JDK 1.1 with the following additional requirements:
-----------------------
Log4j uses the JUnit framework version 3.7 for internal unit
- testing. If you want to compile all log4j source code, then you
- will need JUnit. JUnit is available from:
+ testing. If you want to compile the source code in the tests/
+ directory, then you will need JUnit. JUnit is available from:
http://www.junit.org
@@ -121,7 +122,7 @@ the build.properties and example of which is supplied in the
build.properties.sample file.
In case of problems send an e-mail note to
-log4j-user@jakarta.apache.org. Please do not directly e-mail any of
-the log4j developers. The answer to your question might be useful to
-other users. Moreover, there are many knowledgeable users on the
-log4j-user mailing lists who can quickly answer your questions.
+log4j-user@jakarta.apache.org. Please do not directly e-mail any
+log4j developers. The answer to your question might be useful to other
+users. Moreover, there are many knowledgeable users on the log4j-user
+mailing lists who can quickly answer your questions.
diff --git a/bin/StartLogFactor5.sh b/bin/StartLogFactor5.sh
new file mode 100644
index 0000000..80e296c
--- /dev/null
+++ b/bin/StartLogFactor5.sh
@@ -0,0 +1,20 @@
+#! /bin/sh
+
+if [ -z "$LOG4J_HOME" ] ; then
+ LOG4J_HOME=..
+fi
+
+JAVACMD=$JAVA_HOME/bin/java
+
+# add in the dependency .jar files
+DIRLIBS=${LOG4J_HOME}/dist/lib/*.jar
+for i in ${DIRLIBS}
+do
+
+ if [ "$i" != "${DIRLIBS}" ] ; then
+ LOCALCLASSPATH=$LOCALCLASSPATH:"$i"
+ fi
+
+done
+
+$JAVACMD -classpath "$LOCALCLASSPATH" org.apache.log4j.lf5.StartLogFactor5
\ No newline at end of file
diff --git a/bin/StartLogFactor5Console.bat b/bin/StartLogFactor5Console.bat
new file mode 100644
index 0000000..42cb1ea
--- /dev/null
+++ b/bin/StartLogFactor5Console.bat
@@ -0,0 +1,24 @@
+@echo off
+
+if not "%LOG4J_HOME%" == "" goto start
+
+SET LOG4J_HOME=..
+
+:start
+
+java -fullversion
+set LOCALCLASSPATH=
+for %%i in ("%LOG4J_HOME%\dist\lib\*.jar") do call "%LOG4J_HOME%\bin\lcp.bat" "%%i"
+
+echo using classpath %LOCALCLASSPATH%
+
+java -classpath %LOCALCLASSPATH% org.apache.log4j.lf5.StartLogFactor5
+
+exit
+
+:usage
+echo usage: lf5 (target)
+
+:eof
+pause
+
diff --git a/bin/lcp.bat b/bin/lcp.bat
new file mode 100644
index 0000000..4f26713
--- /dev/null
+++ b/bin/lcp.bat
@@ -0,0 +1,2 @@
+set LOCALCLASSPATH=%1;%LOCALCLASSPATH%
+
diff --git a/build.properties.sample b/build.properties.sample
index 300f021..c5555f6 100644
--- a/build.properties.sample
+++ b/build.properties.sample
@@ -19,4 +19,16 @@ jmx.jar=/java/jmx/lib/jmxri.jar
jmx-extra.jar=/java/jmx/lib/jmxtools.jar
+# jakarta-site2 module is used to transform xml files to html using
+# Anakia. You do not need to worry about this property unless you
+# intend to build the log4j web site yourself.
+jakarta-site2=../jakarta-site2
+# Required to run Checkstyle. Available from http://checkstyle.sf.net
+checkstyle.jar=/java/checkstyle-2.2/checkstyle-all-2.2.jar
+
+
+
+# The templates for the creation of the web-pages are inherited
+# from the parent project.
+logging-site=../logging-site
\ No newline at end of file
diff --git a/build.xml b/build.xml
index 9bcb740..1a1a443 100644
--- a/build.xml
+++ b/build.xml
@@ -4,7 +4,7 @@
<!-- ================================================================= -->
-<!-- NOTE: all directories are relative to jakarta-log4j/ -->
+<!-- NOTE: all directories are relative to logging-log4j/ -->
<!-- the parent of build/ -->
<!-- ================================================================= -->
<project name="log4j" default="usage" basedir="." >
@@ -17,11 +17,14 @@
<!-- prefixed with "env". -->
<property environment="env"/>
- <property name="version" value="1.2"/>
+ <property name="version" value="1.2.10"/>
<!-- The base directory relative to which most targets are built -->
<property name="base" value="."/>
+
+ <property name="deprecation" value="on"/>
+
<!-- The directory where source files are stored. -->
<property name="java.source.dir" value="src/java/"/>
@@ -35,11 +38,14 @@
<!-- Destination for generated jar files -->
<property name="jar.dest" value="dist/lib"/>
+ <!-- The jar file that the jar task will generate -->
<property name="jar.filename" value="log4j-${version}.jar"/>
+ <!-- Destination for documentation files -->
+ <property name="docs.dest" value="./docs"/>
+ <!-- Source directory for xml docs -->
+ <property name="xdocs.src" value="./src/xdocs"/>
- <!-- Destination for documentation files generated or not -->
- <property name="docs" value="docs"/>
<!-- Destination for javadoc generated files -->
<property name="javadoc.dest" value="docs/api"/>
@@ -75,6 +81,12 @@
<pathelement location="${jmx-extra.jar}"/>
</path>
+ <!-- Construct classpath for building the html pages-->
+ <path id="site.classpath">
+ <fileset dir="${logging-site}/lib">
+ <include name="*.jar"/>
+ </fileset>
+ </path>
<!-- ================================================================= -->
<!-- Default target -->
@@ -149,6 +161,19 @@
<echo message="JAVAMAIL is present."/>
</target>
+ <target name="slf4jCheck">
+ <available file="${java.source.dir}/org/slf4j/ULogger.java"
+ property="slf4j-present"/>
+
+ <fail unless="slf4j-present">
+ Missing src/java/org/slf4j/*.java source files.
+
+ Just run the refresh-slf4j target with the command:
+
+ ant refresh-slf4j
+ </fail>
+ </target>
+
<!-- ================================================================= -->
<!-- Initialize variables -->
<!-- NOTE: all directories are relative to jakarta-log4j/ -->
@@ -157,14 +182,23 @@
<tstamp />
</target>
+
+ <target name="refresh-slf4j">
+ <echo>Fecthing required source files from SLF4J.ORG</echo>
+ <!-- copy required SLF4J files into log4j -->
+ <ant antfile="slf4j.xml" target="refresh-slf4j"/>
+ </target>
+
<target name="build" depends="init, build.core, build.examples, build.xml,
build.javamail, build.jms, build.jmx"/>
- <target name="build.core" depends="init">
+ <target name="build.core" depends="init, slf4jCheck">
<mkdir dir="${javac.dest}" />
<javac srcdir="${java.source.dir}"
destdir="${javac.dest}"
- includes="${stem}/**/*.java, ${stem}/xml/XMLLayout.java,"
+ includes="org/slf4j/**/*.java,
+ ${stem}/**/*.java,
+ ${stem}/xml/XMLLayout.java"
excludes="misc/*, **/UnitTest*.java,
**/StressCategory.java,
**/doc-files/*,
@@ -179,6 +213,13 @@
<classpath refid="compile.classpath"/>
</javac>
+ <copy todir="${javac.dest}">
+ <fileset dir="${java.source.dir}"
+ includes="${stem}/lf5/**/*.properties"/>
+ <fileset dir="${java.source.dir}"
+ includes="${stem}/lf5/viewer/images/*"/>
+ </copy>
+
</target>
<target name="build.examples" depends="build.core">
@@ -193,6 +234,12 @@
<rmic base="${javac.dest}"
classname="examples.NumberCruncherServer"
/>
+
+ <copy todir="${javac.dest}">
+ <fileset dir="." includes="examples/lf5/**/*.properties"/>
+ <fileset dir="." includes="examples/lf5/**/*.xml"/>
+ </copy>
+
</target>
<target name="build.xml" depends="init, jaxp" if="jaxp-present">
@@ -223,7 +270,7 @@
<javac deprecation="${deprecation}"
srcdir="${java.source.dir}"
destdir="${javac.dest}"
- includes="${stem}/net/JMS*.java">
+ includes="${stem}/net/JMS*.java, ${stem}/or/jms/*.java">
<classpath refid="compile.classpath"/>
</javac>
</target>
@@ -251,7 +298,7 @@
<!-- ================================================================= -->
<target name="checkstyle" depends="init">
<taskdef resource="checkstyletask.properties"
- classpath="build/lib/checkstyle-all-2.1.jar"/>
+ classpath="${checkstyle.jar}"/>
<!-- by default checkstyle supports the Sun coding standard. -->
<checkstyle lcurlyMethod="nlow"
@@ -270,7 +317,7 @@
<target name="chainsaw" depends="build">
<!-- Need to fork to avoid problems -->
<java classname="org.apache.log4j.chainsaw.Main" fork="yes"
- classpath="${javac.dest}">
+ classpath="${javac.dest};${ant.home}/lib/crimson.jar">
</java>
</target>
@@ -300,7 +347,9 @@
</delete>
<jar jarfile="${jar.dest}/${jar.filename}" basedir="${javac.dest}"
- includes="${stem}/*.class, ${stem}/xml/log4j.dtd,
+ includes="org/slf4j/**/*.class,
+ ${stem}/*.class,
+ ${stem}/xml/log4j.dtd,
${stem}/config/*.class,
${stem}/helpers/*.class,
${stem}/spi/*.class,
@@ -308,6 +357,9 @@
${stem}/jdbc/*.class,
${stem}/varia/*.class,
${stem}/chainsaw/*.class,
+ ${stem}/lf5/**/*.class,
+ ${stem}/lf5/**/*.properties,
+ ${stem}/lf5/**/*.gif,
${stem}/nt/*.class,
${stem}/xml/*.class,
${stem}/jmx/*.class,
@@ -334,6 +386,7 @@
org.apache.log4j.config,
org.apache.log4j.helpers,
org.apache.log4j.jmx,
+ org.apache.log4j.lf5,
org.apache.log4j.net,
org.apache.log4j.nt,
org.apache.log4j.or,
@@ -350,23 +403,63 @@
protected="true"
author="true"
use="true"
- overview="${docs}/overview.html"
+ overview="${docs.dest}/overview.html"
doctitle="log4j version ${version}<br>API Specification"
windowtitle="Log4j Version ${version}"
header="<b>Log4j ${version}</b>"
- bottom="Copyright 2000-2002 Apache Software Foundation.">
+ bottom="Copyright 2000-2005 Apache Software Foundation.">
- <link offline="true"
- href="http://java.sun.com/products/jdk/1.2/docs/api"
- packageListLoc="${packaging.dir}"/>
+ <link href="http://java.sun.com/products/jdk/1.3/docs/api/"/>
+ <link href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/"/>
+ <link href="http://www.slf4j.org/api/"/>
<classpath refid="compile.classpath"/>
</javadoc>
</target>
+ <!-- ============================================== -->
+ <!-- Build the site files using Anakia -->
+ <!-- ============================================== -->
+ <!-- ============================================== -->
+ <!-- Build the site files using Anakia -->
+ <!-- ============================================== -->
+ <target name="prepareSite">
+ <available classname="org.apache.velocity.anakia.AnakiaTask"
+ property="AnakiaTask.present">
+ <classpath refid="site.classpath"/>
+ </available>
+ </target>
+
+ <target name="checkSite" depends="prepareSite" unless="AnakiaTask.present">
+ <echo>
+ AnakiaTask is not present! Please check to make sure that
+ velocity.jar is in your classpath.
+ </echo>
+ </target>
+
+ <target name="site" depends="checkSite" if="AnakiaTask.present">
+ <taskdef name="anakia" classname="org.apache.velocity.anakia.AnakiaTask">
+ <classpath refid="site.classpath"/>
+ </taskdef>
+
+ <mkdir dir="${docs.dest}/css"/>
+ <copy file="${logging-site}/docs/css/site.css" tofile="${docs.dest}/css/site.css"/>
+
+ <anakia basedir="${xdocs.src}" destdir="${docs.dest}/"
+ extension=".html"
+ style="site.vsl"
+ projectFile="stylesheets/project.xml"
+ excludes="**/stylesheets/**, empty.xml, lf5/**"
+ includes="**/*.xml"
+ lastModifiedCheck="true"
+ templatePath="${logging-site}/src/xdocs/stylesheets">
+ </anakia>
+
+ </target>
+
<!-- ================================================================= -->
<!-- Build a complete distribution. Results go to ${dist.images} -->
<!-- ================================================================= -->
- <target name="dist" depends="init, clean, javadoc, jar">
+ <target name="dist" depends="init, clean, javadoc, jar, site">
<delete verbose="true">
<fileset dir=".">
@@ -403,16 +496,17 @@
</delete>
<mkdir dir="${dist.images}" />
+
+ <mkdir dir="${dist.tmp}/logging-log4j-${version}" />
- <mkdir dir="${dist.tmp}/jakarta-log4j-${version}" />
-
- <copy todir="${dist.tmp}/jakarta-log4j-${version}">
+ <copy todir="${dist.tmp}/logging-log4j-${version}">
<fileset dir="${base}"
includes="src/java/**,
docs/**,
examples/**,
build/*,
build.xml,
+ build.properties.sample,
manifest.mf,
INSTALL,
LICENSE.txt,
@@ -423,28 +517,29 @@
**/*.bak, **/goEnv.bat,
**/Makefile, **/goEnv.bat,
docs/pub-support/*,
+ dist/classes/org/**,
src/java/org/apache/log4j/test/**/*,
**/.#*"/>
</copy>
- <fixcrlf srcdir="${dist.tmp}/jakarta-log4j-${version}"
+ <fixcrlf srcdir="${dist.tmp}/logging-log4j-${version}"
includes="build.sh" cr="remove"/>
- <fixcrlf srcdir="${dist.tmp}/jakarta-log4j-${version}"
+ <fixcrlf srcdir="${dist.tmp}/logging-log4j-${version}"
includes="build.bat" cr="add"/>
- <chmod dir="${dist.tmp}/jakarta-log4j-${version}"
+ <chmod dir="${dist.tmp}/logging-log4j-${version}"
includes="build.sh" perm="+x"/>
- <tar tarfile="${dist.images}/jakarta-log4j-${version}.tar"
+ <tar tarfile="${dist.images}/logging-log4j-${version}.tar"
basedir="${dist.tmp}"
- includes="jakarta-log4j-${version}/**" />
+ includes="logging-log4j-${version}/**" />
- <gzip src="${dist.images}/jakarta-log4j-${version}.tar"
- zipfile="${dist.images}/jakarta-log4j-${version}.tar.gz" />
+ <gzip src="${dist.images}/logging-log4j-${version}.tar"
+ zipfile="${dist.images}/logging-log4j-${version}.tar.gz" />
- <zip zipfile="${dist.images}/jakarta-log4j-${version}.zip"
+ <zip zipfile="${dist.images}/logging-log4j-${version}.zip"
basedir="${dist.tmp}"
- includes="jakarta-log4j-${version}/**" />
+ includes="logging-log4j-${version}/**" />
<delete dir="${dist.tmp}" />
diff --git a/build/siteBuild.sh b/build/siteBuild.sh
deleted file mode 100644
index d6707e7..0000000
--- a/build/siteBuild.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-
-if [ "$JAVA_HOME" = "" ] ; then
- echo You must set JAVA_HOME to point at your Java Development Kit directory
- exit 1
-fi
-
-# convert the existing path to unix
-if [ "$OSTYPE" = "cygwin32" ] || [ "$OSTYPE" = "cygwin" ] ; then
- CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
-fi
-
-# Add in the jakarta-site2 library files
-for i in ../../jakarta-site2/lib/*.jar
-do
- CLASSPATH=$CLASSPATH:"$i"
-done
-
-
-# convert the unix path to windows
-if [ "$OSTYPE" = "cygwin32" ] || [ "$OSTYPE" = "cygwin" ] ; then
- CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
-fi
-
-echo "CLASSPATH=$CLASSPATH"
-
-BUILDFILE=siteBuild.xml
-
-#echo $CLASSPATH
-
-java $ANT_OPTS -classpath "$CLASSPATH" org.apache.tools.ant.Main \
- -Dant.home=$ANT_HOME \
- -buildfile ${BUILDFILE} \
- "$@"
diff --git a/build/siteBuild.xml b/build/siteBuild.xml
deleted file mode 100644
index 5f9f844..0000000
--- a/build/siteBuild.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<project name="build-site" default="docs" basedir="..">
-
- <!-- Initialization properties -->
- <property name="project.name" value="log4j.site"/>
-
- <property name="docs.src" value="./src/xdocs"/>
- <property name="docs.dest" value="./docs"/>
-
- <target name="prepare">
- <available classname="org.apache.velocity.anakia.AnakiaTask"
- property="AnakiaTask.present"/>
- </target>
-
- <target depends="prepare" name="prepare-error" unless="AnakiaTask.present">
- <echo>
- AnakiaTask is not present! Please check to make sure that
- velocity.jar is in your classpath.
- </echo>
- </target>
-
- <target name="docs" depends="prepare-error" if="AnakiaTask.present">
- <taskdef name="anakia"
- classname="org.apache.velocity.anakia.AnakiaTask"/>
- <anakia basedir="${docs.src}" destdir="${docs.dest}/"
- extension=".html"
- style="site.vsl"
- projectFile="stylesheets/project.xml"
- excludes="**/stylesheets/**, empty.xml"
- includes="**/*.xml"
- lastModifiedCheck="true"
- templatePath="../jakarta-site2/xdocs/stylesheets">
- </anakia>
- <!--
- <copy todir="${docs.dest}/images" filtering="no">
- <fileset dir="${docs.src}/images">
- <include name="**/*.gif"/>
- <include name="**/*.jpeg"/>
- <include name="**/*.jpg"/>
- </fileset>
- </copy>
- In case we have CSS someday
- <copy todir="${docs.dest}" filtering="no">
- <fileset dir="${docs.src}">
- <include name="**/*.css"/>
- </fileset>
- </copy>
- -->
- </target>
-</project>
diff --git a/docs/FAQ.html b/docs/FAQ.html
index 3b0b0db..f2a9f67 100644
--- a/docs/FAQ.html
+++ b/docs/FAQ.html
@@ -1,212 +1,407 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html> <head>
-<title>log4j FAQ</title>
-</head>
-<body bgcolor=#FFFFFF>
-
-<center>
-<h1>Frequently Asked Questions about log4j</h1>
-
-<b>Ceki Gülcü</b> and <b>Chris Taylor</b>
-<h2>May 2002</h2>
-</center>
-<ul>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<li><p><a href=#whatIs>What is log4j?</a></p>
-
-<li><p><a href=#reliable>Is log4j a reliable logging system?</a></p>
-<li><p><a href=#prerequisites>What are the prerequisites for log4j?</a></p>
-<li><p><a href=#javadoc>Is there javadoc documentation for log4j?</a></p>
-<li><p><a href=#alternatives>What other logging packages are there?</a></p>
-<li><p><a HREF=#usageExample>Is there example code for using log4j?</a></p>
-<li><p><a href=#features>What are the features of log4j?</a></p>
-<li><p><a href=#thread-safety>Is log4j thread-safe?</a></p>
-<li><p><a href=#sample>What does log output look like?</a></p>
-<li><p><a href=#logger>What are <em>Loggers</em>?</a></p>
-<li><p><a href=#behavior>How can I change log behavior at runtime?</a></p>
-<li><p><a HREF=#fastLogging>What is the fastest way of (not) logging?</a></p>
-<li><p><a HREF=#arrayDebug>What is the use of the <code>debug</code> method
-expecting a <code>String</code> array as one of its parameters?</a></p>
+<!-- Content Stylesheet for Site -->
-<li><p><a href=#introCat>Why was the Logger class introduced and how
-do I migrate from the previous String based implementation?</a></p>
-
-<li><p><a href=#namingLoggers>Are there any suggested ways for naming
-loggers?</a></p>
-
-<li><p><a href=#className>How do I get the fully-qualified name of a class in
-a static block?</a></p>
-
-<li><p><a href=#customLayouts>Can the log output format be
-customized?</a></p>
-
-<li><p><a href="#options">What are the configurable options for
-<code>ForBarAppender</code>?</a></p>
-
-
-<li><p><a href=#NDC>Can the outputs of multiple client request go to
-different log files?</a></p>
-
-<li><p><a href=#rm>Logger instances seem to be create only. Why isn't
-there a method to remove logger instances?</a></p>
-
-<li><p><a href=#filterByLevel>Is it possible to direct log output
-to different appenders by level?</a></p>
-
-<li><p><a href=#many21>How do I get multiple processes to log to the
-same file?</a></p>
-
-<li><p><a href=#timestamp>If I have many process across multiple hosts
-(possibly across multiple timezones) logging to the same file using the
-method above, what happens to timestamps?</P>
-
-<LI><P><A HREF="#j2ee">Why can't Log4J find my properties file in a J2EE or WAR application?</P>
-<LI><P><A HREF="#configureandwatch">Is there a way to get Log4J to automatically reload a configuration file if it changes?</P>
-<LI><P><A HREF="#nteventlogproblems">What does the Windows NT Event Viewer complain about missing descriptions for my event messages
-when I use the NTEventLogAppender?</P>
-<LI><P><A HREF="#morenteventlogproblems">Why can't I map my logger names to the loggers that appear in the
-NT Event Log when I use the NTEventLogAppender?</p>
-<li><p><a href=#tax>Why should I donate my log4j extensions back to the
-project?</a></p>
-<li><p><a href=#help>What should I keep in mind when contributing code?</a></p>
-
-
-<li><p><a href=#download>Where can I find the latest distribution of log4j?</a></p>
-
-</ul>
-
-<hr>
-<p><a name=whatIs><h4 id="whatIs">What is log4j?</h4>
-
-log4j is a tool to help the programmer output log statements to a
-variety of output targets.
-
-<p>In case of problems with an application, it is helpful to enable
-logging so that the problem can be located. With log4j it is possible
-to enable logging at runtime without modifying the application binary.
-The log4j package is designed so that log statements can remain in
-<i>shipped</i> code without incurring a high performance cost. It
-follows that the speed of logging (or rather not logging) is capital.
-
-<p>At the same time, log output can be so voluminous that it quickly
-becomes overwhelming. One of the distinctive features of log4j is the
-notion of <i>hierarchical loggers</i>. Using loggers it is
-possible to selectively control which log statements are output at
-arbitrary granularity.
-
-<p>log4j is designed with two distinct goals in mind: speed and
-flexibility. There is a tight balance between these two
-requirements. I believe that log4j strikes the right balance.
-
-<a name=reliable><h4>Is log4j a reliable logging system?</h4>
-
-No. log4j is not reliable. It is a best-effort and <em>fail-stop</em>
-logging system.
-
-<p>By fail-stop, we mean that log4j will not throw unexpected
-exceptions at run-time potentially causing your application to
-crash. <b>If for any reason, log4j throws an uncaught exception,
-please send an email to the <a
-href="mailto:log4j-user@jakarta.apache.org">log4j-user@jakarta.apache.org</a>
-mailing list</b>. Uncaught exceptions are handled as serious bugs
-requiring immediate attention.
-
-
-<p>Moreover, log4j will not revert to System.out or System.err
-when its designated output stream is not opened, is not writable or
-becomes full. This avoids corrupting an otherwise working program by
-flooding the user's terminal because logging fails. However, log4j
-will output a single message to System.err indicating that logging can
-not be performed.
-
-<a name=prerequisites><h4>What are the prerequisites for log4j?</h4>
-
-<ul>
-
- <p><li>Log4j is JDK 1.1.x compatible.
-
- <p><li>The DOMConfigurator is based on the DOM Level 1 API. The
- DOMConfigurator.configure(Element) method will work with any XML
- parser that will pass it a DOM tree.
- <p>The DOMConfigurator.configure(String filename) method and its
- variants require a JAXP compatible XML parser, for example <a
- href="http://xml.apache.org/">Xerces</a> or Sun's
- parser. Compiling the DOMConfigurator requires the presence of a
- JAXP parser in the classpath.
-
- <p><li>The <code>org.apache.log4j.net.SMTPAppender</code> relies
- on the <a href="http://java.sun.com/products/javamail/">JavaMail
- API</a>. It has been tested with JavaMail API version 1.2. The
- JavaMail API requires the <a
- href="http://java.sun.com/beans/glasgow/jaf.html">JavaBeans
- Activation Framework</a> package.
- <p><li>The <code>org.apache.log4j.net.JMSAppender</code> requires
- the presence of the JMS API as well as JNDI.
-
-
- <p><li>log4j test code relies on the <a
- href="http://www.junit.org">JUnit</a> testing framework.
-
-</ul>
-
-<a name=usageExample><h4>Is there example code for using log4j?</h4>
-
-<p>See the <code>examples/</code> directory.
-
-<a name=features><h4 id="">What are the features of log4j?</h4>
-
-<ul>
-
- <p><li>log4j is optimized for speed.
+
+
+<!-- start the processing -->
+ <!-- ====================================================================== -->
+ <!-- GENERATED FILE, DO NOT EDIT, EDIT THE XML FILE IN xdocs INSTEAD! -->
+ <!-- Main Page Section -->
+ <!-- ====================================================================== -->
+ <html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
+
+ <meta name="author" value="Ceki Gulcu">
+ <meta name="email" value="cgu@apache.org">
+
+
+
+
+ <link href="./css/site.css" rel="stylesheet" type="text/css"/>
+
+
+ <title>Log4j project - Frequently Asked Questions about log4j</title>
+ </head>
+
+ <body bgcolor="#ffffff" text="#000000" link="#525D76">
+ <!-- START Header table -->
+ <table class="banner" border="0">
+ <tr>
+ <td valign="top">
+ <a href="http://logging.apache.org/">
+ <img src="http://logging.apache.org/images/ls-logo.jpg" border="0"/>
+ </a>
+ </td>
+ <td align="right">
+ <a href="http://logging.apache.org/log4j/docs/">
+ <img src="./images/logo.jpg" alt="The log4j project" border="0"/>
+ </a>
+ </td>
+ </tr>
+ </table>
+ <!-- END Header table -->
+
+ <div class="centercol">
+ <hr noshade="" size="1"/>
+
+ <center>
+ <h2>Frequently Asked Questions about log4j</h2>
+ <h3>Ceki G�lc�, Paul Smith, Chris Taylor<br />
+ May 2002, last updated on September 15th, 2004</h3>
+ </center>
+
+
+
+ <br/>
+ <div class="index-faqSection">
+ Section 1. <a href="#1"> Generalities</a>
+ </div>
+
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 1.1</td>
+ <td><a href="#1.1">What is log4j?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 1.2</td>
+ <td><a href="#1.2">Is log4j a reliable logging system?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 1.3</td>
+ <td><a href="#1.3">What are the prerequisites for log4j?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 1.4</td>
+ <td><a href="#1.4">What are the features of log4j?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 1.5</td>
+ <td><a href="#1.5">Is there example code for using log4j?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 1.6</td>
+ <td><a href="#1.6">What documentation should I read to learn more about
+ log4j?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 1.7</td>
+ <td><a href="#1.7">Is log4j thread-safe?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 1.8</td>
+ <td><a href="#1.8">What does log output look like?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 1.9</td>
+ <td><a href="#1.9">Why should I use log4j when JDK 1.4 already ships with a
+ logging API?</a></td>
+ </table>
+ <br/>
+ <div class="index-faqSection">
+ Section 2. <a href="#2"> Using log4j</a>
+ </div>
+
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.1</td>
+ <td><a href="#2.1">What are <em>Loggers</em>?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.2</td>
+ <td><a href="#2.2">How can I change log behavior at runtime?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.3</td>
+ <td><a href="#2.3">What is the fastest way of (not) logging?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.4</td>
+ <td><a href="#2.4"> Are there any suggested ways for naming loggers?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.5</td>
+ <td><a href="#2.5">How do I get the fully-qualified name of a class in a static block?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.6</td>
+ <td><a href="#2.6">Can the log output format be customized? </a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.7</td>
+ <td><a href="#2.7">What are the configurable options for <code>FooBarAppender</code>?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.8</td>
+ <td><a href="#2.8">What is the recommended way of migrating from
+ java.util.logging to log4j?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.9</td>
+ <td><a href="#2.9">Is it possible to direct log output to
+ different appenders by level? </a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.10</td>
+ <td><a href="#2.10">What does the Windows NT Event Viewer complain about
+ missing descriptions for my event messages when I use the
+ <code>NTEventLogAppender</code>?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.11</td>
+ <td><a href="#2.11">Why can't I map my logger names to the loggers that
+ appear in the NT Event Log when I use the
+ NTEventLogAppender?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 2.12</td>
+ <td><a href="#2.12">Are there suggested approaches for logging in JSP pages?</a></td>
+ </table>
+ <br/>
+ <div class="index-faqSection">
+ Section 3. <a href="#3"> Advanced questions</a>
+ </div>
+
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 3.1</td>
+ <td><a href="#3.1">Can the outputs of multiple client request go to
+ different log files?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 3.2</td>
+ <td><a href="#3.2">Logger instances seem to be create only. Why isn't
+ there a method to remove logger instances?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 3.3</td>
+ <td><a href="#3.3">How do I get multiple process to log to the same file?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 3.4</td>
+ <td><a href="#3.4">How about the timesamps of events generated by multiple
+ processes across multiple hosts (possibly across multiple
+ timezones)?
+ </a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 3.5</td>
+ <td><a href="#3.5">Why can't log4j find my properties file in a J2EE or WAR
+ application?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 3.6</td>
+ <td><a href="#3.6">Is there a way to get log4j to automatically reload a
+ configuration file if it changes?</a></td>
+ </table>
+ <br/>
+ <div class="index-faqSection">
+ Section 4. <a href="#4"> Contributing to the project</a>
+ </div>
+
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 4.1</td>
+ <td><a href="#4.1">Why should I donate my extensions to log4j back to the
+ project?
+ </a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 4.2</td>
+ <td><a href="#4.2">What should I keep in mind when contributing code?</a></td>
+ </table>
+ <table class="index-question">
+ <td nowrap="true" valign="top">Question 4.3</td>
+ <td><a href="#4.3">How can I contribute a new question/answer to this
+ document?</a></td>
+ </table>
+ <hr/>
- <p><li>log4j is based on a named logger hierarchy.
+
+ <div class="faqSection">
+ <a name="1">Section 1.</a> Generalities
+ </div>
+
+ <p>This section contains general questions about log4j.</p>
+
+ <div class="question">
+ <a name="1.1">1.1 What is log4j?</a>
+ </div>
+
+ <p>log4j is a tool to help the programmer output log statements to a
+ variety of output targets.
+ </p>
+
+ <p>In case of problems with an application, it is helpful to
+ enable logging so that the problem can be located. With log4j
+ it is possible to enable logging at runtime without modifying
+ the application binary. The log4j package is designed so that
+ log statements can remain in <i>shipped</i> code without
+ incurring a high performance cost. It follows that the speed
+ of logging (or rather not logging) is capital.
+ </p>
+
+ <p>At the same time, log output can be so voluminous that it quickly
+ becomes overwhelming. One of the distinctive features of log4j is the
+ notion of <i>hierarchical loggers</i>. Using loggers it is
+ possible to selectively control which log statements are output at
+ arbitrary granularity.
+ </p>
+
+ <p>log4j is designed with two three goals in mind:
+ reliability, speed and flexibility. There is a tight balance
+ between these requirements. We believe that log4j strikes the
+ right balance.
+ </p>
- <p><li>log4j is fail-stop but not reliable.
-
- <p><li>log4j is thread-safe.
-
- <p><li>log4j is not restricted to a predefined set of facilities.
-
- <p><li>Logging behavior can be set at runtime using a configuration
- file. Configuration files can be property files or in XML format.
+ <div class="question">
+ <a name="1.2">1.2 Is log4j a reliable logging system?</a>
+ </div>
+
+ <p>No. log4j is not reliable. It is a best-effort
+ <em>fail-stop</em> logging system.
+ </p>
+
+ <p>By fail-stop, we mean that log4j will not throw unexpected
+ exceptions at run-time potentially causing your application to
+ crash. <b>If for any reason, log4j throws an uncaught exception,
+ please send an email to the <a href="mailto:log4j-user@logging.apache.org">log4j-user@logging.apache.org</a>
+ mailing list</b>. Uncaught exceptions are handled as serious bugs
+ requiring immediate attention.
+ </p>
+
+ <p>Moreover, log4j will not revert to System.out or System.err
+ when its designated output stream is not opened, is not writable or
+ becomes full. This avoids corrupting an otherwise working program by
+ flooding the user's terminal because logging fails. However, log4j
+ will output a single message to System.err indicating that logging can
+ not be performed.
+ </p>
- <p><li>log4j is designed to handle Java Exceptions from the start.
+ <div class="question">
+ <a name="1.3">1.3 What are the prerequisites for log4j?</a>
+ </div>
+
+ <ul>
+ <li><p>Log4j versions upto and including 1.2.8 are
+ compatible with JDK 1.1.x and later. Log4j version 1.3 will
+ be compatilble with JDK 1.2 and later.
+ </p></li>
+
+ <li><p>The DOMConfigurator is based on the DOM Level 1
+ API. The DOMConfigurator.configure(Element) method will work
+ with any XML parser that will pass it a DOM tree.
+ </p>
+ <p>The DOMConfigurator.configure(String filename) method and its
+ variants require a JAXP compatible XML parser, for example <a href="http://xml.apache.org/">Xerces</a> or Sun's
+ parser. Compiling the DOMConfigurator requires the presence of a
+ JAXP parser in the classpath.
+ </p>
+ </li>
+
+ <li><p>The <code>org.apache.log4j.net.SMTPAppender</code>
+ relies on the <a href="http://java.sun.com/products/javamail/">JavaMail
+ API</a>. It has been tested with JavaMail API version
+ 1.2. The JavaMail API requires the <a href="http://java.sun.com/beans/glasgow/jaf.html">JavaBeans
+ Activation Framework</a> package.
+ </p></li>
+
+ <li><p>The <code>org.apache.log4j.net.JMSAppender</code>
+ requires the presence of the JMS API as well as JNDI.
+ </p></li>
+
+ <li><p>log4j test code relies on the <a href="http://www.junit.org">JUnit</a> testing framework.
+ </p></li>
+ </ul>
- <p><li>log4j can direct its output to a file, the console, an
- <code>java.io.OutputStream</code>, <code>java.io.Writer</code>,
- a remote server using TCP, a remote Unix Syslog daemon, to a
- remote listener using JMS, to the NT EventLog or even send e-mail.
-
- <p><li>log4j uses 5 levels, namely DEBUG, INFO, WARN, ERROR and
- FATAL.
-
- <p><li>The format of the log output can be easily changed by
- extending the Layout class.
-
- <p><li>The target of the log output as well as the writing strategy
- can be altered by implementations of the Appender interface.
-
- <p><li>log4j supports multiple output appenders per logger.
-
- <p><li>log4j supports internationalization.
-
-</ul>
-
-<a name=thread-safety><h4 id="">Is log4j thread-safe?</h4>
-
-Yes, log4j is thread-safe.
-
-<a name=sample><h4 id="">What does log output look like?</h4>
+ <div class="question">
+ <a name="1.4">1.4 What are the features of log4j?</a>
+ </div>
+
+ <ul>
+
+ <li><p>log4j is optimized for speed.</p></li>
+
+ <li><p>log4j is based on a named logger hierarchy.</p></li>
+
+ <li><p>log4j is fail-stop. However, altough it certainly
+ strives to ensure delivery, log4j does not guarantee that
+ each log statement will be delivered to its destination.
+ </p></li>
+
+ <li><p>log4j is thread-safe.</p></li>
+
+ <li><p>log4j is not restricted to a predefined set of
+ facilities.</p></li>
+
+ <li><p>Logging behavior can be set at runtime using a
+ configuration file. Configuration files can be property
+ files or in XML format. </p></li>
+
+ <li><p>log4j is designed to handle Java Exceptions from the
+ start.</p></li>
+
+ <li><p>log4j can direct its output to a file, the console,
+ an <code>java.io.OutputStream</code>,
+ <code>java.io.Writer</code>, a remote server using TCP, a
+ remote Unix Syslog daemon, to a remote listener using JMS,
+ to the NT EventLog or even send e-mail. </p></li>
+
+ <li><p>log4j uses 6 levels, namely TRACE, DEBUG, INFO, WARN,
+ ERROR and FATAL. </p></li>
+
+ <li><p>The format of the log output can be easily changed by
+ extending the <code>Layout</code>
+ class. </p></li>
+
+ <li><p>The target of the log output as well as the writing
+ strategy can be altered by implementations of the
+ <code>Appender</code> interface. </p></li>
+
+ <li><p>log4j supports multiple output appenders per logger.
+ </p></li>
+
+ <li><p>log4j supports internationalization.</p></li>
+ </ul>
+
+ <div class="question">
+ <a name="1.5">1.5 Is there example code for using log4j?</a>
+ </div>
+
+ <p>See the <code>examples/</code> directory.</p>
+
+ <div class="question">
+ <a name="1.6">1.6 What documentation should I read to learn more about
+ log4j?</a>
+ </div>
+
+ <p>Make sure to read the <a href="manual.html">short
+ manual</a>. It is also recommended to you read <a href="https://www.qos.ch/shop/products/log4j/log4j-Manual.jsp">The complete
+ log4j manual</a> which is much more detailed and up to
+ date. Both documents were written by Ceki G�lc�.
+ </p>
+
+ <div class="question">
+ <a name="1.7">1.7 Is log4j thread-safe?</a>
+ </div>
+
+ <p>Yes, log4j is thread-safe. Log4j components are designed to
+ be used in heavily multithreaded systems.</p>
+
+ <div class="question">
+ <a name="1.8">1.8 What does log output look like?</a>
+ </div>
+
-The log output can be customized in many ways. Moreover, one can completely
-override the output format by implementing one's own Layout.
+ <p>The log output can be customized in many ways. Moreover,
+ one can completely override the output format by implementing
+ one's own Layout.
+ </p>
-<p>Here is an example output using <em>PatternLayout</em> with
-the conversion pattern <b>"%r [%t] %-5p %c{2} %x - %m%n"</b>
+ <p>Here is an example output using <em>PatternLayout</em> with
+ the conversion pattern <b>"%r [%t] %-5p %c{2} %x - %m%n"</b>
+ </p>
-<pre>
+ <pre class="screen_output">
176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order.
225 [main] INFO examples.SortAlgo - Entered the sort method.
262 [main] DEBUG SortAlgo.OUTER i=1 - Outer loop.
@@ -220,394 +415,739 @@ the conversion pattern <b>"%r [%t] %-5p %c{2} %x - %m%n"</b>
at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
at org.log4j.examples.Sort.main(Sort.java:64)
467 [main] INFO examples.Sort - Exiting main method.
-</pre>
-
-<p>The first field is the number of milliseconds elapsed since the
-start of the program. The second field is the thread outputting the
-log statement. The third field is the level of the log
-statement. The fourth field is the rightmost two components of the
-logger making the log request. The fifth field (just before the '-')
-is the <em>nested diagnostic context</em> (NDC). Note the nested diagnostic
-context may be empty as in the first two statements. The text after
-the '-' is the message of the statement.
-
-<a name=logger><h4 id="">What are <em>Loggers</em>?</h4>
-
-Lggers lie at the heart of log4j. Loggers define a hierarchy and give
-the programmer <em>run-time</em> control on which statements are
-printed or not.
-
-<p>Loggers are assigned levels. A log statement is printed
-depending on its level <em>and</em> its logger.
-
-<p>Make sure to read the <a href=manual.html>log4j manual</a>
-for more information.
-
-<a name=behavior><h4 id="">How can I change log behavior at runtime?</h4>
-
-<p>Log behavior can be set using configuration files which are parsed
-at runtime. Using configuration files the programmer can define
-loggers and set their levels.
-
-<p>The <code>PropertyConfigurator</code> defines a particular format
-of a configuration file. See also the <code>examples/Sort.java</code>
-example and associated configuration files.
-
-<p>Configuration files can be specified in XML. See
-<code>log4j.dtd</code> and
-<code>org.log4j.xml.DOMConfigurator</code> for more details.
-
-<p>See the various Layout and Appender components for specific
-configuration options.
-
-<p>In addition to configuration files, the user may disable all
-messages belonging to a set of levels. See next item.
-
-<a name=fastLogging><h4>What is the fastest way of (not) logging?</h4>
-
-<p> For some logger <code>l</code>, writing, <pre>
- l.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
-</pre>
-
-<p>incurs the cost of constructing the message parameter, that is
-converting both integer <code>i</code> and <code>entry[i]</code> to a
-String, and concatenating intermediate strings. This, regardless of
-whether the message will be logged or not.
+ </pre>
+
+ <p>The first field is the number of milliseconds elapsed since
+ the start of the program. The second field is the thread
+ outputting the log statement. The third field is the level of
+ the log statement. The fourth field is the rightmost two
+ components of the logger making the log request. The fifth
+ field (just before the '-') is the <em>nested diagnostic
+ context</em> (NDC). Note the nested diagnostic context may be
+ empty as in the first two statements. The text after the '-'
+ is the message of the statement.
+ </p>
+
+ <div class="question">
+ <a name="1.9">1.9 Why should I use log4j when JDK 1.4 already ships with a
+ logging API?</a>
+ </div>
+
+ <p>
+ Although both APIs are conceptually similar, the log4j API is
+ significantly more flexible and offers many more features, too
+ numerous to be listed here. You will discover that the
+ additional features and flexibility turn out to be
+ indispensable in the context of a mission-critical
+ application.
+ </p>
+
+ <p>The open and collaborative way in which log4j is developped
+ ensures that it continues to preserve and even widen its
+ competitive edge. At some point, input from bright developpers
+ from all over the world is bound to make a difference.
+ </p>
+
+ <div class="faqSection">
+ <a name="2">Section 2.</a> Using log4j
+ </div>
+
+ <p>This section contains answers to questions encountered while
+ using log4j.</p>
+
+ <div class="question">
+ <a name="2.1">2.1 What are <em>Loggers</em>?</a>
+ </div>
+
+ <p>Lggers lie at the heart of log4j. Loggers define a hierarchy and give
+ the programmer <em>run-time</em> control on which statements are
+ printed or not.
+ </p>
+
+ <p>Loggers are assigned levels. A log statement is printed
+ depending on its level <em>and</em> its logger.
+ </p>
+
+ <p>Make sure to read the <a href="manual.html">log4j manual</a>
+ for more information.
+ </p>
+
+ <div class="question">
+ <a name="2.2">2.2 How can I change log behavior at runtime?</a>
+ </div>
+
+ <p>Log behavior can be set using configuration files which are parsed
+ at runtime. Using configuration files the programmer can define
+ loggers and set their levels.
+ </p>
+
+ <p>The <code>PropertyConfigurator</code> defines a particular format
+ of a configuration file. See also the <code>examples/Sort.java</code>
+ example and associated configuration files.
+ </p>
+
+ <p>Configuration files can be specified in XML. See
+ <code>log4j.dtd</code> and
+ <code>org.log4j.xml.DOMConfigurator</code> for more details.
+ </p>
+
+ <p>See the various Layout and Appender components for specific
+ configuration options.
+ </p>
+
+ <p>In addition to configuration files, the user may disable all
+ messages belonging to a set of levels. See next item.
+ </p>
+
+ <div class="question">
+ <a name="2.3">2.3 What is the fastest way of (not) logging?</a>
+ </div>
+
-<p>If you are worried about speed, then write
-<pre>
+ <p> For some logger <code>l</code>, writing,
+ </p>
+
+ <pre class="source">
+ l.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
+ </pre>
+
+ <p>incurs the cost of constructing the message parameter, that is
+ converting both integer <code>i</code> and <code>entry[i]</code> to a
+ String, and concatenating intermediate strings. This, regardless of
+ whether the message will be logged or not.
+ </p>
+
+ <p>If you are worried about speed, then write</p>
+ <pre class="source">
if(l.isDebugEnabled()) {
l.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}
-</pre>
-
-<p>This way you will not incur the cost of parameter construction if
-debugging is disabled for logger <code>l</code>. On the other
-hand, if the logger is debug enabled, you will incur the cost of
-evaluating whether the logger is enabled or not, twice: once in
-<code>debugEnabled</code> and once in <code>debug</code>. This is an
-insignificant overhead since evaluating a logger takes less than 1%
-of the time it takes to actually log a statement.
-
-<a name=namingLoggers><h4>Are there any suggested ways for naming
-loggers?</a></h4>
-
-<p>Yes, there are.
-
-<p>You can name loggers by <strong>locality</strong>. It turns out
-that instantiating a logger in each class, with the logger name
-equal to the fully-qualified name of the class, is a useful and
-straightforward approach of defining loggers. This approach has
-many benefits:
+ </pre>
+
+ <p>This way you will not incur the cost of parameter
+ construction if debugging is disabled for logger
+ <code>l</code>. On the other hand, if the logger is debug
+ enabled, you will incur the cost of evaluating whether the
+ logger is enabled or not, twice: once in
+ <code>debugEnabled</code> and once in <code>debug</code>.
+ This is an insignificant overhead since evaluating a logger
+ takes less than 1% of the time it takes to actually log a
+ statement.
+ </p>
+
+ <h3>Better alternative based on message patterns</h3>
+ <p>As of log4j version 1.3, there exists a significantly more
+ convenient alternative based on message patterns. Assuming
+ <code>entry</code> is an object, you can write:
+ </p>
+
+ <p class="source">
+ l.debug("The new entry is {}.", entry);
+ </p>
+
+ <p>After evaluting whether to log or not, and only if the
+ decision is positive, will the logger instace format the
+ message and replace the '{}' pair with the string value of
+ <code>entry</code>. In other words, the paramerized form does
+ not incur the cost of parameter construction in case the log
+ statement is disabled.
+ </p>
+
+ <p>Thus, the following two lines will yield the exact same
+ output. However, the second form will perform at least 30
+ (thirty) times faster in case of a <em>disabled</em> logging
+ statement.
+ </p>
+
+ <p class="source">
+ l.debug("The new entry is "+entry+"."); <br />
+ l.debug("The new entry is {}.", entry);
+ </p>
+
+ <p>A two argument variant is also availalble. For example, you
+ can write:
+ </p>
+ <p class="source">
+ l.debug("The new entry is {}. It replaces {}.", entry, oldEntry);
+ </p>
+
+
-<ul>
- <li>It is very simple to implement.
+
+ <div class="question">
+ <a name="2.4">2.4 Are there any suggested ways for naming loggers?</a>
+ </div>
+
+
- <li>It is very simple to explain to new developers.
+ <p>Yes, there are.</p>
- <li>It automatically mirrors your application's own modular design.
+ <p>You can name loggers by <strong>locality</strong>. It turns out
+ that instantiating a logger in each class, with the logger name
+ equal to the fully-qualified name of the class, is a useful and
+ straightforward approach of defining loggers. This approach has
+ many benefits:
+ </p>
+
+ <ul>
+ <li>It is very simple to implement.</li>
+
+ <li>It is very simple to explain to new developers.</li>
+
+ <li>It automatically mirrors your application's own modular design.
+ </li>
+ <li>It can be further refined at will.</li>
+
+ <li>Printing the logger automatically gives information on the locality
+ of the log statement. </li>
+ </ul>
+
+ <p>However, this is not the only way for naming loggers. A
+ common alternative is to name loggers by <strong>functional
+ areas</strong>. For example, the "database" logger, "RMI"
+ logger, "security" logger, or the "XML" logger.
+ </p>
+
+ <p>You may choose to name loggers by functionality and
+ subcategorize by locality, as in "DATABASE.com.foo.some.package.someClass" or
+ "DATABASE.com.foo.some.other.package.someOtherClass".
+ </p>
+
+ <p><em>You are totally free in choosing the names of your
+ loggers.</em> The log4j package merely allows you to manage your
+ names in a hierarchy. However, it is your responsibility to define
+ this hierarchy.
+ </p>
+
+ <p>Note by naming loggers by locality one tends to name things by
+ functionality, since in most cases the locality relates closely to
+ functionality.
+ </p>
- <li>It can be further refined at will.
+
+ <div class="question">
+ <a name="2.5">2.5 How do I get the fully-qualified name of a class in a static block?</a>
+ </div>
+
+ <p>You can easily retrieve the fully-qualified name of a class in a
+ static block for class X, with the statement
+ <code>X.class.getName()</code>. Note that <code>X</code> is the class
+ name and not an instance. The <code>X.class</code> statement does
+ <i>not</i> create a new instance of class <code>X</code>.
+ </p>
+
+ <p>Here is the suggested usage template:</p>
- <li>Printing the logger automatically gives information on the locality
- of the log statement.
+ <pre class="source">
+package a.b.c;
-</ul>
+public class Foo {
+ final static Logger logger = Logger.getLogger(Foo.class);
+ ... other code
+}
+ </pre>
+
+ <div class="question">
+ <a name="2.6">2.6 Can the log output format be customized? </a>
+ </div>
+
+ <p>Yes, you can extend the <code>Layout</code> class to create
+ you own customized log format. Appenders can be parameterized
+ to use the layout of your choice.
+ </p>
+
+ <div class="question">
+ <a name="2.7">2.7 What are the configurable options for <code>FooBarAppender</code>?</a>
+ </div>
+
+ <p>Log4j uses JavaBeans style configuration.</p>
+
+ <p>Thus, any setter method in <code>FooBarAppender</code>
+ corresponds to a configurable option. For example, in <a href="api\org\apache\log4j\RollingFileAppender.html"><code>RollingFileAppender</code></a>
+ the <a href="api/org/apache/log4j/RollingFileAppender.html#setMaxBackupIndex(int)"><code>setMaxBackupIndex(int
+ maxBackups)</code></a> method corresponds to the
+ <code>maxBackupIndex</code> option. The first letter of the
+ option can be upper case, i.e. <code>MaxBackupIndex</code>
+ and <code>maxBackupIndex</code> are equivalent but not
+ <code>MAXBACKUPIndex</code> nor <code>mAXBackupIndex</code>.
+ </p>
+
+ <p>Layouts options are also defined by their setter methods. The same goes
+ for most other log4j components.
+ </p>
+
+ <div class="question">
+ <a name="2.8">2.8 What is the recommended way of migrating from
+ java.util.logging to log4j?</a>
+ </div>
+
+
+ <p>We suggest to just use global file search/replace. You should be able
+ to replace all the "java.util.Logger" references with
+ "org.apache.log4j.Logger", and you should be on your way.
+ </p>
+
+ <p>If you're on a Win32 platform, we recommend <a href="http://www.textpad.com/">Textpad</a>. You can use the
+ CTRL+SHIFT+O to open all *.java files from a directory including all
+ its sub-directories, and then use the search/replace function to
+ replace in all files, and then CTRL+SHIFT+S to save all. Should take
+ about 60 seconds! :)
+ </p>
+
+ <div class="question">
+ <a name="2.9">2.9 Is it possible to direct log output to
+ different appenders by level? </a>
+ </div>
+
+ <p>Yes it is. Setting the <b>Threshold</b> option of any appender
+ extending <a href="api/org/apache/log4j/AppenderSkeleton.html">AppenderSkeleton</a>,
+ (most log4j appenders extend AppenderSkeleton) to filter out all log
+ events with <em>lower</em> level than the value of the threshold
+ option.
+ </p>
+
+ <p>For example, setting the threshold of an appender to DEBUG
+ also allow INFO, WARN, ERROR and FATAL messages to log along
+ with DEBUG messages. This is usually acceptable as there is
+ little use for DEBUG messages without the surrounding INFO,
+ WARN, ERROR and FATAL messages. Similarly, setting the
+ threshold of an appender to ERROR will filter out DEBUG, INFO
+ and WARN messages but not ERROR or FATAL messages.
+ </p>
+
+ <p>This policy usually best encapsulates what the user
+ actually wants to do, as opposed to her mind-projected
+ solution.
+ </p>
+ <p>See <i>examples/sort4.lcf</i> for an example threshold
+ configuration.</p>
+
+ <p>If you must filter events by exact level match, then you can
+ attach a <a href="api/org/apache/log4j/varia/LevelMatchFilter.html">LevelMatchFilter</a>
+ to any appender to filter out logging events by exact level match.
+ </p>
-<p>However, this is not the only way for naming loggers. A common
-alternative is to name loggers by <strong>functional
-areas</strong>. For example, the "database" logger, "RMI" logger,
-"security" logger, or the "XML" logger.
+
+ <div class="question">
+ <a name="2.10">2.10 What does the Windows NT Event Viewer complain about
+ missing descriptions for my event messages when I use the
+ <code>NTEventLogAppender</code>?</a>
+ </div>
+
+ <p>The NT Event Viewer relies on <i>message resource</i> DLLs
+ to properly view an event message. The NTEventLogAppender.dll
+ contains these message resources, but that DLL must be copied
+ to %SYSTEMROOT%\SYSTEM32 for it to work properly.
+ </p>
+
+ <div class="question">
+ <a name="2.11">2.11 Why can't I map my logger names to the loggers that
+ appear in the NT Event Log when I use the
+ NTEventLogAppender?</a>
+ </div>
+
+
+ <p>Unfotunately, the logger names are hardcoded within the
+ message resource DLL (see previous question about
+ NTEventLogAppender), so there isn't any easy way to override
+ those dynamically... in fact, I don't think it's possible to
+ do it, as you'd have to modify the DLL resources for every
+ application. Since most native applications don't use the
+ Logger column anyway...
+ </p>
+
+ <div class="question">
+ <a name="2.12">2.12 Are there suggested approaches for logging in JSP pages?</a>
+ </div>
+
+ <p>
+ The suggested approach depends on your design requirements. If you or
+ your organization has no constraints on the use of Java in JSP pages,
+ simply use log4j normally in <code><% ... %></code> statements
+ as indicated in the Short Manual and the rest of the documentation.
+ </p>
+ <p>
+ However, if your design calls for a minimum amount of Java in your JSP
+ pages, consider using the
+ <a href="http://jakarta.apache.org/taglibs/doc/log-doc/intro.html">Log Taglib</a>
+ from the Jakarta Taglibs project. It provides logging JSP tags that invoke
+ log4j.
+ </p>
+
+ <div class="faqSection">
+ <a name="3">Section 3.</a> Advanced questions
+ </div>
+
+ <p>This section contains answers to more advanced questions about log4j.</p>
+
+ <div class="question">
+ <a name="3.1">3.1 Can the outputs of multiple client request go to
+ different log files?</a>
+ </div>
+
+
+ <p>Many developers are confronted with the problem of
+ distinguishing the log output originating from the same class
+ but different client requests. They come up with ingenious
+ mechanisms to fan out the log output to different files. In
+ most cases, this is not the right approach.
+ </p>
+
+ <p>It is simpler to use a nested diagnostic context
+ (NDC). Typically, one would <em>NDC.push()</em> client
+ specific information, such as the client's hostname, ID or any
+ other distinguishing information when starting to handle the
+ client's request. Thereafter, log output will automatically
+ include the nested diagnostic context so that you can
+ distinguish logs from different client requests even if they
+ are output to the same file.
+ </p>
+
+ <p>See the <code>NDC</code> and the <code>PatternLayout</code>
+ classes for more information. The <code>NumberCruncher</code>
+ example shows how the NDC can be used to distinguish the log
+ output from multiple clients even if they share the same log
+ file.
+ </p>
+
+ <p>For select applications, such as virtual hosting
+ web-servers, the NDC solution is not sufficient. As of version
+ 0.9.0, log4j supports multiple hierarchy trees. Thus, it is
+ possible to log to different targets from the same logger
+ depending on the current context.
+ </p>
-<p>You may choose to name loggers by functionality and
-subcategorize by locality, as in "DATABASE.com.foo.some.package.someClass" or
-"DATABASE.com.foo.some.other.package.someOtherClass".
+
+ <div class="question">
+ <a name="3.2">3.2 Logger instances seem to be create only. Why isn't
+ there a method to remove logger instances?</a>
+ </div>
+
+ <p>It is quite nontrivial to define the semantics of a
+ "removed" logger escecially if it is still referenced by the
+ user. Future releases <em>may</em> include a remove method in
+ the Logger class.</p>
+
+ <div class="question">
+ <a name="3.3">3.3 How do I get multiple process to log to the same file?</a>
+ </div>
+
+ <p>You may have each process log to a
+ <a href="api/org/apache/log4j/net/SocketAppender.html"><code>SocketAppender</code></a>.
+ The receiving
+ <a href="api/org/apache/log4j/net/SocketServer.html"><code>SocketServer</code></a>
+ (or
+ <a href="api/org/apache/log4j/net/SimpleSocketServer.html"><code>SimpleSocketServer</code></a>)
+ can receive all the events and send them to a single
+ log file.
+ </p>
+
+ <div class="question">
+ <a name="3.4">3.4 How about the timesamps of events generated by multiple
+ processes across multiple hosts (possibly across multiple
+ timezones)?
+ </a>
+ </div>
+
+
+ <p>The timestamp is created when the logging event is created.
+ That is so say, when the <code>debug</code>,
+ <code>info</code>, <code>warn</code>, <code>error</code> or
+ <code>fatal</code> method is invoked. Thus, the timestamp is
+ unaffected by the time at which event arrive at a remote
+ socket server.
+ </p>
+
+ <p>Timestamps are stored in UTC format inside the
+ event. Consequently, when displayed or written to a log file,
+ timestamps appear in the same timezone as the host displaying
+ or creating the logfile. Note that because the clocks of
+ various machines may not be synchronized, there may be
+ timestamp inconsistencies between events generated on
+ different hosts.
+ </p>
+
+ <div class="question">
+ <a name="3.5">3.5 Why can't log4j find my properties file in a J2EE or WAR
+ application?</a>
+ </div>
+
+
+ <p>The short answer: the log4j classes and the properties file
+ are not within the scope of the same classloader.
+ </p>
+
+ <p>The long answer (and what to do about it): J2EE or Servlet
+ containers utilize Java's class loading system. Sun changed
+ the way classloading works with the release of Java 2. In
+ Java 2, classloaders are arranged in a hierarchial
+ parent-child relationship. When a child classloader needs to
+ find a class or a resource, it first delegates the request to
+ the parent.
+ </p>
+
+ <p>Log4j only uses the default <code>Class.forName()</code>
+ mechanism for loading classes. Resources are handled
+ similarly. See the documentation for
+ <code>java.lang.ClassLoader</code> for more details.
+ </p>
+
+ <p>So, if you're having problems, try loading the class or
+ resource yourself. If you can't find it, neither will
+ log4j. ;)
+ </p>
-<p><em>You are totally free in choosing the names of your
-loggers.</em> The log4j package merely allows you to manage your
-names in a hierarchy. However, it is your responsibility to define
-this hierarchy.
+
+ <div class="question">
+ <a name="3.6">3.6 Is there a way to get log4j to automatically reload a
+ configuration file if it changes?</a>
+ </div>
+
+ <p>Yes. Both the DOMConfigurator and the PropertyConfigurator support
+ automatic reloading through the <code>configureAndWatch</code> method.
+ See the API documentation for more details.
+ </p>
+
+
+ <p>Because the <code>configureAndWatch</code> launches a
+ separate wathdog thread, and because there is no way to stop
+ this thread in log4j 1.2, the <code>configureAndWatch</code>
+ method is unsafe for use in J2EE envrironments where
+ applications are recycled.
+ </p>
+
+
+ <div class="faqSection">
+ <a name="4">Section 4.</a> Contributing to the project
+ </div>
+
+ <p>This section includes questions about contributing to the
+ project</p>
+
+ <div class="question">
+ <a name="4.1">4.1 Why should I donate my extensions to log4j back to the
+ project?
+ </a>
+ </div>
+
+ <p>Contrary to the GNU Public License (GPL) the Apache
+ Software License does not make any claims over your
+ extensions. By extensions, we mean totally new code that
+ invokes existing log4j classes. <em>You are free to do
+ whatever you wish with your proprietary log4j extensions.</em>
+ In particular, you may choose to never release your extensions
+ to the wider public.
+ </p>
+
+ <p>We are very careful not to change the log4j client API so
+ that newer log4j releases are backward compatible with
+ previous versions. We are a lot less scrupulous with the
+ internal log4j API. Thus, if your extension is designed to
+ work with log4j version <code>n</code>, then when log4j
+ release version <code>n+1</code> comes out, you will probably
+ need to adapt your proprietary extensions to the new release.
+ </p>
+
+ <p>Thus, you will be forced to spend precious resources in
+ order to keep up with log4j changes. This is commonly referred
+ to as the "stupid-tax." By donating the code and making it
+ part of the standard distribution, you save yourself the
+ unnecessary maintenance work.
+ </p>
+
+ <p>If your extensions are useful then someone will eventually
+ write an extension providing the same or very similar
+ functionality. Your development effort will be wasted. Unless
+ the proprietary log4j extension is business critical, there is
+ little reason for not donating your extensions back to the
+ project.
+ </p>
+
+ <div class="question">
+ <a name="4.2">4.2 What should I keep in mind when contributing code?</a>
+ </div>
+
+ <ol>
+
+ <li>
+ <p>Write a test case for your contribution.</p>
+
+ <p>There is nothing more irritating than finding the bugs
+ in debugging (i.e. logging) code. Writing a test case
+ takes some effort but is crucial for a widely used library
+ such as log4j. Writing a test case will go a long way in
+ earning you the respect of fellow developers. See the
+ tests/ directory for exiting test cases.
+ </p>
+ </li>
+
+
+ <li>
+ <p>Stick to the existing indentation style even if you hate it.</p>
+
+ <p>Alternating between indentation styles makes it hard to
+ understand the source code. Make it a little harder on
+ yourself but easier on others.
+ </p>
+
+ <p>Log4j has adopted a rather conservative approach by
+ following the <a href="http://java.sun.com/docs/codeconv/">Code Conventions
+ for the JavaTM Programming Language</a>. <b>We use 2 (two)
+ spaces for indentation and no tabs.</b>
+ </p>
+ </li>
+
+ <li>
+ <p>Please do not both modify the code and change the
+ indentation in a single commit.</p>
+
+ <p>If you change the code and reformat it at the same time
+ and then commit, the commit notification message will be
+ hard to read. It will contain many diffs associated with
+ the reformatting in addition to logical changes.
+ </p>
+
+ <p>If you must reformat and change the code, then perform
+ each step separately. For example, reformat the code and
+ commit. Following that, you can change the logic and
+ commit. The two steps can be performed in the reverse
+ order just as well. You can first change the logic and
+ commit and only later reformat and commit.
+ </p>
+
+ </li>
+ <li>
+ <p>Make every effort to stick to the JDK 1.1 API.</p>
+
+ <p>One of the important advantages of log4j is its
+ compatibility with JDK 1.1.x.
+ </p>
+ </li>
+
+ <li>
+ <p>Always keep it simple, small and fast when
+ possible.</p>
+
+ <p>It's all about the application not about logging.</p>
+ </li>
+
+ <li>
+ <p>Identify yourself as a contributor at the top of the
+ relevant file.
+ </p>
+ </li>
+ <li>
+ <p>Take responsibility for your code.</p>
+
+ <p>Authoring software is very much like running a marathon. It
+ takes time and endurance.
+ </p>
+ </li>
+ <li>
+ <p>Did we mention sticking with the indentation style? </p>
+ </li>
+ <li><p>Did we mention writing test cases? </p>
+ </li>
+
+ </ol>
+
+ <div class="question">
+ <a name="4.3">4.3 How can I contribute a new question/answer to this
+ document?</a>
+ </div>
+
+ <p>Log4j uses <a href="http://jakarta.apache.org/velocity/anakia.html">velocity-anakia</a>
+ to generate its web-site, including this FAQ. We have devised
+ special macros to help us automatically generate labeled
+ question/answer pairs.
+ </p>
+
+ <p>If you are not a commiter, you can simply submit your new
+ question/answer pair to the log4j-dev@logging.apache.org
+ mailing list. The committers will take it from there.
+ </p>
+
+ <p>If you are a committer, then you must edit the
+ <em>/src/xdocs/faq.xml</em> file. The format of the file
+ should be self-evident. After you have made your changes, run
+ the command
+ </p>
+ <pre class="source">ant site</pre>
+
+ <p>After the appropriate transformation, your changes should
+ appear in the file <em>/docs/faq.html</em>.
+ </p>
+
+
+
+
+ <!-- FOOTER -->
+ <div align="center"><font color="#525D76" size="-1"><em>
+ Copyright © 1999-2005, Apache Software Foundation
+ </em></font></div>
+
+ <!-- END main table -->
+
+ <!-- LEFT SIDE NAVIGATION -->
+ <!-- ============================================================ -->
+ <div class="leftcol">
+ <div class="menu_header">Log4j Project</div>
+ <div class="menu_item"> <a href="./index.html">Introduction</a>
+ </div>
+ <div class="menu_item"> <a href="./download.html">Download</a>
+ </div>
+ <div class="menu_item"> <a href="./documentation.html">Documentation</a>
+ </div>
+ <div class="menu_item"> <a href="./contactUs.html">Contact us</a>
+ </div>
+ <div class="menu_item"> <a href="./contributors.html">Contributors</a>
+ </div>
+ <div class="menu_item"> <a href="./chainsaw.html">Chainsaw</a>
+ </div>
+ <div class="menu_item"> <a href="./history.html">History</a>
+ </div>
+ <div class="menu_header">Support</div>
+ <div class="menu_item"> <a href="http://logging.apache.org/site/binindex.cgi">Binary distributions</a>
+ </div>
+ <div class="menu_item"> <a href="http://logging.apache.org/site/cvs-repositories.html">CVS Repositories</a>
+ </div>
+ <div class="menu_item"> <a href="http://logging.apache.org/site/mailing-lists.html">Mailing Lists</a>
+ </div>
+ <div class="menu_item"> <a href="http://logging.apache.org/site/bugreport.html">Bug Reporting</a>
+ </div>
+ <div class="menu_header">Related Projects</div>
+ <div class="menu_item"> <a href="http://www.slf4j.org">SLF4J</a>
+ </div>
+ <div class="menu_header">Translations</div>
+ <div class="menu_item"> <a href="http://jakarta.apache-korea.org/log4j/index.html">Korean</a>
+ </div>
+ <div class="menu_item"> <a href="http://www.ingrid.org/jajakarta/log4j/">Japanese</a>
+ </div>
+ </div>
+
-<p>Note by naming loggers by locality one tends to name things by
-functionality, since in most cases the locality relates closely to
-functionality.
+ </body>
+ </html>
+<!-- end the processing -->
-<a name=className><h4>How do I get the fully-qualified name of a class
-in a static block?</a></h4>
-<p>You can easily retrieve the fully-qualified name of a class in a
-static block for class X, with the statement
-<code>X.class.getName()</code>. Note that <code>X</code> is the class
-name and not an instance. The <code>X.class</code> statement does
-<i>not</i> create a new instance of class <code>X</code>.
-<p>Here is the suggested usage template:
-<font color=BLUE><pre>
-package a.b.c;
-public class Foo {
- static Logger logger = Logger.getLogger(Foo.class);
- ... other code
-}
-</pre></font>
-
-<a name=customLayouts><h4>Can the log output format be customized?</h4>
-
-<p>Yes. Since release 0.7.0, you can extend the <code>Layout</code>
-class to create you own customized log format. Appenders can be
-parameterized to use the layout of your choice.
-
-<a name=NDC><h4>Can the outputs of multiple client request go to
-different log files?</h4>
-
-Many developers are confronted with the problem of distinguishing the
-log output originating from the same class but different client
-requests. They come up with ingenious mechanisms to fan out the log
-output to different files. In most cases, this is not the right
-approach.
-
-<p>It is simpler to use a nested diagnostic context (NDC). Typically,
-one would <em>NDC.push()</em> client specific information, such as the
-client's hostname, ID or any other distinguishing information when
-starting to handle the client's request. Thereafter, log output will
-automatically include the nested diagnostic context so that you can
-distinguish logs from different client requests even if they are
-output to the same file.
-
-<p>See the <code>NDC</code> and the <code>PatternLayout</code> classes
-for more information. The <code>NumberCruncher</code> example shows
-how the NDC can be used to distinguish the log output from multiple
-clients even if they share the same log file.
-
-<p>For select applications, such as virtual hosting web-servers, the
-NDC solution is not sufficient. As of version 0.9.0, log4j supports
-multiple hierarchy trees. Thus, it is possible to log to different
-targets from the same logger depending on the current context.
-
-<p><a name="#options"><h4>What are the configurable options for
-FooBarAppender?</h4>
-
-Log4j uses JavaBeans style configuration.
-
-<p>Thus, any setter method in <code>FooBarAppender</code> corresponds
-to a configurable option. For example, in <a
-href="api\org\apache\log4j\RollingFileAppender.html">RollingFileAppender</a>
-the <a
-href="api/org/apache/log4j/RollingFileAppender.html#setMaxBackupIndex(int)">setMaxBackupIndex(int
-maxBackups)</a> method corresponds to the <code>maxBackupIndex</code>
-option. The first letter of the option can be upper case, i.e.
-<code>MaxBackupIndex</code> and <code>maxBackupIndex</code> are
-equivalent but not <code>MAXBACKUPIndex</code> nor
-<code>mAXBackupIndex</code>.
-
-<p>Layouts options are also defined by their setter methods. Same goes
-for most other log4j components.
-
-<!-- ------------------------------------------------------------------ -->
-
-<p><a name=rm><h4>Logger instances seem to be create only. Why isn't
-there a method to remove logger instances?</h4>
-
-It is quite nontrivial to define the semantics of a "removed" logger
-which is still referenced by the user. Future releases <em>may</em>
-include a remove method in the Logger class.
-
-<a name=filterByLevel><h4>Is it possible to direct log output to
-different appenders by level?</h4>
-
-<p>Yes it is. Setting the <b>Threshold</b> option of any appender
-extending <a
-href="api/org/apache/log4j/AppenderSkeleton.html">AppenderSkeleton</a>,
-(most log4j appenders extend AppenderSkeleton) to filter out all log
-events with <em>lower</em> level than the value of the threshold
-option.
-
-<p>For example, setting the threshold of an appender to DEBUG also
-allow INFO, WARN, ERROR and FATAL messages to log along with DEBUG
-messages. This is usually acceptable as there is little use for DEBUG
-messages without the surrounding INFO, WARN, ERROR and FATAL
-messages. Similarly, setting the threshold of an appender to ERROR
-will filter out DEBUG, INFO and WARN messages but not ERROR or FATAL
-messages.
-
-<p>This policy usually best encapsulates what the user actually wants
-to do, as opposed to her mind-projected solution.
-
-<p>See <a
-href="api/org/apache/log4j/examples/doc-files/sort4.lcf">sort4.lcf</a>
-for an example threshold configuration.
-
-<p>If you must filter events by exact level match, then you can
-attach a <a
-href="api/org/apache/log4j/varia/LevelMatchFilter.html">LevelMatchFilter</a>
-to any appender to filter out logging events by exact level match.
-
-
-<p><a name=many21><h4>How do I get multiple process to log to the same file?</h4></a>
-
-<p>You may have each process log to a
-<a href="api/org/apache/log4j/net/SocketAppender.html"><code>SocketAppender</code></a>.
-The receiving
-<a href="api/org/apache/log4j/net/SocketServer.html"><code>SocketServer</code></a>
-(or
-<a href="api/org/apache/log4j/net/SimpleSocketServer.html"><code>SimpleSocketServer</code></a>)
-can receive all the events and send them to a single
-log file.
-
-<p><a name=timestamp><h4>If I have many processes across multiple hosts
-(possibly across multiple timezones) logging to the same file using the
-method above, what happens to timestamps?</h4>
-
-<p>The timestamp is created when the logging event is created. That is
-so say, when the <code>debug</code>, <code>info</code>, <code>warn</code>,
-<code>error</code> or <code>fatal</code> method is invoked.
-This is unaffected by the time at which they may arrive at a remote
-socket server. Since the timestamps are stored in UTC format inside
-the event, they all appear in the same timezone as the host creating the
-logfile. Since the clocks of various machines may not be synchronized,
-this may account for time interval inconsistencies between events generated
-on different hosts.
-
-<p>While this is the intended behavior, it only recently became so due to
-a bug discovery between version 1.0.4 and 1.1b1. Versions 1.0.4 and before
-had their timestamp regenerated in the converter. In this case the timestamps
-seen in the log file would all appear in order, generated at the time they
-arrived at the log server host according to its local clock.
-
-<p><a name=j2ee><h4>Why can't Log4J find my properties file in a J2EE
-or WAR application?</h4>
-
-The short answer: the Log4J classes and the properties file are not
-within the scope of the same classloader.<P>
-
-The long answer (and what to do about it): J2EE or Servlet containers
-utilize Java's class loading system. Sun changed the way classloading
-works with the release of Java 2. In Java 2, classloaders are
-arranged in a hierarchial parent-child relationship. When a child
-classloader needs to find a class or a resource, it first delegates
-the request to the parent.
-
-<P>Log4J only uses the default <CODE>Class.forName()</code> mechanism
-for loading classes. Resources are handled similarly. See the
-documentation for <CODE>java.lang.ClassLoader</CODE> for more details.
-
-<P>So, if you're having problems, try loading the class or resource
-yourself. If you can't find it, neither will Log4J. ;)
-
-<P><A NAME=configureandwatch><H4>Is there a way to get Log4J to
-automatically reload a configuration file if it changes?</H4>
-
-<P>Yes. Both the DOMConfigurator and the PropertyConfigurator support
-automatic reloading through the <CODE>configureAndWatch</CODE> APIs.
-See the API documentation for more details.
-
-<P><A NAME=nteventlogproblems><H4>What does the Windows NT Event
-Viewer complain about missing descriptions for my event messages when
-I use the NTEventLogAppender?</H4>
-
-<P>The NT Event Viewer relies on <I>message resource</I> DLLs to
-properly view an event message. The NTEventLogAppender.dll contains
-these message resources, but that DLL must be copied to
-%SYSTEMROOT%\SYSTEM32 for it to work properly.
-
-
-<P><A NAME=morenteventlogproblems><H4>Why can't I map my logger names
-to the loggers that appear in the NT Event Log when I use the
-NTEventLogAppender?</H4>
-
-<P>Unfotunately, the logger names are hardcoded within the message
-resource DLL (see previous question about NTEventLogAppender), so
-there isn't any easy way to override those dynamically... in fact, I
-don't think it's possible to do it, as you'd have to modify the DLL
-resources for every application. Since most native applications don't
-use the Logger column anyway...
-
-<p><a name=tax><h4>Why should I donate my extensions to log4j back to the
-project?</h4>
-
-Contrary to the GNU Public License (GPL) the Apache Software License
-does not make any claims over your extensions. By extensions, we mean
-totally new code that invokes existing log4j classes. <em>You are free
-to do whatever you wish with your proprietary log4j extensions.</em>
-In particular, you may choose to never release your extensions to the
-wider public.
-
-<p>We are very careful not to change the log4j client API so that
-newer log4j releases are backward compatible with previous
-versions. We are a lot less scrupulous with the internal log4j
-API. Thus, if your extension is designed to work with log4j version
-<code>n</code>, then when log4j release version <code>n+1</code> comes
-out, you will probably need to adapt your proprietary extensions to
-the new release.
-
-Thus, you will be forced to spend precious resources in order to keep
-up with log4j changes. This is commonly referred to as the
-"stupid-tax." By donating the code and making it part of the standard
-distribution, you save yourself the unnecessary maintenance work.
-
-<p>If your extensions are useful then someone will eventually write an
-extension providing the same or very similar functionality. Your
-development effort will be wasted. Unless the proprietary log4j
-extension is business critical, there is little reason for not
-donating your extensions back to the project.
-
-<a name=help><h4>What should I keep in mind when contributing
-code?</h4>
-
-<ol>
-
- <li><b>Write a test case for your contribution.</b>
-
- <p>There is nothing more irritating than finding the bugs in
- debugging (i.e. logging) code. Writing a test case takes some
- effort but is crucial for a widely used library such as
- log4j. Writing a test case will go a long way in earning you the
- respect of fellow developers. See the tests/ directory for exiting
- test cases.
- </li>
- <p><li>Stick to the existing indentation style even if you hate it.
- <p>Alternating between indentation styles makes it hard to
- understand the source code. Make it hard on yourself but easier
- on others. Log4j follows the <a
- href=http://java.sun.com/docs/codeconv/>Code Conventions for
- the JavaTM Programming Language</a>.
- <p><li>Make every effort to stick to the JDK 1.1 API.
- <p>One of the important advantages of log4j is its compatibility with
- JDK 1.1.x.
-
- <p><li>Keep it simple, small and fast.
- <p>It's all about the application not about logging.
- <p><li>Identify yourself as the contributor at the top of the
- relevant file.
- <p><li>Take responsibility for your code.
-
- <p>Authoring software is like parenting. It takes many
- years to raise a child.
- <p><li>Did I mention sticking with the indentation style?
- <p><li>Did I mention writing test cases?
-
-</ol>
-<a name=download><h4>Where can I find the latest distribution of log4j?</h4>
-<p>The log4j project is hosted at <a
-href="http://jakarta.apache.org/log4j/">http://jakarta.apache.org/log4j/</a>.
-<p>
-<hr>
-</body> </html>
diff --git a/docs/HISTORY b/docs/HISTORY.txt
similarity index 91%
rename from docs/HISTORY
rename to docs/HISTORY.txt
index d20fba1..620e09f 100644
--- a/docs/HISTORY
+++ b/docs/HISTORY.txt
@@ -5,7 +5,170 @@
client code.
[***] Changes requiring important modifications to existing client code.
- April, 2002
+
+ April 28th, 2005
+
+ - Release of version 1.2.10
+
+ - Added support for the SLF4J project. The Logger class now
+ implements the ULogger interface defined by the SLF4J. See
+
+ http://www.slf4j.org
+
+ for more detailed information.
+
+ - Fixed bug #34491 whereby the class o.a.log4j.or.jms.MessageRenderer
+ would not be compiled in the build.jms target. Bug reported by Andy
+ McBride.
+
+ http://issues.apache.org/bugzilla/show_bug.cgi?id=34491
+
+ November 1st, 2004
+
+ - Release of version 1.2.9
+
+ Log4j version 1.2.9, is identical to version 1.2.8, except that
+ several key methods have been deprecated in preparation for version
+ 1.3.0, the next major release of log4j. These changes are intended to
+ enforce the rule that client code should never refer to the Category
+ class directly, but use the Logger class instead. Similarly, client
+ code should not refer to the Priority class but to the Level class
+ instead.
+
+ For a more detailed discussion, refer to the document entitled
+ preparing for log4j 1.3 at:
+
+ http://www.qos.ch/logging/preparingFor13.jsp
+
+ February 19th, 2003
+
+ - Release of version 1.2.8
+
+ - Fixed bug #11570 whereby XMLAppender would throw a
+ NullPointerException if the input message was null. Many thanks to
+ David Vandegrift for reporting the bug and to Hendrik Brummermann for
+ supplying the patch. [*]
+
+ - Fixed bug #12366 whereby various versions of Xerces would not parse
+ log4j configuration scripts expressed in XML format. [*]
+
+ - Fixed bug #14827. The "removes" buffer used in the flushBuffer() method
+ of JDBCAppender is now cleared, solving the memory leak. Thanks to John
+ Landers for reporting the bug and suggesting the fix. [*]
+
+ - Fixed bug #15599. SocketAppender now honors ReconnectionDelay of 0.
+ Many thanks to Scott Schram for reporting the bug and providing the fix. [*]
+
+ October 9th, 2002
+
+ - Release of version 1.2.7
+
+ - Log4j now searches for the file log4j.xml as well as the file
+ log4j.properties during log4j initialization. [*]
+
+ July 31st, 2002
+
+ - Release of version 1.2.6
+
+ - Addition of new options in JMSAppender and new command line arguments in
+ JMSSink. [*]
+
+ - Added new method getLoggerName() in LoggingEvent class. The
+ getLoggerName is the preferred way for accessing the logger
+ name. The public access categoryName field should not be accessed
+ directly. Similarly, added the getLevel method which is now the
+ preferred way of accessing the event's level. The public access
+ level field should not be accessed directly. The javadocs now mark
+ the categoryName and level fields as deprecated.
+
+ Modified existing appenders to comply with these new directives. [*]
+
+ - Log4j now will check if a system property named "log4j.ignoreTCL"
+ is set. If it is set, then it will ignore the Thread Context
+ ClassLoader when loading classes. This solves the irritating
+ "appender is not assignable to Appender" messages observed when
+ log4j.jar is loaded by multiple class loaders.
+
+ The error reporting for this problem was also improved. [*]
+
+ - Fixed bug #10528 whereby calling the MDC.get method with a null
+ argument would throw a NullPointerException. [*]
+
+ July 5th, 2002
+
+ - Release of version 1.2.5
+
+ - Minor changes and bug fixes in LF5. [*]
+
+ - Calling an AsyncAppender close method also closes the embedded
+ appender instances. This resolves bug #10185 submitted by Paul
+ Voutier. [*]
+
+ June 12th, 2002
+
+ - Release of version 1.2.4
+
+ - The JDBCAppender is marked as slated for replacement. Do not build
+ critical software using it.
+
+ - Added LF5 documentation and examples. Further tests are required
+ for full integration. [*]
+
+ - XMLLayout can now output messages which contain embedded CDATA
+ sections. This resolves bug #9750. Many thanks to Michael
+ A. McAngus for supplying the relevant patch. [*]
+
+ - The dispatcher thread associated with AsyncAppender is now marked
+ as a deamon thread. This resolves bug #9750. [*]
+
+ - Added missing NTEventLogAppender.dll as reported in bug #9606. [*]
+
+ - In response to bug report 9435, the log4j.dtd was changed so that
+ <log4j:event> is now made of logger and level attributes instead of
+ category and priority. Changed XMLLayout to conform to the
+ DTD. Chainsaw was changed to adapt to the XMLLayout. [*]
+
+ - Added missing LevelRangeFilter file. [*]
+
+ May 24th, 2002
+
+ - Release of version 1.2.3
+
+ - Fixed bug #9285 where the SyslogAppender would incorrectly compute
+ the length of the datagram to send to the remote syslogd host.
+ Reported by Mamoru Kadota. [*]
+
+ - Fixed bug #8505 where the stack trace of exception would not be
+ properly printed on the Compaq tru64 Unix platform. Initially
+ reported by Fabrice Claes and later by Espen H. Kolstad who also
+ provided the fix. [*]
+
+ May 22nd, 2002
+
+ - Release of version 1.2.2
+
+ - Log4j configurators take the "NULL" string value as a synonym for
+ "INHERITED". Both of these two strings are legal level values for
+ setting the level of a logger. Both values are case insensitive. [*]
+
+ - When loading component classes, log4j will now first attempt to use
+ the Thread Context Loader and if that fails, it will use
+ Class.forName. In log4j 1.2 and 1.2.1, only Class.forName was used
+ and the TCL was ignored. This change is a response to bug #9305
+ opened by Scott M. Stark. [*]
+
+ May 17th, 2002
+
+ - Release of version 1.2.1
+
+ - This minor release fixes bug #9155 reported by Nicko Cadell.
+ LoggingEvent.getMDCCopy() method now sets mdcCopyLookupRequired
+ instead of ndcLookupRequired. This bug would cause the wrong MDC
+ information to appear on a log server. It could only occur if the
+ client wrapped an AsyncAppender around a SocketAppender or if the
+ server used an AsyncAppender for its logging. [*]
+
+ May, 2002
- Release of version 1.2
diff --git a/docs/critique.html b/docs/critique.html
deleted file mode 100644
index 55c2d70..0000000
--- a/docs/critique.html
+++ /dev/null
@@ -1,294 +0,0 @@
-<HTML>
-<document>
-
-<HEAD>
-<title>JSR47 vs. log4j</title>
-</HEAD>
-
-<body>
-
-<CENTER>
-<H1>JSR47 vs. log4j</H1>
-</CENTER>
-
-<hr>
-<p>I consider it quite distasteful to criticize other people's work,
-especially in public. However, since the logging API included in JDK
-1.4 will be considered by many as the "standard", I feel compelled to
-react. I am not alone in my criticism of JSR47, Greg Davis has his own
-set of <a
-href="http://www.swzoo.org/documents/miscellaneous/jsr047/">comments</a>.
-
-<p>The JDK 1.4 logging API is a result of the <a
-href="http://jcp.org/aboutJava/communityprocess/review/jsr047/index.html">JSR47
-effort</a>, led by Graham Hamilton.
-
-<p>Before delving into the details, some historical perspective is in
-order. I am the founder of the log4j project. I participated in the
-specification of the JSR47 API, although not as an expert. In 1999, I
-was still working for IBM and could not join the experts group because
-big blue had already Chris Barlock as a member in the JSR47 experts
-group. Chris is the author of <a
-href="http://www.alphaworks.ibm.com/tech/loggingtoolkit4j">IBM's
-logging toolkit for Java</a>.
-
-<p>On the surface, his toolkit has heavily influenced the JSR47
-API. In particular, the two share the same basic components, namely
-loggers, levels, handlers and formatters. In log4j, these components
-are called categories, priorities, appenders and layouts
-respectively. Pairwise, they are identical in purpose. As such, the
-terms logger and category, level and priority, handler and appender,
-formatter and layout will be used interchangeably in the remainder of
-this document.
-
-<p>Even after a casual review it should be apparent that the log4j and
-JSR47 APIs are <em>very</em> similar. For one, they are the only
-logging APIs which are based on a named hierarchy. If you understand
-one API, then understanding the concepts of the other should be a
-breeze. There are differences however.
-
-<h2>On Parents and Children</h2>
-
-<p>In JSR47, a parent logger knows about its children but not the
-other way around. Children do not have links to their parent. For
-example, the logger named <code>"foo"</code> knows about
-<code>"foo.bar1"</code> and <code>"foo.bar2"</code>. However,
-<code>"foo.bar1"</code> has no links to its parent <code>"foo"</code>.
-
-<p>In log4j, it is exactly the other way around. A log4j category
-contains a link to its parent but a parent does not have links to its
-children.
-
-<p>At first glance, this might look like a mundane implementation
-detail but it is actually quite fundamental.
-
-<ol>
-<p><b><li>Configuration order matters</b>
-
-<p>In JSR47, when you set the level of a logger, say
-<code>wombat</code>, JSR47 traverses the tree below
-<code>wombat</code>. In other words, the levels for all the loggers
-descending from <code>wombat</code> are overwritten. This can be a
-very expensive operation for large trees. In particular, for the most
-common case where one sets the level of the root logger. However,
-performance is not the point I am trying to make.
-
-<p>In log4j, changing the priority of a category involves the change
-of a single field. Children categories dynamically inherit the
-priority of their parent by traversing the hierarchy tree upwards.
-
-<p>It follows that with JSR47 if you configure the level for logger
-"foo.bar1" before configuring the level for "foo", then the latter
-instruction will overwrite the first exactly as if the first
-instruction for configuring "foo.bar1" had never
-existed. <em>Configuration order dependence is not a show stopper but
-it is something that will bite you time and again.</em>
-
-<p>In contrast, in log4j categories can be configured in any
-order. You never have to worry about configuration order.
-
-<p><b><li>Limited inheritance</b>
-
-<p>In JSR47, a logger does not walk the hierarchy to inherit its level
-but possesses a copy of it.
-
-<p>Unfortunately, in the JSR47 API, handlers cannot be inherited
-because it would be prohibitively expensive to let each logger to
-contain a distinct Vector of all inherited handlers, especially in
-large trees.
-
-<p>To circumvent this problem by JSR47 defines global handlers. A
-logger logs to global handlers and to the handlers attached to itself
-directly. <em>It does not inherit any handlers from the
-hierarchy.</em>
-
-<p>In log4j, appenders are inherited additively from the hierarchy. A
-category will log to the appenders attached to itself as well as the
-appenders attached to its ancestors. This might not seem like much
-until the day you need handler inheritance; probably a week after you
-decide to adopt a logging API.
-
-<p>Similarly, in log4j resource bundles are inherited from the
-hierarchy. In JSR47, a resource bundle <em>must</em> be attached to
-each logger individually. There is no resource bundle inheritance in
-JSR47. In practice, this means that you have to choose between
-internationalization and the benefits of the named logger
-hierarchy. It's one or the other. This limitation is particularly
-surprising because support for internationalization is advocated as
-one of the primary advantages of the JSR47 API.
-
-</ol>
-
-<h2>Bogus Levels</h2>
-
-<p>JSR 47 defines the levels <code>ALL</code>, <code>SEVERE</code>,
-<code>WARNING</code>, <code>INFO</code>, <code>CONFIG</code>,
-<code>FINE</code>, <code>FINER</code>, <code>FINEST</code> and
-<code>OFF</code>. Experience shows that the levels <code>ALL</code>
-and <code>OFF</code> are never needed. The <code>SEVERE</code> and
-<code>CONFIG</code> levels are unique to JSR47.
-
-<p>Having three debugging levels <code>FINE</code>,
-<code>FINER</code>, <code>FINEST</code> could seem like a good
-idea. However, you will soon discover that even when by yourself, it
-is hard to decide when to use which level. It is plain impossible in
-groups.
-
-<p>Log4j in contrast has a limited but self-evident set of priorities:
-<code>FATAL</code>, <code>ERROR</code>, <code>WARN</code>,
-<code>INFO</code> and <code>DEBUG</code>.
-
-<p>Both JSR47 and log4j allow the user to extend the set of
-priorities. Log4j supports subclasses of priorities in configuration
-files as well as across the wire. JSR47 does not.
-
-<h2>Limited functionality</h2>
-
-<p>Log4j has appenders capable of logging to the console, to files, to
-Unix Syslog daemons, to Microsoft NT EventLoggers, remote servers, to
-JMS channels, automatically generate email etc. It can roll log files
-by size or date and log asynchronously.
-
-<p>JSR47 can log to the console, to files, to sockets and to a memory
-buffer.
-
-<p>Log4j has an extensible and powerful layout called the
-<code>PatternLayout</code>. JSR47 offers the much weaker
-<code>SimpleFormatter</code> as an alternative.
-
-<p>Log4j supports configuration through property files as well as XML
-documents. JSR47 currently admits only property files. Moreover, the
-language of JSR47 configuration files is very weak. In particular, you
-can only configure one instance of a given handler class. <em>This
-means that you can log to just one file at a time.</em>
-
-<h2>Other differences</h2>
-
-<p>There are many other details in which log4j differs from
-JSR47. Even if the log4j core is small, the project contains a total
-of over 30'000 lines of well-tested code. JSR47 contains about 5'000
-lines of code.
-
-<p>Log4j has been around for a number of years, enjoys the support of
-five active developers (committers) and is being used in thousands of
-projects. Our site gets over 500 downloads each and every day, and the
-numbers are on the rise. Log4j has been ported to C++ and
-Python. Companies are also offering commercial products extending
-log4j.
-
-<p>Here is a short list of opensource projects or sites that are known
-to use log4j.
-
-<ul>
-<li><a href="http://www.cryptix.org/products/sasl/">Cryptix</a>
-<li><a href="http://www.jcorporate.com/html/products/expresso/logging.html">Expresso Framework</a>
-<li><a href="http://www.free-project.org/">Free E-Democracy Project</a>
-<li><a href="http://java.freehep.org">FreeHEP</a>
-<li><a href="http://www.jboss.org">JBoss</a>
-
-<li><a href="http://www.opensymphony.com/guidelines/logging.jsp">OpenSymphony</a>
-<li><a href="http://theserverside.com">TheServerSide</a>
-<li><a href="http://jakarta.apache.org/turbine/index.html">Turbine</a>
-<li><a href="http://jakarta.apache.org/velocity/index.html">Velocity</a>
-<li><a href="http://wired2.web.cern.ch/wired2/">WIRED</a>
-
-</ul>
-
-
-<p>By the way, log4j runs fine under JDK 1.1 and above. JSR 47 will
-run under JDK 1.4 and only under JDK 1.4. Interestingly enough, no
-package shipped with JDK 1.4 is using the JSR47 API.
-
-<p>Brian R. Gilstrap has <A
-href="http://javalogging.sourceforge.net/">re-written</a> JSR47 API to
-run under JDK 1.2 and 1.3. He has also published an <a
-href="http://www.ociweb.com/jnb/archive/jnbJun2001.html">article</a>
-in JavaWorld. This is all very promising but since
-<code>java.util.logging</code> is under the <code>java.*</code>
-namespace, when running under JDK 1.3, you will systematically
-encounter:
-<pre>
-Exception in thread "main" java.lang.ExceptionInInitializerError: java.lang.SecurityException: Prohibited package name: java.util.logging
- at java.lang.ClassLoader.defineClass(ClassLoader.java:477)
- at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:111)
- at java.net.URLClassLoader.defineClass(URLClassLoader.java:248)
- at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
- at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
- at java.security.AccessController.doPrivileged(Native Method)
- at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
- at java.lang.ClassLoader.loadClass(ClassLoader.java:297)
- at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286)
- at java.lang.ClassLoader.loadClass(ClassLoader.java:253)
- at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)
-</pre>
-
-<p>Jochen Hiller had observed this problem in early 2001 when he
-implemented the JSR47 API by wrapping log4j.
-
-<p>Note that any third-party implementation using the
-<code>java.*</code> or <code>javax.*</code> namespaces violates Sun's
-trademark on Java. Without explicit permission from Sun, such software
-remains under the threat of litigation.
-
-<h2>Error Handling</h2>
-
-In JSR 47 when an error occurs then either a
-<code>RunTimeException</code> is thrown to the user or (in handlers
-only) an internal field is set. In the first case, the
-<code>RunTimeException</code> will cause your application to crash. In
-the latter case, you can retrieve the last caught exception in the
-handler by querying the <code>getException</code> method of that
-handler. <em>The former is totally unacceptable while the latter is
-impractical.</em>
-
-<p>In log4j, under no circumstances are exceptions thrown at the
-user. However, all appenders have an associated
-<code>ErrorHandler</code>. This <code>ErrorHandler</code> is invoked
-by the appender whenever a handler-specific error occurs. By default,
-log4j appenders are associated with an
-<code>OnlyOnceErrorHandler</code> which emits a message on the console
-for the first error in an appender and ignoring all following errors.
-
-<p>An <code>ErrorHandler</code> can implement an arbitrary error
-handling policy. For example, after a failure to write to a database a
-<code>JDBCAppender</code> can be redirected to fall back on a
-<code>FileAppender</code>. This functionality is supported in XML
-configuration files. You do not need to change a single line of client
-code.
-
-<p>But again who cares about errors, right?
-
-<h2>Performance</h2>
-
-<p>Logging performance must be studied in three distinct cases: when
-logging is turned off, when turned on but due to priority comparison
-logic not enabled, and when actually logging. Please refer to the <a
-href="manual.html#performance">log4j manual</a> for a more detailed
-discussion of logging performance.
-
-<p>When logging is turned on, log4j will be about two to three times
-slower to decide whether a log statement is enabled or not. This is
-due to the dynamic nature of log4j which requires it to walk the
-hierarchy. To give you an idea about the figures involved, under JDK
-1.4 beta, we are talking about 90 <em>nanoseconds</em> instead of 30
-<em>nanoseconds</em> on a 800Mhz Intel processor. In other words, one
-million disabled logging requests will cost under a second in both
-environments.
-
-<p>In a shipped binary, you can turn off logging entirely and both
-APIs will perform identically. Note that if one is not careful, the
-cost of parameter construction before invoking a disabled log
-statement will overwhelm any other performance consideration.
-Regardless of the API you decide to use, logging statements should
-never be placed in tight loops, for example, before or after an
-element swap instruction in a sort algorithm.
-
-<p>In log4j, caller localization information is optional whereas in
-JSR47 it is always extracted. Since the extraction of caller
-localization is a very slow operation, in the common case where caller
-information is not needed, log4j will log the same information 4 to
-100 times faster.
-
-
-</body>
-</HTML>
diff --git a/docs/deepExtension.html b/docs/deepExtension.html
deleted file mode 100644
index 05e0eb7..0000000
--- a/docs/deepExtension.html
+++ /dev/null
@@ -1,735 +0,0 @@
-<html>
-<head>
-<title>Extending Log4J</title>
-</head>
-
-<body bgcolor="white">
-
-<center>
-<h1>Adding Conversion Characters to PatternLayout</h1>
-
- "Paul Glezen"
-
- January 2001 <br><br>
-</center>
-
-<hr>
-<h2>Abstract</h2>
-
-<p>
-This article describes a systematic way to extend the
-<a href="http://jakarta.apache.org/log4j">log4j</a> API to include
-additional attributes formatted using the
-<code><a href="../docs/api/org/apache/log4j/PatternLayout.html">PatternLayout</a></code>
-class.
-<p>
-<hr>
-<h2>Contents</h2>
-<ul>
- <li><a href="#intro">Introduction</a>
- <ul>
- <li><a href=#case>The Case Study</a>
- <li><a href=#peek>A Peek Under the Hood</a>
- </ul>
- <li><a href="#process">The Process</a>
- <ul>
- <li><a href="#LoggingEvent">Extending <code>LoggingEvent</code></a>
- <li><a href="#PatternLayout">Extending <code>PatternLayout</code></a>
- <li><a href="#PatternParser">Extending <code>PatternParser</code> and
- <code>PatternConverter</code></a>
- <li><a href="#Category">Extending <code>Category</code></a>
- <li><a href="#CategoryFactory">Extending <code>CategoryFactory</code></a>
- </ul>
- <li><a href="#usage">Usage</a>
- <ul>
- <li><a href="#configurators">Configurators</a>
- </ul>
- <li><a href="#enhancements">Further Enhancements</a>
-</ul>
-<p>
-<hr>
-<a name="intro"><h2>Introduction</h2></a>
-
-<p>
-This article assumes familiarity with the log4j
-<a href="manual.html">User Manual</a>. It builds on fundamental
-classes described in both the User Manual and the
-<a href="api/index.html" target="_top">Javadoc API</a>. To assist in illustrating the
-concepts, a simple case study will be developed along side the
-explanations. The resulting classes may be used as a template
-for your own extensions. Condensed (i.e. statements compressed,
-comments removed) snippets of the case study code
-are included in this document.
-
-<a name="case"><h3>The Case Study</h3></a>
-The case study was developed in a CORBA environment in which the
-following information for each log entry was needed. The letters in
-parenthesis represent the corresponding character to be used by the
-<code><a href="api/org/apache/log4j/PatternLayout.html">PatternLayout</a></code>
-class for formatting.
-
-<p>
-<ul>
-<li><b>Host Name (h)</b> - the IP address or hostname of the physical machine
- on which the Category was running.
-<li><b>Server Name (s)</b> - The name of the application server process. In
- this context, a <i>server</i> refers to a process that accepts requests
- rather than referring to a machine. The term <i>host</i> refers to a
- physical machine. Several servers may run on the same host.
-<li><b>Component Name (b)</b> - Rather than getting bogged down on what
- constitutes a component, let's assume for the case study that a component
- is a unit of software worth denoting in the logs.
-<li><b>Version (v)</b> - the version of the component from which the log entry
- originated.
-</ul>
-<p>
-It seems odd to use "b" for the component name. Presently
-<code><a href="api/org/apache/log4j/PatternLayout.html">PatternLayout</a></code>
-already defines both "C" and "c" for class name and category name respectively.
-
-<h3><a name="peek">A Peek Under the Hood</a></h3>
-<p>
-In principle, if the steps described below are followed closely, there is
-not a need to understand how the extended classes will be used by log4j.
-But sometimes software development can be entirely unprincipled. You may
-wish to extend log4j in a different manner than describe here or you may
-make a mistake that requires knowledge of what is really going on. (Heaven
-forbid there be a mistake in this document). In any case, it doesn't hurt
-to get an idea of what's going on.
-<p>
-The following describes a "typical" logging scenario in the un-extended log4j
-case.
-<p>
-<ol>
-<li>Application code invokes a log request on a
-<code><a href="api/org/apache/log4j/Category.html">Category</a></code>
-object. Let's say the <code>info</code> method was invoked.
-<p>
-<li>The first thing <code>info</code> does is to check if logging has
-been turned off entirely for the info level. If so, it returns
-immediately. We'll assume for this scenario that logging has not
-been turned off for the info level.
-<p>
-<li>Next <code>info</code> compares the
-<code><a href="api/org/apache/log4j/Priority.html">Priority</a></code>
-level for this category against <code>Priority.INFO</code>. Assuming
-the priority warrants logging the message, the category instantiates a
-<code><a href="api/org/apache/log4j/spi/LoggingEvent.html">LoggingEvent</a></code>
-object populated with information available for logging.
-<p>
-<li>The <code>Category</code> instance passes the <code>LoggingEvent</code>
-instance to all its
-<code><a href="api/org/apache/log4j/Appender.html">Appender</a></code>
-implementations.
-<p>
-<li>Most (but not all) <code>Appender</code> implementations should have
-an associated subclass of
-<code><a href="api/org/apache/log4j/Layout.html">Layout</a></code>.
-The <code>Layout</code> subclass is passed the <code>LoggingEvent</code>
-instance and returns the event's information formatted in a
-<code>String</code> according to the configuration of the <code>Layout</code>.
-<p>
-When the <code>Layout</code> subclass is
-<code><a href="api/org/apache/log4j/PatternLayout.html">PatternLayout</a></code>,
-the format of the event's information is determined by a character sequence
-similar to the <b>C</b> language library's <code>printf</code> routine.
-<code>PatternLayout</code> delegates the parsing of this character sequence to a
-<code><a href="api/org/apache/log4j/helpers/PatternParser.html">PatternParser</a></code>
-instance.
-<p>
-When the <code>PatternLayout</code> was constructed, it created a
-<code>PatternParser</code> to tokenize the character sequence. Upon
-recognizing a token, the <code>PatternParser</code> constructs an appropriate
-<code><a href="api/org/apache/log4j/helpers/PatternConverter.html">PatternConverter</a></code>
-subclass, passing it formatting information from the token. Often the
-<code>PatternConverter</code> subclasses are implemented as static inner
-classes of <code>PatternParser</code>. The <code>parse</code> method of
-the <code>PatternParser</code> returns a linked list of these
-<code>PatternConverter</code> subclasses.
-<p>
-<li><code>PatternLayout.format()</code> passes the <code>LoggingEvent</code>
-to each <code>PatternConverter</code> subclass in the linked list. Each link
-in the list selects a particular item from the <code>LoggingEvent</code>,
-converts this item to a <code>String</code> in the proper format and appends
-it to a <code>StringBuffer</code>.
-<p>
-<li>The <code>format</code> method returns the resulting <code>String</code>
-to the <code>Appender</code> for output.
-</ol>
-<p>
-The above discussing involved most of the classes that we must extend or
-implement.
-<p>
-<ul>
-<li><code><a href="api/org/apache/log4j/PatternLayout.html">org.apache.log4j.PatternLayout</a></code>
-<li><code><a href="api/org/apache/log4j/Category.html">org.apache.log4j.Category</a></code>
-<li><code><a href="api/org/apache/log4j/spi/LoggerFactory.html">org.apache.log4j.spi.CategoryFactory</a></code>
-<li><code><a href="api/org/apache/log4j/spi/LoggingEvent.html">org.apache.log4j.spi.LoggingEvent</a></code>
-<li><code><a href="api/org/apache/log4j/helpers/PatternParser.html">org.apache.log4j.helpers.PatternParser</a></code>
-<li><code><a href="api/org/apache/log4j/helpers/PatternConverter.html">org.apache.log4j.helpers.PatternConverter</a></code>
-</ul>
-<p>
-<hr>
-<a name="process"><h2>The Process</h2></a>
-Below are steps required to add additional attributes available
-for logging by extending log4j. This will allow you to specify
-their output formats in the same manner as those provided by the
-<code>PatternLayout</code> class. The steps are numbered for
-reference only. It makes no difference in which order they are
-followed.
-<p>
-It's helpful if you know the attributes you wish to add and a
-<code>PatternLayout</code> symbol for each one before you begin. Be
-sure to consult the <code>PatternLayout</code> documentation to ensure
-the symbols you select are not already in use.
-<p>
-Before we dig in, I should give the standard lecture on comments.
-If the log4j library were not well documented, it would be useless
-to everyone but the log4j creators; likewise with your extensions.
-Much like eating vegetables and saving the environment, we all agree
-commenting code properly should be done. Yet it is often sacrificed
-for more immediate pleasures. We all write code faster without
-comments; especially those pesky Javadoc comments. But the reality
-is that the utility of undocumented code fades exponentially with time.
-<p>
-Since the log4j product comes with Javadoc comments together with
-the documentation it produces, it makes sense to include Javadoc
-comments in your extensions. By their very nature, logging tools
-are strong candidates for reuse. They can only be independently
-re-used if they are supported by strong documentation component.
-<p>
-This all having been said, I have elected to remove most comments from
-examples in the interest of space rather than including them to serve
-as a nagging reminder. The reader is referred to the case study source
-code files for a Javadoc version and a
-<a href="http://java.sun.com/javadoc">Javadoc website</a>
-for more information on Javadoc conventions.
-
-<a name="LoggingEvent"><h3>1. Extending <code>LoggingEvent</code></h3></a>
-
-Extending the <code>LoggingEvent</code> class should be one of the
-trivial steps. All that is needed in the extension is the addition
-of public data members representing the new attributes and a new
-constructor to populate them.
-<p>
-<table border=1>
-<tr><td>
-<pre>
-import org.apache.log4j.Category;
-import org.apache.log4j.Priority;
-import org.apache.log4j.spi.LoggingEvent;
-
-public class AppServerLoggingEvent extends LoggingEvent
- implements java.io.Serializable
-{
- public String hostname;
- public String component;
- public String server;
- public String version;
-
- public AppServerLoggingEvent( String fqnOfCategoryClass,
- AppServerCategory category,
- Priority priority,
- Object message,
- Throwable throwable)
- {
- super( fqnOfCategoryClass,
- category,
- priority,
- message,
- throwable );
-
- hostname = category.getHostname();
- component = category.getComponent();
- server = category.getServer();
- version = category.getVersion();
- }
-}
-</pre>
-</table>
-<p>
-The constructor demonstrates that in most cases, the <code>Category</code>
-subclass will contain most of the information necessary to populate
-the attributes of the <code>LoggingEvent</code> subclass. Extensions
-to <code>LoggingEvent</code> seem no more than a collection of strings
-with a constructor. Most of the work is done by the super class.
-
-<a name="PatternLayout"><h3>2. Extending <code>PatternLayout</code></h3></a>
-
-Extending the <code>PatternLayout</code> class should be another
-simple matter. The extension to <code>PatternLayout</code> should
-differ from its parent only in the creation of a
-<code>PatternParser</code> instance. The extended
-<code>PatternLayout</code> should create an extended
-<code>PatternParser</code> class. Fortunately, this task in
-<code>PatternLayout</code> is encapsulated within a single method.
-<p>
-<table border=1> <tr><td>
-<pre>
-import org.apache.log4j.PatternParser;
-import org.apache.log4j.PatternLayout;
-
-public class AppServerPatternLayout extends PatternLayout
-{
- public AppServerPatternLayout()
- {
- this(DEFAULT_CONVERSION_PATTERN);
- }
-
- public MyPatternLayout(String pattern)
- {
- super(pattern);
- }
-
- public PatternParser createPatternParser(String pattern)
- {
- PatternParser result;
- if ( pattern == null )
- result = new AppserverPatternParser( DEFAULT_CONVERSION_PATTERN );
- else
- result = new AppServerPatternParser ( pattern );
-
- return result;
- }
-}
-</pre>
-</table>
-
-<a name="PatternParser"><h3>3. Extend <code>PatternParser</code> and <code>PatternConverter</code></h3></a>
-
-Recall from our <a href="#peek">peek under the hood</a> that the
-<code>PatternParser</code> does much of its work in its
-<code>parse</code> method. The <code>PatternLayout</code> object
-instantiates a <code>PatternParser</code> object by passing it
-the pattern string. The PatternLayout then invokes the
-<code>parse</code> method of <code>PatternParser</code> to produce
-a linked list of <code>PatternConverter</code> subclass instances.
-It is this linked list of converters that is used to convert an
-event instance into a string used by appenders.
-<p>
-Our job will be to subclass <code>PatternParser</code> to properly
-interpret formatting characters we wish to add. Fortunately,
-<code>PatternParser</code> has been designed so that only the one
-step in the parsing process differing for each formatting character
-has to be overridden. The grunt work of parsing is still performed
-by the <code>PatternParser.parse()</code> method. Only the
-<code>PatternParser.finalizeConverter</code> method has to be
-overridden. This is the method that decides which
-<code>PatternConverter</code> to create based on a formatting
-character.
-<p>
-The extension to <code>PatternParser</code>,
-<code>AppServerPatternParser</code>, is similar to its super class.
-It uses
-<ul>
-<li>constants to identify the various formats
-<li>a converter defined as private static inner-classes of
- <code>AppServerPatternParser</code>.
-<li>a <code>finalizeConverter</code> method which instantiates
- the appropriate converter for a given format character.
-</ul>
-<p>
-<code>AppServerPatternParser</code> differs principally by
-dedicating a separate converter type for each logging
-attribute to be formatted.
-Rather than placing switch logic in the converter, like its
-parent class, each converter only converts one format character.
-This means the decision of which converter subclass
-to instantiate is made at layout instantiation time rather
-than in a switch statement at logging time.
-<p>
-It also differs in that the format constants are characters
-rather than integers.
-<p>
-<table border=1>
-<tr><td>
-<pre>
-import org.apache.log4j.*;
-import org.apache.log4j.helpers.FormattingInfo;
-import org.apache.log4j.helpers.PatternConverter;
-import org.apache.log4j.helpers.PatternParser;
-import org.apache.log4j.spi.LoggingEvent;
-
-public class AppServerPatternParser extends PatternParser
-{
- static final char HOSTNAME_CHAR = 'h';
- static final char SERVER_CHAR = 's';
- static final char COMPONENT_CHAR = 'b';
- static final char VERSION_CHAR = 'v';
-
- public AppServerPatternParser(String pattern)
- {
- super(pattern);
- }
-
- public void finalizeConverter(char formatChar)
- {
- PatternConverter pc = null;
- switch( formatChar )
- {
- case HOSTNAME_CHAR:
- pc = new HostnamePatternConverter( formattingInfo );
- currentLiteral.setLength(0);
- addConverter( pc );
- break;
- case SERVER_CHAR:
- pc = new ServerPatternConverter( formattingInfo );
- currentLiteral.setLength(0);
- addConverter( pc );
- break;
- case COMPONENT_CHAR:
- pc = new ComponentPatternConverter( formattingInfo );
- currentLiteral.setLength(0);
- addConverter( pc );
- break;
- case VERSION_CHAR:
- pc = new VersionPatternConverter( formattingInfo );
- currentLiteral.setLength(0);
- addConverter( pc );
- break;
- default:
- super.finalizeConverter( formatChar );
- }
- }
-
- private static abstract class AppServerPatternConverter extends PatternConverter
- {
- AppServerPatternConverter(FormattingInfo formattingInfo)
- {
- super(formattingInfo);
- }
-
- public String convert(LoggingEvent event)
- {
- String result = null;
- AppServerLoggingEvent appEvent = null;
-
- if ( event instanceof AppServerLoggingEvent )
- {
- appEvent = (AppServerLoggingEvent) event;
- result = convert( appEvent );
- }
- return result;
- }
-
- public abstract String convert( AppServerLoggingEvent event );
- }
-
- private static class HostnamePatternConverter extends AppServerPatternConverter
- {
- HostnamePatternConverter( FormattingInfo formatInfo )
- { super( formatInfo ); }
-
- public String convert( AppServerLoggingEvent event )
- { return event.hostname; }
- }
-
- private static class ServerPatternConverter extends AppServerPatternConverter
- {
- ServerPatternConverter( FormattingInfo formatInfo )
- { super( formatInfo ); }
-
- public String convert( AppServerLoggingEvent event )
- { return event.server; }
- }
-
- private static class ComponentPatternConverter extends AppServerPatternConverter
- {
- ComponentPatternConverter( FormattingInfo formatInfo )
- { super( formatInfo ); }
-
- public String convert( AppServerLoggingEvent event )
- { return event.component; }
- }
-
- private static class VersionPatternConverter extends AppServerPatternConverter
- {
- VersionPatternConverter( FormattingInfo formatInfo )
- { super( formatInfo ); }
-
- public String convert( AppServerLoggingEvent event )
- { return event.version; }
- }
-}
-</pre>
-</table>
-<p>
-<a name="Category"><h3>4. Extending <code>Category</code></h3></a>
-Extending <code>Category</code> and its factory will be more straight
-forward than extending <code>PatternParser</code> and the converters.
-The following tasks are involved in overridding
-<code>Category</code> for our purposes.
-<p>
-<ul>
-<li>Add fields corresponding to the new attributes with their
- corresponding getters and setters.
-<p>
-<li>Override the constructor to accept or acquire information
- about new attributes.
-<p>
-<li>Override the <code>forcedLog</code> method to ensure that a
- correctly populated instance of
- <code>AppServerLoggingEvent</code> is instantiated rather than
- the default <code>LoggingEvent</code>.
-<p>
-<li>Override the <code>getInstance</code> method to use our
- <code>CategoryFactory</code> (described in the next step). This will
- require that we hold a static reference to our factory and provide a
- way to initialize it.
-</ul>
-<p>
-Most of the code below is standard getter/setter verbage which has been
-somewhat abbreviated. The notable parts are in bold. We add five more
-attributes to <code>Category</code>: the four new logging attributes
-plus a static <code>AppServerCategoryFactory</code> reference. This is
-pre-initialized to an instance with attributes set to null as a
-precautionary measure. Otherwise the <code>getInstance</code> method
-will result in a null pointer exception if invoked before the
-<code>setFactory</code> method.
-<p>
-The <code>getInstance</code> method simply invokes its parent class
-method that accepts a <code>CategoryFactory</code> reference in
-addition to the category name.
-<p>
-The <code>forcedLog</code> method follows closely the corresponding
-parent class method. The most important difference is the instantiation
-of the <code>AppServerLoggingEvent</code>. A minor yet necessary
-difference is the use of the <code>getRendererMap()</code> method rather
-than accessing the data member directory as in <code>Category</code>.
-<code>Category</code> can do this because the rendererMap
-is package level accessible.
-<p>
-The <code>setFactory</code> method is provided to allow application code
-to set the factory used in the <code>getInstance</code> method.
-<p>
-<table border=1>
-<tr><td>
-<pre>
-import org.apache.log4j.Priority;
-import org.apache.log4j.Category;
-import org.apache.log4j.spi.CategoryFactory;
-import org.apache.log4j.spi.LoggingEvent;
-
-public class AppServerCategory extends Category
-{
- protected String <b>component</b>;
- protected String <b>hostname</b>;
- protected String <b>server</b>;
- protected String <b>version</b>;
- private static CategoryFactory <b>factory =
- new AppServerCategoryFactory(null, null, null)</b>;
-
- protected AppServerCategory( String categoryName,
- String hostname,
- String server,
- String component,
- String version )
- {
- super( categoryName );
- <b>instanceFQN = "org.apache.log4j.examples.appserver.AppServerCategory";</b>
-
- this.hostname = hostname;
- this.server = server;
- this.component = component;
- this.version = version;
- }
-
- public String getComponent()
- { return (component == null ) ? "" : result; }
-
- public String getHostname()
- { return ( hostname == null ) ? "" : hostname; }
-
- public static Category <b>getInstance</b>(String name)
- {
- return Category.getInstance(name, factory);
- }
-
- public String getServer()
- { return ( server == null ) ? "" : server; }
-
- public String getVersion()
- { return ( version == null ) ? "" : version; }
-
- protected void <b>forcedLog</b>( String fqn,
- Priority priority,
- Object message,
- Throwable t)
- {
-<b> LoggingEvent event = new AppServerLoggingEvent(fqn, this, priority, message, t);</b>
- callAppenders( event );
- }
-
- public void setComponent(String componentName)
- { component = componentName; }
-
- public static void <b>setFactory</b>(CategoryFactory factory)
- { AppServerCategory.factory = factory; }
-
- public void setHostname(String hostname)
- { this.hostname = hostname; }
-
- public void setServer(String serverName)
- { server = serverName; }
-
- public void setVersion(String versionName)
- { version = versionName; }
-}
-</pre>
-</table>
-<p>
-
-<a name="CategoryFactory"><h3>5. Extending <code>CategoryFactory</code></h3></a>
-
-The last step is to provide an implementation of the
-<code>CategoryFactory</code> interface that will correctly
-instantiate our <code>AppServerCategory</code> objects. It
-will obtain the hostname of the machine on which it runs using the
-<code>java.net</code> API. Aside from providing getters and
-setters for the attributes introduced, the only method to
-be implemented is the <code>makeNewCategoryInstance</code>.
-<p>
-Below is a snippet from <code>AppServerCategoryFactory</code>
-with getters, setters and comments removed.
-<p>
-<table border=1>
-<tr><td>
-<pre>
-import org.apache.log4j.Category;
-import org.apache.log4j.spi.CategoryFactory;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-public class AppServerCategoryFactory implements CategoryFactory
-{
- protected String hostname;
- protected String server;
- protected String component;
- protected String version;
- protected ResourceBundle messageBundle;
-
- protected AppServerCategoryFactory( String serverName,
- String componentName,
- String versionName )
- {
- try
- {
- hostname = java.net.InetAddress.getLocalHost().getHostName();
- }
- catch ( java.net.UnknownHostException uhe )
- {
- System.err.println("Could not determine local hostname.");
- }
-
- server = serverName;
- component = componentName;
- version = versionName;
- }
-
- public Category makeNewCategoryInstance(String name)
- {
- Category result = new AppServerCategory( name,
- hostname,
- server,
- component,
- version);
- return result;
- }
-}
-</pre>
-</table>
-<p>
-<hr>
-<a name="usage"><h2>Usage</h2></a>
-We now arrive at how to use what we have created. We must remember to
-initialize log4j by creating an instance of
-<code>AppServerCategoryFactory</code> and passing it to
-<code>AppServerCategory</code>. Once done, we can obtain a
-<code>AppServerCategoryInstance</code> anytime by using the static
-<code>getInstance</code> method of <code>AppServerCategory</code>.
-This will ensure that <code>AppServerLoggingEvent</code> instances
-are generated by the category logging methods.
-<p>
-<table border=1>
-<tr><td>
-<pre>
-import org.apache.log4j.*;
-import org.apache.log4j.appserver.AppServerCategory;
-import org.apache.log4j.appserver.AppServerCategoryFactory;
-import org.apache.log4j.appserver.AppServerPatternLayout;
-
-public class test
-{
- private static String formatString =
- "---------------------------------------------------%n" +
- "Time: %d%n" +
- "Host: %h%n" +
- "Server: %s%n" +
- "Component: %b%n" +
- "Version: %v%n" +
- "Priority: %p%n" +
- "Thread Id: %t%n" +
- "Context: %x%n" +
- "Message: %m%n";
-
- public static void main(String[] args)
- {
- AppServerCategoryFactory factory;
- factory = new AppServerCategoryFactory("MyServer", "MyComponent", "1.0");
- AppServerCategory.setFactory( factory );
- Category cat = AppServerCategory.getInstance("some.cat");
-
- PatternLayout layout = new AppServerPatternLayout( formatString );
- cat.addAppender( new FileAppender( layout, System.out) );
-
- cat.debug("This is a debug statement.");
- cat.info("This is an info statement.");
- cat.warn("This is a warning statement.");
- cat.error("This is an error statement.");
- cat.fatal("This is a fatal statement.");
- }
-}
-</pre>
-</table>
-<a name="configurators"><h3>Configurators</h3></a>
-There is one a word of caution concerning the use of configurators that
-may create <code>Category</code> instances (such as
-<a href="api/org/apache/log4j/PropertyConfigurator.html">
-<code>PropertyConfigurator</code></a>
-and
-<a href="api/org/apache/log4j/xml/DOMConfigurator.html">
-<code>DOMConfigurator</code></a>). Since these configurators do not
-know about our extensions, any <code>Category</code> instances they
-create will not be <code>AppServerCategory</code> instances. To
-prevent this problem, any <code>AppServerCategory</code> that one
-might want to be configured through a configurator should be
-instantiated before the configure method is invoked. In this way,
-the configurator will configure the <code>AppServerCategory</code>
-that already exists rather than creating an instance of its super
-class.
-<p>
-The consequence of a configurator creating the super class by
-mistake is merely that the extra attributes will not appear in
-the log output. All other attributes are conveyed properly.
-<p>
-<hr>
-<a name="enhancements"><h2>Further Enhancements</h2></a>
-There are some other directions in which this log4j extension
-may be enhanced:
-<p>
-<ol>
-<li>The hostname attribute could incorportate a formatting convention
- similar to that of class and category names whereby only a certain
- number of the more significant components are displayed. But
- whereas with class and category names, the most significant component
- is on the right, with host names, it is on the left.
-<p>
-<li>Specifying a version number could be dangerous since programmers
- are apt to change versions of the code without changing the
- string constant in the code which specifies the version. Some
- source control programs provide for insertion of a version number
- into source. For those that don't, including the version number as
- a constant is likely to lead to confusion later on. It would be
- nice to see this short-coming addressed.
-</body>
-</html>
diff --git a/docs/images/ceki-72x101.gif b/docs/images/ceki-72x101.gif
new file mode 100644
index 0000000..7c7f002
Binary files /dev/null and b/docs/images/ceki-72x101.gif differ
diff --git a/docs/images/chainsaw-fullscreen-small.jpg b/docs/images/chainsaw-fullscreen-small.jpg
new file mode 100644
index 0000000..e4de51f
Binary files /dev/null and b/docs/images/chainsaw-fullscreen-small.jpg differ
diff --git a/docs/images/chainsaw-fullscreen.jpg b/docs/images/chainsaw-fullscreen.jpg
new file mode 100644
index 0000000..14835d1
Binary files /dev/null and b/docs/images/chainsaw-fullscreen.jpg differ
diff --git a/docs/images/coverSmall.png b/docs/images/coverSmall.png
new file mode 100644
index 0000000..4b19db9
Binary files /dev/null and b/docs/images/coverSmall.png differ
diff --git a/docs/images/mark-72x99.gif b/docs/images/mark-72x99.gif
new file mode 100644
index 0000000..8d50730
Binary files /dev/null and b/docs/images/mark-72x99.gif differ
diff --git a/docs/images/psmith.jpg b/docs/images/psmith.jpg
new file mode 100644
index 0000000..edde7ad
Binary files /dev/null and b/docs/images/psmith.jpg differ
diff --git a/docs/images/yshapira.bmp b/docs/images/yshapira.bmp
new file mode 100644
index 0000000..c2f2bdd
Binary files /dev/null and b/docs/images/yshapira.bmp differ
diff --git a/docs/lf5/images/blue_on_white.gif b/docs/lf5/images/blue_on_white.gif
new file mode 100644
index 0000000..caeb5fa
Binary files /dev/null and b/docs/lf5/images/blue_on_white.gif differ
diff --git a/docs/lf5/images/console_window.gif b/docs/lf5/images/console_window.gif
new file mode 100644
index 0000000..315a7c5
Binary files /dev/null and b/docs/lf5/images/console_window.gif differ
diff --git a/docs/lf5/images/lf5.gif b/docs/lf5/images/lf5.gif
new file mode 100644
index 0000000..71c4c08
Binary files /dev/null and b/docs/lf5/images/lf5.gif differ
diff --git a/docs/lf5/images/lf5_about.gif b/docs/lf5/images/lf5_about.gif
new file mode 100644
index 0000000..206b545
Binary files /dev/null and b/docs/lf5/images/lf5_about.gif differ
diff --git a/docs/lf5/images/lf5_category_explorer.gif b/docs/lf5/images/lf5_category_explorer.gif
new file mode 100644
index 0000000..0adf254
Binary files /dev/null and b/docs/lf5/images/lf5_category_explorer.gif differ
diff --git a/docs/lf5/images/lf5_collapseall.gif b/docs/lf5/images/lf5_collapseall.gif
new file mode 100644
index 0000000..c32a665
Binary files /dev/null and b/docs/lf5/images/lf5_collapseall.gif differ
diff --git a/docs/lf5/images/lf5_colorchooser.gif b/docs/lf5/images/lf5_colorchooser.gif
new file mode 100644
index 0000000..4bb0447
Binary files /dev/null and b/docs/lf5/images/lf5_colorchooser.gif differ
diff --git a/docs/lf5/images/lf5_compactview.gif b/docs/lf5/images/lf5_compactview.gif
new file mode 100644
index 0000000..fd84c92
Binary files /dev/null and b/docs/lf5/images/lf5_compactview.gif differ
diff --git a/docs/lf5/images/lf5_configure.gif b/docs/lf5/images/lf5_configure.gif
new file mode 100644
index 0000000..5855c26
Binary files /dev/null and b/docs/lf5/images/lf5_configure.gif differ
diff --git a/docs/lf5/images/lf5_deselectall.gif b/docs/lf5/images/lf5_deselectall.gif
new file mode 100644
index 0000000..943c460
Binary files /dev/null and b/docs/lf5/images/lf5_deselectall.gif differ
diff --git a/docs/lf5/images/lf5_detailedview.gif b/docs/lf5/images/lf5_detailedview.gif
new file mode 100644
index 0000000..cc61b25
Binary files /dev/null and b/docs/lf5/images/lf5_detailedview.gif differ
diff --git a/docs/lf5/images/lf5_expandall.gif b/docs/lf5/images/lf5_expandall.gif
new file mode 100644
index 0000000..69f450c
Binary files /dev/null and b/docs/lf5/images/lf5_expandall.gif differ
diff --git a/docs/lf5/images/lf5_loglevels.gif b/docs/lf5/images/lf5_loglevels.gif
new file mode 100644
index 0000000..204a029
Binary files /dev/null and b/docs/lf5/images/lf5_loglevels.gif differ
diff --git a/docs/lf5/images/lf5_logo.gif b/docs/lf5/images/lf5_logo.gif
new file mode 100644
index 0000000..3fc62b7
Binary files /dev/null and b/docs/lf5/images/lf5_logo.gif differ
diff --git a/docs/lf5/images/lf5_logo_small.gif b/docs/lf5/images/lf5_logo_small.gif
new file mode 100644
index 0000000..c6fa96d
Binary files /dev/null and b/docs/lf5/images/lf5_logo_small.gif differ
diff --git a/docs/lf5/images/lf5_logtable.gif b/docs/lf5/images/lf5_logtable.gif
new file mode 100644
index 0000000..c804d17
Binary files /dev/null and b/docs/lf5/images/lf5_logtable.gif differ
diff --git a/docs/lf5/images/lf5_ndc_filtering.gif b/docs/lf5/images/lf5_ndc_filtering.gif
new file mode 100644
index 0000000..e44fc2f
Binary files /dev/null and b/docs/lf5/images/lf5_ndc_filtering.gif differ
diff --git a/docs/lf5/images/lf5_openfile.gif b/docs/lf5/images/lf5_openfile.gif
new file mode 100644
index 0000000..4ca07c5
Binary files /dev/null and b/docs/lf5/images/lf5_openfile.gif differ
diff --git a/docs/lf5/images/lf5_openurl.gif b/docs/lf5/images/lf5_openurl.gif
new file mode 100644
index 0000000..91a4765
Binary files /dev/null and b/docs/lf5/images/lf5_openurl.gif differ
diff --git a/docs/lf5/images/lf5_properties.gif b/docs/lf5/images/lf5_properties.gif
new file mode 100644
index 0000000..1758d1f
Binary files /dev/null and b/docs/lf5/images/lf5_properties.gif differ
diff --git a/docs/lf5/images/lf5_recorddetail.gif b/docs/lf5/images/lf5_recorddetail.gif
new file mode 100644
index 0000000..cd7c942
Binary files /dev/null and b/docs/lf5/images/lf5_recorddetail.gif differ
diff --git a/docs/lf5/images/lf5_remove_categories.gif b/docs/lf5/images/lf5_remove_categories.gif
new file mode 100644
index 0000000..0c45926
Binary files /dev/null and b/docs/lf5/images/lf5_remove_categories.gif differ
diff --git a/docs/lf5/images/lf5_search.gif b/docs/lf5/images/lf5_search.gif
new file mode 100644
index 0000000..bd218ab
Binary files /dev/null and b/docs/lf5/images/lf5_search.gif differ
diff --git a/docs/lf5/images/lf5_selectall.gif b/docs/lf5/images/lf5_selectall.gif
new file mode 100644
index 0000000..e8224a5
Binary files /dev/null and b/docs/lf5/images/lf5_selectall.gif differ
diff --git a/docs/lf5/images/lf5_small.gif b/docs/lf5/images/lf5_small.gif
new file mode 100644
index 0000000..0c6fc10
Binary files /dev/null and b/docs/lf5/images/lf5_small.gif differ
diff --git a/docs/lf5/images/lf5_standardview.gif b/docs/lf5/images/lf5_standardview.gif
new file mode 100644
index 0000000..5dffd91
Binary files /dev/null and b/docs/lf5/images/lf5_standardview.gif differ
diff --git a/docs/lf5/images/lf5_view.gif b/docs/lf5/images/lf5_view.gif
new file mode 100644
index 0000000..dace2eb
Binary files /dev/null and b/docs/lf5/images/lf5_view.gif differ
diff --git a/docs/lf5/images/small_right_arrow.gif b/docs/lf5/images/small_right_arrow.gif
new file mode 100644
index 0000000..deca2b4
Binary files /dev/null and b/docs/lf5/images/small_right_arrow.gif differ
diff --git a/docs/manual.html b/docs/manual.html
index 50c5331..db910d5 100644
--- a/docs/manual.html
+++ b/docs/manual.html
@@ -22,12 +22,12 @@
distribution. This document is based on the article <a
href="http://www.javaworld.com/jw-11-2000/jw-1122-log4j.html">"Log4j
delivers control over logging"</a> published in November 2000
- edition of <a
- href="http://www.javaworld.com">JavaWorld</a>. However, the
- present article contains more detailed and up to date
- information. The short manual also borrows some text from the
- book "log4j: the Manual" by the same author (yours truly).
-
+ edition of JavaWorld. However, the present article contains more
+ detailed and up to date information. The present short manual
+ also borrows some text from <a
+ href="https://www.qos.ch/shop/products/eclm/">"<em>The
+ complete log4j manual</em>"</a> by the same author (yours
+ truly).
<h2>Abstract</h2>
@@ -52,9 +52,9 @@ fully-fledged open source license certified by the <a
href="http://www.opensource.org">open source</a> initiative. The
latest log4j version, including full-source code, class files and
documentation can be found at <a
-href="http://jakarta.apache.org/log4j/"><b>http://jakarta.apache.org/log4j/</b></a>.
-By the way, log4j has been ported to the C, C++, C#, Python, Ruby, and
-Eiffel languages.
+href="http://logging.apache.org/log4j/"><b>http://logging.apache.org/log4j/</b></a>.
+By the way, log4j has been ported to the C, C++, C#, Perl, Python,
+Ruby, and Eiffel languages.
<p>Inserting log statements into code is a low-tech method for
debugging it. It may also be the only way because debuggers are not
@@ -70,7 +70,7 @@ to be studied at a later time. In addition to its use in the
development cycle, a sufficiently rich logging package can also be
viewed as an auditing tool.
-<p>As Brian W. Kernigan and Rob Pike put it in their truly excellent
+<p>As Brian W. Kernighan and Rob Pike put it in their truly excellent
book <i>"The Practice of Programming"</i>
<pre>
As personal choice, we tend not to use debuggers beyond getting a
@@ -90,7 +90,7 @@ book <i>"The Practice of Programming"</i>
application. If too verbose, it can cause scrolling blindness. To
alleviate these concerns, log4j is designed to be reliable, fast and
extensible. Since logging is rarely the main focus of an application,
-log4j API strives to be simple to understand and to use.
+the log4j API strives to be simple to understand and to use.
<h2>Loggers, Appenders and Layouts</h2>
@@ -114,13 +114,13 @@ has replaced the <code>Category</code> class. For those familiar with
earlier versions of log4j, the <code>Logger</code> class can be
considered as a mere alias to the <code>Category</code> class.
-<p> Loggers are named entities. Logger names are case-sensitive and
+<p>Loggers are named entities. Logger names are case-sensitive and
they follow the hierarchical naming rule:
<p>
<table bgcolor="#EEEE99">
<tr>
- <td>
+ <td>
<dl>
<dt><b>Named Hierarchy</b>
@@ -142,11 +142,11 @@ ancestor of <code>"java.util.Vector"</code>. This naming scheme
should be familiar to most developers.
<p>The root logger resides at the top of the logger hierarchy. It
-is exceptional in two ways:
+is exceptional in two ways:
<ol>
<li> it always exists,
-<li> it cannot be retrieved by name.
+<li> it cannot be retrieved by name.
</ol>
<p>Invoking the class static <a
href="api/org/apache/log4j/Logger.html#getRootLogger()">Logger.getRootLogger</a>
@@ -162,18 +162,19 @@ below.
<td>
<pre>
package org.apache.log4j;
-
+
public class <b>Logger</b> {
-
+
// Creation & retrieval methods:
public static Logger getRootLogger();
public static Logger getLogger(String name);
-
+
// printing methods:
public void debug(Object message);
public void info(Object message);
public void warn(Object message);
public void error(Object message);
+ public void fatal(Object message);
// generic printing method:
public void log(Level l, Object message);
@@ -183,19 +184,19 @@ below.
</table>
<p>Loggers <em>may</em> be assigned levels. The set of possible
-levels, that is
+levels, that is
-<a href="api/org/apache/log4j/Level.html#DEBUG">DEBUG</a>,
-<a href="api/org/apache/log4j/Level.html#INFO">INFO</a>,
-<a href="api/org/apache/log4j/Level.html#WARN">WARN</a>,
-<a href="api/org/apache/log4j/Level.html#ERROR">ERROR</a> and
-<a href="api/org/apache/log4j/Level.html#FATAL">FATAL</a>
+<a href="api/org/apache/log4j/Level.html#DEBUG">DEBUG</a>,
+<a href="api/org/apache/log4j/Level.html#INFO">INFO</a>,
+<a href="api/org/apache/log4j/Level.html#WARN">WARN</a>,
+<a href="api/org/apache/log4j/Level.html#ERROR">ERROR</a> and
+<a href="api/org/apache/log4j/Level.html#FATAL">FATAL</a>
are defined in the <code><a
href="api/org/apache/log4j/Level.html">org.apache.log4j.Level</a></code>
-class. Although we do not encourage you from doing so, you may define
+class. Although we do not encourage you to do so, you may define
your own levels by sub-classing the <code>Level</code> class. A
-perhaps better approach is will be explained later on.
+perhaps better approach will be explained later on.
<p>If a given logger is not assigned a level, then it inherits
one from its closest ancestor with an assigned level. More
@@ -205,7 +206,7 @@ formally:
<p>
<table bgcolor="#EEEE99">
<tr>
- <td>
+ <td>
<dl>
<dt><b>Level Inheritance</b>
@@ -231,10 +232,10 @@ resulting inherited levels according to the above rule.
<tr align=left><td>X </td> <td>none</td> <td>Proot</td></tr>
<tr align=left><td>X.Y </td> <td>none</td> <td>Proot</td></tr>
<tr align=left><td>X.Y.Z</td> <td>none</td> <td>Proot</td></tr>
- <caption align=bottom>Example 1</caption>
+ <caption align=bottom>Example 1</caption>
</table>
-<p>In example 1 above, only the root logger is assinged a
+<p>In example 1 above, only the root logger is assigned a
level. This level value, <code>Proot</code>, is inherited by the
other loggers <code>X</code>, <code>X.Y</code> and
<code>X.Y.Z</code>.
@@ -288,17 +289,17 @@ having an assigned level..
<p>Logging requests are made by invoking one of the printing methods
-of a logger instance. These printing methods are
+of a logger instance. These printing methods are
<code>
<a href="api/org/apache/log4j/Logger.html#debug(java.lang.Object)">debug</a>,
-<a href="api/org/apache/log4j/Logger.html#info(java.lang.Object)">info</a>,
+<a href="api/org/apache/log4j/Logger.html#info(java.lang.Object)">info</a>,
-<a href="api/org/apache/log4j/Logger.html#warn(java.lang.Object)">warn</a>,
+<a href="api/org/apache/log4j/Logger.html#warn(java.lang.Object)">warn</a>,
<a href="api/org/apache/log4j/Logger.html#error(java.lang.Object)">error</a>,
<a href="api/org/apache/log4j/Logger.html#fatal(java.lang.Object)">fatal</a>
- and <a href="api/org/apache/log4j/Logger.html#log(org.apache.log4j.Level, java.lang.Object)">log</a></code>.
+ and <a href="api/org/apache/log4j/Logger.html#log(org.apache.log4j.Level, java.lang.Object)">log</a></code>.
<p>By definition, the printing method determines the level of a
@@ -321,8 +322,8 @@ summarized below.
<dt><b>Basic Selection Rule</b>
<dd><p>A log request of level <i>p</i> in a logger with
- inherited level <i>q</i>, is enabled if <i> p >=
- q</i>.
+ (either assigned or inherited, whichever is appropriate) level <i>q</i>, is enabled if <i> p >=
+ q</i>.
</dl>
</table>
@@ -330,7 +331,7 @@ summarized below.
ordered. For the standard levels, we have <code>DEBUG < INFO
< WARN < ERROR < FATAL</code>.
-<p>Here is an example of this rule.
+<p>Here is an example of this rule.
<p><table bgcolor="CCCCCC">
<tr><td>
@@ -339,35 +340,35 @@ ordered. For the standard levels, we have <code>DEBUG < INFO
// get a logger instance named "com.foo"
Logger logger = Logger.getLogger(<strong>"com.foo"</strong>);
- // Now set its level. Normally you do not need to set the
- // level of a logger progamitcally. This is usually done
+ // Now set its level. Normally you do not need to set the
+ // level of a logger programmatically. This is usually done
// in configuration files.
<strong>logger</strong>.setLevel(<font
color="0000AA"><strong>Level.INFO</strong></font>);
Logger barlogger = Logger.getLogger(<strong>"com.foo.Bar"</strong>);
-
+
// This request is enabled, because <font color="00AA00"><strong>WARN</strong></font> >= <font color="0000AA"><strong>INFO</strong></font>.
logger.<font color="00AA00"><strong>warn</strong></font>("Low fuel level.");
-
+
// This request is disabled, because <font color="00AA00"><strong>DEBUG</strong></font> < <font color="0000AA"><strong>INFO</strong></font>.
- logger.<font color="00AA00"><strong>debug</strong></font>("Starting search for nearest gas station.");
-
+ logger.<font color="00AA00"><strong>debug</strong></font>("Starting search for nearest gas station.");
+
// The logger instance barlogger, named "com.foo.Bar",
- // will inherit its level from the logger named
- // "com.foo" Thus, the following request is enabled
- // because <font color="00AA00"><strong>INFO</strong></font> >= <font color="0000AA"><strong>INFO</strong></font>.
- barlogger.<font color="00AA00"><strong>info</strong></font>("Located nearest gas station.");
+ // will inherit its level from the logger named
+ // "com.foo" Thus, the following request is enabled
+ // because <font color="00AA00"><strong>INFO</strong></font> >= <font color="0000AA"><strong>INFO</strong></font>.
+ barlogger.<font color="00AA00"><strong>info</strong></font>("Located nearest gas station.");
// This request is disabled, because <font color="00AA00"><strong>DEBUG</strong></font> < <font color="0000AA"><strong>INFO</strong></font>.
- barlogger.<font color="00AA00"><strong>debug</strong></font>("Exiting gas station search");
+ barlogger.<font color="00AA00"><strong>debug</strong></font>("Exiting gas station search");
</pre>
-</table>
+</table>
<p>Calling the <code>getLogger</code> method with the same name will
-always return a reference to the exact same logger object.
+always return a reference to the exact same logger object.
-<p>For example, in
+<p>For example, in
<table bgcolor="CCCCCC">
<tr><td>
@@ -422,7 +423,7 @@ href="api/org/apache/log4j/net/JMSAppender.html">JMS</a>,
Event Loggers</a>, and remote UNIX <a
href="api/org/apache/log4j/net/SyslogAppender.html">Syslog</a>
daemons. It is also possible to log <a href="api/org/apache/log4j/AsyncAppender.html">asynchronously</a>.
-
+
<p>More than one appender can be attached to a logger.
<p>The <a
@@ -486,14 +487,14 @@ the additivity flag</a> to <code>false</code>.
<tr><td>x.y <td>none <td>true <td>A1, A-x1, A-x2
<td>Appenders of "x" and root.
-<tr><td>x.y.z <td>A-xyz1 <td>true <td>A1, A-x1, A-x2, A-xyz1
+<tr><td>x.y.z <td>A-xyz1 <td>true <td>A1, A-x1, A-x2, A-xyz1
<td>Appenders in "x.y.z", "x" and root.
-<tr><td>security <td>A-sec <td><font color="blue">false</font>
+<tr><td>security <td>A-sec <td><font color="blue">false</font>
<td>A-sec
<td>No appender accumulation since the additivity flag is set to
- <code>false</code>.
+ <code>false</code>.
<tr><td>security.access <td>none <td> true <td> A-sec <td>Only
appenders of "security" because the additivity flag in "security" is
@@ -507,7 +508,7 @@ destination but also the output format. This is accomplished by
associating a <em>layout</em> with an appender. The layout is
responsible for formatting the logging request according to the user's
wishes, whereas an appender takes care of sending the formatted output
-to its destination.
+to its destination.
The <a
href="api/org/apache/log4j/PatternLayout.html">PatternLayout</a>, part
@@ -533,7 +534,7 @@ message according to user specified criteria. For example, if you
frequently need to log <code>Oranges</code>, an object type used in
your current project, then you can register an
<code>OrangeRenderer</code> that will be invoked whenever an orange
-needs to be logged.
+needs to be logged.
<p>Object rendering follows the class hierarchy. For example, assuming
oranges are fruits, if you register an <code>FruitRenderer</code>, all
@@ -570,7 +571,7 @@ imaginary application <code>MyApp</code> that uses log4j.
// Import log4j classes.
<b>import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;</b>
-
+
public class MyApp {
// Define a static logger variable so that it references the
@@ -585,7 +586,7 @@ imaginary application <code>MyApp</code> that uses log4j.
logger.info("Entering application.");
Bar bar = new Bar();
bar.doIt();
- logger.info("Exiting application.");
+ logger.info("Exiting application.");
}
}
</pre>
@@ -603,12 +604,12 @@ package <code>com.foo</code>.
<pre>
<b>package com.foo;</b>
import org.apache.log4j.Logger;
-
+
public class Bar {
<strong>static</strong> Logger logger = <strong>Logger.getLogger(Bar.class);</strong>
-
+
public void doIt() {
- logger.debug("Did it again!");
+ logger.debug("Did it again!");
}
}
</pre>
@@ -624,7 +625,7 @@ href="api/org/apache/log4j/PatternLayout.html">PatternLayout</a> set
to the pattern "%-4r [%t] %-5p %c %x - %m%n".
<p>Note that by default, the root logger is assigned to
-<code>Level.DEBUG</code>.
+<code>Level.DEBUG</code>.
<p>The output of MyApp is:
<pre>
@@ -635,7 +636,7 @@ to the pattern "%-4r [%t] %-5p %c %x - %m%n".
<p>The figure below depicts the object diagram of <code>MyApp</code>
after just having called the <code>BasicConfigurator.configure</code>
-method.
+method.
<p>
<center>
@@ -658,7 +659,7 @@ retrieve the loggers they wish to use, and log away.
<p>The previous example always outputs the same log information.
Fortunately, it is easy to modify <code>MyApp</code> so that the log
output can be controlled at run-time. Here is a slightly modified
-version.
+version.
<p><table bgcolor="CCCCCC"><tr><td>
<pre>
@@ -666,21 +667,21 @@ version.
import org.apache.log4j.Logger;
<b>import org.apache.log4j.PropertyConfigurator;</b>
-
+
public class MyApp {
static Logger logger = Logger.getLogger(MyApp.class.getName());
public static void main(String[] args) {
-
+
// BasicConfigurator replaced with PropertyConfigurator.
<strong>PropertyConfigurator.configure(args[0]);</strong>
logger.info("Entering application.");
Bar bar = new Bar();
bar.doIt();
- logger.info("Exiting application.");
+ logger.info("Exiting application.");
}
}
</pre>
@@ -697,10 +698,10 @@ output as the previous <code>BasicConfigurator</code> based example.
<pre>
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1
-
-# A1 is set to be a ConsoleAppender.
+
+# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender
-
+
# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
@@ -721,10 +722,10 @@ configuration file shows one possible way of achieving this.
log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-
+
# <strong>Print the date in ISO 8601 format</strong>
log4j.appender.A1.layout.ConversionPattern=<strong>%d</strong> [%t] %-5p %c - %m%n
-
+
# Print only messages of level WARN or above in the package com.foo.
<strong>log4j.logger.com.foo=WARN</strong>
</pre>
@@ -813,13 +814,13 @@ control of a web-server.
<ol>
- <li>Skip default initialization if the system property
- <b>log4j.defaultInitOverride</b> is set to any value other than
- "false".
+ <li>Setting the <b>log4j.defaultInitOverride</b> system property to
+ any other value then "false" will cause log4j to skip the default
+ initialization procedure (this procedure).
<p><li>Set the <code>resource</code> string variable to the value of
the <b>log4j.configuration</b> system property. <em>The preferred
- way to specify the default initialization file is thourough the
+ way to specify the default initialization file is through the
<b>log4j.configuration</b> system property.</em> In case the system
property <b>log4j.configuration</b> is not defined, then set the
string variable <code>resource</code> to its default value
@@ -932,7 +933,7 @@ web-application.
tells log4j to use the file <code>c:\foobar.lcf</code> as the default
configuration file. The configuration file is fully specified by the
URL <code>file:/c:/foobar.lcf</code>. Thus, the same configuration
-file will be used for all web-applications.
+file will be used for all web-applications.
<p>Different web-applications will load the log4j classes through
@@ -963,9 +964,9 @@ import java.io.PrintWriter;
import java.io.IOException;
public class Log4jInit extends HttpServlet {
-
+
public
- void <b>init()</b> {
+ void <b>init()</b> {
String prefix = getServletContext().getRealPath("/");
String file = getInitParameter("log4j-init-file");
// if the log4j-init-file is not set, then no point in trying
@@ -1029,19 +1030,19 @@ user pushes contextual information into the NDC, the abbreviation of
<em>Nested Diagnostic Context</em>. The NDC class is shown below.
<pre>
- public class NDC {
- // Used when printing the diagnostic
- public <strong>static</strong> String get();
-
+ public class NDC {
+ // Used when printing the diagnostic
+ public <strong>static</strong> String get();
+
// Remove the top of the context from the NDC.
- public <strong>static</strong> String pop();
-
+ public <strong>static</strong> String pop();
+
// Add diagnostic context for the current thread.
- public <strong>static</strong> void push(String message);
-
- // Remove the diagnostic context for this thread.
- public <strong>static</strong> void remove();
- }
+ public <strong>static</strong> void push(String message);
+
+ // Remove the diagnostic context for this thread.
+ public <strong>static</strong> void remove();
+ }
</pre>
<p>The NDC is managed per thread as a <em>stack</em> of contextual
@@ -1096,7 +1097,7 @@ claims to be fast and flexible: speed first, flexibility second.
machine this cost is typically in the 5 to 50 nanosecond range.
<p>However, The method invocation involves the "hidden" cost of
- parameter construction.
+ parameter construction.
<p>For example, for some logger <code>cat</code>, writing,
<pre>
@@ -1113,12 +1114,12 @@ claims to be fast and flexible: speed first, flexibility second.
<p>To avoid the parameter construction cost write:
- <pre>
+ <pre>
if(logger.isDebugEnabled() {
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}
</pre>
-
+
<p>This will not incur the cost of parameter
construction if debugging is disabled. On the other hand, if
the logger is debug-enabled, it will incur twice the cost of
@@ -1127,7 +1128,7 @@ claims to be fast and flexible: speed first, flexibility second.
<code>debug</code>. This is an insignificant
overhead because evaluating a logger takes about 1%
of the time it takes to actually log.
-
+
<p>In log4j, logging requests are made to instances of the Logger
class. Logger is a class and not an interface. This measurably
reduces the cost of method invocation at the cost of some
diff --git a/docs/overview.html b/docs/overview.html
index 40efccd..1dbe3ee 100644
--- a/docs/overview.html
+++ b/docs/overview.html
@@ -7,5 +7,6 @@
<p>Make sure to read the <a href="../manual.html"><b>user manual</b></a>
in addition to this javadoc documentation.
+</p>
</body> </html>
diff --git a/docs/praise.html b/docs/praise.html
deleted file mode 100755
index e6d10d0..0000000
--- a/docs/praise.html
+++ /dev/null
@@ -1,266 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html> <head>
-<title>Praise from log4j users</title>
-</head>
-
-<body bgcolor="white">
-<h2>Praise from log4j users</h2>
-
-<hr><blockquote>
-Log4J was named as a finalist in the "Most Useful New or Revised Java API/Technology"
-category, and Tomcat 3.2 was named as a finalist in the "Most Innovative Java Product" category.
-</blockquote>
-<p align=right><a href="http://www.javaworld.com" target="_blank">JavaWorld</a>, April 2001
-
-<hr><blockquote>
-<p>Log4j is an incredibly well designed and functional logging tool. I
-caught the religion last summer and with every project I work on, most
-everyone agrees it's a must know/have tool. Previously I was using
-another Java logging library developed internally within my company
-which I liked. I had no desire to learn another but did so for the
-sake of due diligence. Log4j has the following features which set it
-apart from others I have seen.
-
-<p><b>Highly configurable</b> - the ability to configure the
-properties of your loggers (called Categories in log4j) from within a
-property file is indispensible. This allows you to change the
-characteristics of your logging without changing code. You can change
-the logging level, the format of the output and the output targets
-very easily. One can also use XML files (though I haven't).
-
-<p><b>Unobtrusive</b> - I'm finishing a project where we started using another
-logging tool. The log statements were clumsily long and required using
-predefined constants that were hard to remember. When writing the
-initial code, "System.out.println" was so much easier to type that
-people did this for tracing with the best of intentions to place
-legitimate logging in later. You know the story. It never
-happened. Log4j statements are shorter than "System.out.println"
-statements. This encourages people to actually use it rather than
-simply agreeing to.
-
-<p><b>Easy configuration</b> - With just one statement, log4j will
-configure itself with a set of defaults that are useful until you get
-around to actually writing your property file, XML file or
-whatever. Like the point just made before, this allows log4j to be
-used at the outset of coding rather than having to wait because you
-haven't considered how you wish logging to be configured. The
-application code itself does not have to know how logging will be
-configured.
-
-<p><b>Performance Concerns</b> - Since Java does not use pre-processor
-macros, most Java tracing is always compiled into the code. That means
-that the decision to compile is made at runtime. There are times when
-performance is so paramount that even checking whether to log is a
-concern. There are other extremes where other delays make this
-insignificant so that the performance is easily sacrificed for the
-increased amount of information logged (such as method name, class
-name and line number in source code). The log4j javadoc documentation
-explains which information elements are quickly logged and which may
-compromise performance. It also includes benchmarks that demonstrate
-how fast certain statements are logged for a few sample machine
-configurations.
-
-<p><b>Hierarchical Categories</b> - This is highly useful in component
-based development. Each component has its own set of logging
-categories. When individually tested, the properties of these
-categories may be set however the developer wishes. When combined with
-other components, the categories inherit the properties determined by
-the integrator of the components. One can selectively elevate logging
-priorities on one component without affecting the other
-components. This is useful when you need a detailed trace from just a
-single component without crowding the trace file with messages from
-other components. All this can be done with property files - no change
-in the code is required.
-
-<p><b>Easily specified output format</b> - Some Java and OO purist
-disagree with me on this, but allowing one to use printf-style output
-format specification is powerful, convenient and compact. Log4j
-provides a Layout class with this capability. Of course, for those who
-wish, you may implement the Layout interface yourself with something
-"more OO". Naturally, the printf-style pattern can be specified in a
-property file.
-
-<p><b>Customization</b> - Like other loggers, log4j is interface-based
-making it possible to extend. Log4j supplies useful implementations
-that are extended easily without having to implement the interface
-from scratch.
-</blockquote>
-
-<p align=right>Paul Glezen (pglezen at atdial.net), December 3rd, 2000
-
-<hr><blockquote>
-This Java package is probably one of the best and most reliable packages
-around, and really helps development and maintenance of quality software.
-Thanks to all contributors who have made such a good work.
-</blockquote>
-
-<p align=right>Denis Balazuc (denis.balazuc at trader.com), December 8th, 2000
-
-<hr><blockquote> This is just a quick note of thanks for publishing
-your article in Javaworld. Log4j is really easy to use. While I was
-initially skeptical of the idea, code like this makes me a believer in
-the concept of Open Source.
-</blockquote>
-
-<p align=right>Paul Hyndman (PaulHyndman at mynd.com), November 29th, 2000
-
-<hr><blockquote>
-I just recently became aware of log4j and am just now begining to use
-it. I want to thank you and the rest of the log4j development team for
-making this functionality available. You are providing an outstanding
-service to the development community. Please pass my regards on to the
-other team members.
-</blockquote>
-
-<p align=right>Rich Coco (racoco at celoxnetworks.com), November 16th, 2000
-
-
-
-<hr><blockquote>
-
-Just thought I'd let you know that I am using your log4j as a part of
-an e-commerce application (<a
-href="http://www.consumerd.com">www.consumerd.com</a>). I am using
-the XML configuration classes and have to say that I am most
-impressed.
-</blockquote>
-
-<p align=right>Richard King (Richard.King at capgemini.co.uk), October 25th, 2000
-
-<hr><blockquote>
-
-You should see what we've used log4j for at work... I put together
-this Servlet that can interpret SOAP messages and invoke little
-"handlers". Logging is pervasive through out the system, and the
-handler developers can "create" their own Categories dynamically using
-the getInstance method of Category.
-
-<p>It's funny when I get an email from someone at work who's using the
-toolkit with a "it didn't work" question, and I ask them to check out
-the log... due to the coolness of log4j, they can track down their
-mistake immediately.
-
-</blockquote>
-<p align=right>Christopher Taylor (cstaylor at pacbell.net), September 2nd, 2000
-
-<hr><blockquote>
-I am using log4j for a project I am currently working on. The
-simplicity and ease with which new appenders can be written makes it
-one of the best logging systems I have ever used.
-</blockquote>
-
-<p align=right> Manish Balsara (manishb at aumsoft.com) August 28th, 2000
-
-<hr><blockquote>
-Thank you for writing this incredibly effective piece of software. You
-have made my and my team's lives much easier.
-</blockquote>
-
-<p align=right>Guy Nirpaz, Java Architect (guyn at tantian.com) August
-14th, 2000
-
-<hr><blockquote>
-Thank you <em>so</em> much for developing such a
-sleek package. I think it's going to be a part of many of my projects in
-the future :)
-</blockquote>
-
-<p align=right>Alice Nakajima (alice.t.nakajima at saic.com) May 10th,
-2000
-
-
-<hr><blockquote>
-Thank you very much for your great work on log4j, which is really
-powerful and flexible logging system. Log4j is now playing an
-important role in our project.
-</blockquote>
-
-<p align=right> Zeng Qiang (zeng.qiang at europeloan.com) April 26th, 2000
-
-<hr>
-<blockquote> Thank you and your team giving us a excellent tool to
-help us to develop our Java applications. After evaluation, our team
-is ready to use log4j as our eCare product's diagnostic strategy.
-</blockquote> <p align=right>Jianbo Wang (jiwang at Daleen.com) April
-25th, 2000
-
-<hr>
-<blockquote> <!-- OK -->
-Was trying to use the log4j tracer ... great job, by the way !
-
-<p>Actually I'm evaluating the log4j package for use in our commercial
-projects. We have our own tracer package which is by far less
-powerfull and less configurable than yours.
-</blockquote>
-<p align=right>Joerg Palmer (Joerg.Palmer at Compart.net) April 14th, 2000
-
-
-<hr>
-<blockquote><!-- OK -->
-Hooray, log4j! It's now all over my current project, and my colleagues
-were pleasantly surprised at the ease of debugging. I gave them my
-jarfile, it didn't work, I said "oh, just change this configuration
-file" and <em>presto</em>, logging to a file. They're happy.
-</blockquote>
-<p align=right>Nelson Minar CTO, Popular Power, Inc. (nelson at popularpower.com) April 14th, 2000
-
-<hr>
-<blockquote><!-- OK -->
-I really dig your log4j package... just started using it on our linux
-and os390 boxes for the java servlets we run in websphere. Still
-trying to get the hang of it properly, but what I do have working is
-working great. (Not to mention your makefile tutorial which has
-improved my life significantly! :-)
-</blockquote>
-<p align=right>Anthony (ant at sanlam.co.za) April 13th, 2000
-
-
-<hr><!-- OK -->
-<blockquote>
-Thanks for providing log4j: it's a very useful package.
-</blockquote>
-<p align=right>Andrew Harris (Andrew.Harris at capgemini.co.uk) April 10th, 2000
-
-<hr>
-<blockquote><!-- OK -->
-I just started using log4j v.0.8.1. It is quite what I was looking for.
-<p>So here is my <b>"THANK YOU"</b> to all the contributors.
-I think I'll join the club.
-</blockquote>
-<p align=right>Avy Sharell (asharell at club-internet.fr) March 8th, 2000
-
-
-<hr>
-<blockquote><!-- OK -->
-I just wanted to thank you for log4j which is a great piece of software!
-
-<p>We are using it in the FREE e-democracy project
-<a href="http://www.thecouch.org/free/">http://www.thecouch.org/free/</a> to provide an effective security audit
-trail in our electronic voting software.
-</blockquote>
-<p align=right> Jason Kitcat (jeep at thecouch.org) March 29th, 2000
-
-
-<hr>
-<blockquote>
-Thanks for making log4j available.
-I like the changes in v0.8 and am using it in all my java projects.
-</blockquote>
-<p align=right>Steven Marcus (srnm at awaretechnologies.com) February 19th, 2000
-
-<hr>
-<blockquote><!-- OK -->
-First congratulation for your great job on the Log mechanism log4j,
-it's really valuable.
-</blockquote>
-<p align=right>Sebastien Sahuc (ssahuc at imediation.com) January 4th, 2000
-
-
-<hr> <blockquote> Just a few remarks to your log4j Logging-Tool. First
-of all, in my opinion, it is exactly what many Java programmers need:
-A small but very useful tool complementing the debugger ;-) The logs
-help me to debug results generated on a distant client. <p
-align=right>Jens Uwe Pipka (jens.pipka at gmx.de) October 25th, 1999
-
-<hr>
-</body> </html>
diff --git a/examples/MyPatternLayout.java b/examples/MyPatternLayout.java
index eba1787..9116864 100644
--- a/examples/MyPatternLayout.java
+++ b/examples/MyPatternLayout.java
@@ -46,9 +46,9 @@ public class MyPatternLayout extends PatternLayout {
public
static void main(String[] args) {
Layout layout = new MyPatternLayout("[counter=%.10#] - %m%n");
- Category cat = Category.getInstance("some.cat");
- cat.addAppender(new ConsoleAppender(layout, ConsoleAppender.SYSTEM_OUT));
- cat.debug("Hello, log");
- cat.info("Hello again...");
+ Logger logger = Logger.getLogger("some.cat");
+ logger.addAppender(new ConsoleAppender(layout, ConsoleAppender.SYSTEM_OUT));
+ logger.debug("Hello, log");
+ logger.info("Hello again...");
}
}
diff --git a/examples/NumberCruncherServer.java b/examples/NumberCruncherServer.java
index d2eec74..a5dde22 100644
--- a/examples/NumberCruncherServer.java
+++ b/examples/NumberCruncherServer.java
@@ -14,7 +14,7 @@ import java.rmi.Naming;
import java.util.Vector;
-import org.apache.log4j.Category;
+import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
import org.apache.log4j.PropertyConfigurator;
@@ -54,8 +54,7 @@ public class NumberCruncherServer extends UnicastRemoteObject
implements NumberCruncher {
- static Category cat = Category.getInstance(
- NumberCruncherServer.class.getName());
+ static Logger logger = Logger.getLogger(NumberCruncherServer.class);
public
NumberCruncherServer() throws RemoteException {
@@ -79,7 +78,7 @@ public class NumberCruncherServer extends UnicastRemoteObject
// contained in cookies.
NDC.push(String.valueOf(number));
- cat.info("Beginning to factor.");
+ logger.info("Beginning to factor.");
if(number <= 0) {
throw new IllegalArgumentException(number+" is not a positive integer.");
}
@@ -93,10 +92,10 @@ public class NumberCruncherServer extends UnicastRemoteObject
// It is bad practice to place log requests within tight loops.
// It is done here to show interleaved log output from
// different requests.
- cat.debug("Trying to see if " + i + " is a factor.");
+ logger.debug("Trying to see if " + i + " is a factor.");
if((n % i) == 0) {
- cat.info("Found factor "+i);
+ logger.info("Found factor "+i);
factors.addElement(new Integer(i));
do {
n /= i;
@@ -108,7 +107,7 @@ public class NumberCruncherServer extends UnicastRemoteObject
}
if(n != 1) {
- cat.info("Found factor "+n);
+ logger.info("Found factor "+n);
factors.addElement(new Integer(n));
}
@@ -153,10 +152,10 @@ public class NumberCruncherServer extends UnicastRemoteObject
try {
ncs = new NumberCruncherServer();
Naming.rebind("Factor", ncs);
- cat.info("NumberCruncherServer bound and ready to serve.");
+ logger.info("NumberCruncherServer bound and ready to serve.");
}
catch(Exception e) {
- cat.error("Could not bind NumberCruncherServer.", e);
+ logger.error("Could not bind NumberCruncherServer.", e);
return;
}
NumberCruncherClient.loop(ncs);
diff --git a/examples/SortAlgo.java b/examples/SortAlgo.java
index a5a3f53..98a4b04 100644
--- a/examples/SortAlgo.java
+++ b/examples/SortAlgo.java
@@ -1,7 +1,7 @@
package examples;
-import org.apache.log4j.Category;
+import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
/**
@@ -16,11 +16,11 @@ import org.apache.log4j.NDC;
public class SortAlgo {
final static String className = SortAlgo.class.getName();
- final static Category CAT = Category.getInstance(className);
- final static Category OUTER = Category.getInstance(className + ".OUTER");
- final static Category INNER = Category.getInstance(className + ".INNER");
- final static Category DUMP = Category.getInstance(className + ".DUMP");
- final static Category SWAP = Category.getInstance(className + ".SWAP");
+ final static Logger LOG = Logger.getLogger(className);
+ final static Logger OUTER = Logger.getLogger(className + ".OUTER");
+ final static Logger INNER = Logger.getLogger(className + ".INNER");
+ final static Logger DUMP = Logger.getLogger(className + ".DUMP");
+ final static Logger SWAP = Logger.getLogger(className + ".SWAP");
int[] intArray;
@@ -29,7 +29,7 @@ public class SortAlgo {
}
void bubbleSort() {
- CAT.info( "Entered the sort method.");
+ LOG.info( "Entered the sort method.");
for(int i = intArray.length -1; i >= 0 ; i--) {
NDC.push("i=" + i);
diff --git a/examples/Trivial.java b/examples/Trivial.java
index 0f97056..9be452d 100644
--- a/examples/Trivial.java
+++ b/examples/Trivial.java
@@ -2,7 +2,7 @@
package examples;
-import org.apache.log4j.Category;
+import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.NDC;
@@ -33,31 +33,31 @@ import org.apache.log4j.NDC;
*/
public class Trivial {
- static Category cat = Category.getInstance(Trivial.class.getName());
+ static Logger logger = Logger.getLogger(Trivial.class);
public static void main(String[] args) {
BasicConfigurator.configure();
NDC.push("Client #45890");
- cat.info("Awake awake. Put on thy strength.");
+ logger.info("Awake awake. Put on thy strength.");
Trivial.foo();
InnerTrivial.foo();
- cat.info("Exiting Trivial.");
+ logger.info("Exiting Trivial.");
}
static
void foo() {
NDC.push("DB");
- cat.debug("Now king David was old.");
+ logger.debug("Now king David was old.");
NDC.pop();
}
static class InnerTrivial {
- static Category cat = Category.getInstance(InnerTrivial.class.getName());
+ static Logger logger = Logger.getLogger(InnerTrivial.class);
static
void foo() {
- cat.info("Entered foo.");
+ logger.info("Entered foo.");
}
}
}
diff --git a/examples/lf5/InitUsingDefaultConfigurator/InitUsingDefaultConfigurator.java b/examples/lf5/InitUsingDefaultConfigurator/InitUsingDefaultConfigurator.java
new file mode 100644
index 0000000..e089069
--- /dev/null
+++ b/examples/lf5/InitUsingDefaultConfigurator/InitUsingDefaultConfigurator.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software
+ * License version 1.1, a copy of which has been included with this
+ * distribution in the LICENSE.txt file.
+ */
+package examples.lf5.InitUsingDefaultConfigurator;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.NDC;
+import org.apache.log4j.lf5.DefaultLF5Configurator;
+
+import java.io.IOException;
+
+/**
+ * This class is a simple example of how to configure the LogFactor5
+ * logging window using the DefaultLF5Configurator.
+ *
+ * The DefaultLF5Configurator uses a default configuration file stored
+ * in the log4j.jar in order to provide a default configuration for
+ * the LF5Appender.
+ *
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class InitUsingDefaultConfigurator {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private static Logger logger =
+ Logger.getLogger(InitUsingDefaultConfigurator.class);
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public static void main(String[] args) throws IOException {
+ // Configure the LF5Appender using the DefaultLF5Configurator. This
+ // will add the LF5Appender to the root of the Category tree.
+ DefaultLF5Configurator.configure();
+
+ // Add an NDC to demonstrate how NDC information is output.
+ NDC.push("#23856");
+ // Log some information.
+ for (int i = 0; i < 10; i++) {
+ logger.debug("Hello, my name is Homer Simpson.");
+ logger.info("Mmmmmm .... Chocolate.");
+ logger.warn("Mmm...forbidden donut.");
+ }
+ // Clean up NDC
+ NDC.pop();
+ NDC.remove();
+
+ NDC.push("Another NDC");
+ // Log some information.
+ logger.fatal("Hello, my name is Bart Simpson.");
+ logger.error("Hi diddly ho good neighbour.");
+ // Clean up NDC
+ NDC.pop();
+ NDC.remove();
+
+ // Call methods on both classes.
+ InitUsingDefaultConfigurator.foo();
+ InnerInitUsingDefaultConfigurator.foo();
+
+ logger.info("Exiting InitUsingDefaultConfigurator.");
+
+ }
+
+ public static void foo() {
+ logger.debug("Entered foo in InitUsingDefaultConfigurator class");
+
+ NDC.push("#123456");
+ logger.debug("Hello, my name is Marge Simpson.");
+ logger.info("D'oh!! A deer! A female deer.");
+ // Clean up NDC
+ NDC.pop();
+ NDC.remove();
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+ public static class InnerInitUsingDefaultConfigurator {
+ static Logger logger =
+ Logger.getLogger(InnerInitUsingDefaultConfigurator.class.getName());
+
+ static void foo() throws IOException {
+ // Configure the LF5Appender again. You can call
+ // DefaultLF5Configurator.configure() as often as you want
+ // without unexpected behavior.
+ DefaultLF5Configurator.configure();
+
+ logger.info("Entered foo in InnerInitUsingDefaultConfigurator class.");
+ }
+ }
+}
+
+
+
+
+
diff --git a/examples/lf5/InitUsingLog4JProperties/InitUsingLog4JProperties.java b/examples/lf5/InitUsingLog4JProperties/InitUsingLog4JProperties.java
new file mode 100644
index 0000000..2679d6d
--- /dev/null
+++ b/examples/lf5/InitUsingLog4JProperties/InitUsingLog4JProperties.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software
+ * License version 1.1, a copy of which has been included with this
+ * distribution in the LICENSE.txt file.
+ */
+package examples.lf5.InitUsingLog4JProperties;
+
+import org.apache.log4j.Logger;
+
+import java.io.IOException;
+
+/**
+ * This class is a simple example of how to use the LogFactor5 logging
+ * window.
+ *
+ * The LF5Appender is the primary class that enables logging to the
+ * LogFactor5 logging window. The simplest method of using this Appender
+ * is to add the following line to your log4j.properties file:
+ *
+ * log4j.appender.A1=org.apache.log4j.lf5.LF5Appender
+ *
+ * The log4j.properties file MUST be in you system classpath. If this file
+ * is in your system classpath, a static initializer in the Category class
+ * will load the file during class initialization. The LF5Appender will be
+ * added to the root category of the Category tree.
+ *
+ * Create a log4j.properties file and add this line to it, or add this line
+ * to your existing log4j.properties file. Run the example at the command line
+ * and explore the results!
+ *
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class InitUsingLog4JProperties {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ private static Logger logger =
+ Logger.getLogger(InitUsingLog4JProperties.class);
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public static void main(String argv[]) {
+ // Add a bunch of logging statements ...
+ logger.debug("Hello, my name is Homer Simpson.");
+ logger.debug("Hello, my name is Lisa Simpson.");
+ logger.debug("Hello, my name is Marge Simpson.");
+ logger.debug("Hello, my name is Bart Simpson.");
+ logger.debug("Hello, my name is Maggie Simpson.");
+
+ logger.info("We are the Simpsons!");
+ logger.info("Mmmmmm .... Chocolate.");
+ logger.info("Homer likes chocolate");
+ logger.info("Doh!");
+ logger.info("We are the Simpsons!");
+
+ logger.warn("Bart: I am through with working! Working is for chumps!" +
+ "Homer: Son, I'm proud of you. I was twice your age before " +
+ "I figured that out.");
+ logger.warn("Mmm...forbidden donut.");
+ logger.warn("D'oh! A deer! A female deer!");
+ logger.warn("Truly, yours is a butt that won't quit." +
+ "- Bart, writing as Woodrow to Ms. Krabappel.");
+
+ logger.error("Dear Baby, Welcome to Dumpsville. Population: you.");
+ logger.error("Dear Baby, Welcome to Dumpsville. Population: you.",
+ new IOException("Dumpsville, USA"));
+ logger.error("Mr. Hutz, are you aware you're not wearing pants?");
+ logger.error("Mr. Hutz, are you aware you're not wearing pants?",
+ new IllegalStateException("Error !!"));
+
+
+ logger.fatal("Eep.");
+ logger.fatal("Mmm...forbidden donut.",
+ new SecurityException("Fatal Exception"));
+ logger.fatal("D'oh! A deer! A female deer!");
+ logger.fatal("Mmmmmm .... Chocolate.",
+ new SecurityException("Fatal Exception"));
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/examples/lf5/InitUsingLog4JProperties/log4j.properties b/examples/lf5/InitUsingLog4JProperties/log4j.properties
new file mode 100644
index 0000000..98b54b5
--- /dev/null
+++ b/examples/lf5/InitUsingLog4JProperties/log4j.properties
@@ -0,0 +1,17 @@
+# For the general syntax of property based configuration files see the
+# documenation of org.apache.log4j.PropertyConfigurator.
+
+# The root category uses the appender called A1. Since no priority is
+# specified, the root category assumes the default priority for root
+# which is DEBUG in log4j. The root category is the only category that
+# has a default priority. All other categories need not be assigned a
+# priority in which case they inherit their priority from the
+# hierarchy.
+
+log4j.rootCategory=, A1
+
+# A1 is set to be a LF5Appender which outputs to a swing
+# logging console.
+
+log4j.appender.A1=org.apache.log4j.lf5.LF5Appender
+log4j.appender.A1.MaxNumberOfRecords=1000
diff --git a/examples/lf5/InitUsingMultipleAppenders/InitUsingMultipleAppenders.java b/examples/lf5/InitUsingMultipleAppenders/InitUsingMultipleAppenders.java
new file mode 100644
index 0000000..c3d7a31
--- /dev/null
+++ b/examples/lf5/InitUsingMultipleAppenders/InitUsingMultipleAppenders.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software
+ * License version 1.1, a copy of which has been included with this
+ * distribution in the LICENSE.txt file.
+ */
+package examples.lf5.InitUsingMultipleAppenders;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * This example shows how to use LogFactor5 with other Log4J appenders
+ * (In this case the RollingFileAppender).
+ *
+ * The following lines can be added to the log4j.properties file or a
+ * standard Java properties file.
+ *
+ * # Two appenders are registered with the root of the Category tree.
+ *
+ * log4j.rootCategory=, A1, R
+ *
+ * # A1 is set to be a LF5Appender which outputs to a swing
+ * # logging console.
+ *
+ * log4j.appender.A1=org.apache.log4j.lf5.LF5Appender
+ *
+ * # R is the RollingFileAppender that outputs to a rolling log
+ * # file called rolling_log_file.log.
+ *
+ * log4j.appender.R=org.apache.log4j.RollingFileAppender
+ * log4j.appender.R.File=rolling_log_file.log
+ *
+ * log4j.appender.R.layout=org.apache.log4j.PatternLayout
+ * log4j.appender.R.layout.ConversionPattern=Date - %d{DATE}%nPriority
+ * - %p%nThread - %t%nCategory - %c%nLocation - %l%nMessage - %m%n%n
+ * log4j.appender.R.MaxFileSize=100KB
+ * log4j.appender.R.MaxBackupIndex=1
+ *
+ * To make this example work, either run the InitUsingMultipleAppenders.bat
+ * file located in the examples folder or run it at the command line. If you
+ * are running the example at the command line, you must ensure that the
+ * example.properties file is in your classpath.
+ *
+ * @author Brent Sprecher
+ * @author Brad Marlborough
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class InitUsingMultipleAppenders {
+
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ private static Logger logger =
+ Logger.getLogger(InitUsingMultipleAppenders.class);
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public static void main(String argv[]) {
+ // Use a PropertyConfigurator to initialize from a property file.
+ String resource =
+ "/examples/lf5/InitUsingMultipleAppenders/example.properties";
+ URL configFileResource =
+ InitUsingMultipleAppenders.class.getResource(resource);
+ PropertyConfigurator.configure(configFileResource);
+
+ // Add a bunch of logging statements ...
+ logger.debug("Hello, my name is Homer Simpson.");
+ logger.debug("Hello, my name is Lisa Simpson.");
+ logger.debug("Hello, my name is Marge Simpson.");
+ logger.debug("Hello, my name is Bart Simpson.");
+ logger.debug("Hello, my name is Maggie Simpson.");
+
+ logger.info("We are the Simpsons!");
+ logger.info("Mmmmmm .... Chocolate.");
+ logger.info("Homer likes chocolate");
+ logger.info("Doh!");
+ logger.info("We are the Simpsons!");
+
+ logger.warn("Bart: I am through with working! Working is for chumps!" +
+ "Homer: Son, I'm proud of you. I was twice your age before " +
+ "I figured that out.");
+ logger.warn("Mmm...forbidden donut.");
+ logger.warn("D'oh! A deer! A female deer!");
+ logger.warn("Truly, yours is a butt that won't quit." +
+ "- Bart, writing as Woodrow to Ms. Krabappel.");
+
+ logger.error("Dear Baby, Welcome to Dumpsville. Population: you.");
+ logger.error("Dear Baby, Welcome to Dumpsville. Population: you.",
+ new IOException("Dumpsville, USA"));
+ logger.error("Mr. Hutz, are you aware you're not wearing pants?");
+ logger.error("Mr. Hutz, are you aware you're not wearing pants?",
+ new IllegalStateException("Error !!"));
+
+
+ logger.fatal("Eep.");
+ logger.fatal("Mmm...forbidden donut.",
+ new SecurityException("Fatal Exception"));
+ logger.fatal("D'oh! A deer! A female deer!");
+ logger.fatal("Mmmmmm .... Chocolate.",
+ new SecurityException("Fatal Exception"));
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/examples/lf5/InitUsingMultipleAppenders/example.properties b/examples/lf5/InitUsingMultipleAppenders/example.properties
new file mode 100644
index 0000000..ac1f374
--- /dev/null
+++ b/examples/lf5/InitUsingMultipleAppenders/example.properties
@@ -0,0 +1,34 @@
+# For the general syntax of property based configuration files see the
+# documenation of org.apache.log4j.PropertyConfigurator.
+
+# The root category uses two appenders called A1 and R. Since no priority is
+# specified, the root category assumes the default priority for root
+# which is DEBUG in log4j. The root category is the only category that
+# has a default priority. All other categories need not be assigned a
+# priority in which case they inherit their priority from the
+# hierarchy.
+
+log4j.rootCategory=, A1, R
+
+# A1 is set to be a LF5Appender which outputs to a swing
+# logging console.
+
+log4j.appender.A1=org.apache.log4j.lf5.LF5Appender
+
+# R is the RollingFileAppender that outputs to a rolling log
+# file called rolling_log_file.log.
+
+log4j.appender.R=org.apache.log4j.RollingFileAppender
+log4j.appender.R.File=rolling_log_file.log
+
+# Define a pattern layout for the file.
+# For more information on conversion characters (i.e. d,p,t,c,l,m,n)
+# please see the PatternLayout class of the Log4j API.
+
+log4j.appender.R.layout=org.apache.log4j.PatternLayout
+log4j.appender.R.layout.ConversionPattern=[slf5s.start]%d{DATE}[slf5s.DATE]%n%p[slf5s.PRIORITY]%n%x[slf5s.NDC]%n%t[slf5s.THREAD]%n%c[slf5s.CATEGORY]%n%l[slf5s.LOCATION]%n%m[slf5s.MESSAGE]%n%n
+
+# Set the max size of the file and the number of backup files
+
+log4j.appender.R.MaxFileSize=100KB
+log4j.appender.R.MaxBackupIndex=1
\ No newline at end of file
diff --git a/examples/lf5/InitUsingPropertiesFile/InitUsingPropertiesFile.java b/examples/lf5/InitUsingPropertiesFile/InitUsingPropertiesFile.java
new file mode 100644
index 0000000..71abb94
--- /dev/null
+++ b/examples/lf5/InitUsingPropertiesFile/InitUsingPropertiesFile.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software
+ * License version 1.1, a copy of which has been included with this
+ * distribution in the LICENSE.txt file.
+ */
+package examples.lf5.InitUsingPropertiesFile;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * This is another simple example of how to use the LogFactor5
+ * logging console.
+ *
+ * The LF5Appender is the primary class that enables logging to the
+ * LogFactor5 logging window. If the following line is added to a properties
+ * file, the LF5Appender will be appended to the root category when
+ * the properties file is loaded:
+ *
+ * log4j.appender.A1=org.apache.log4j.lf5.LF5Appender
+ *
+ * To make this example work, you must ensure that the example.properties file
+ * is in your classpath.You can then run the example at the command line.
+ *
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class InitUsingPropertiesFile {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ private static Logger logger =
+ Logger.getLogger(InitUsingPropertiesFile.class);
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public static void main(String argv[]) {
+ // Use a PropertyConfigurator to initialize from a property file.
+ String resource =
+ "/examples/lf5/InitUsingPropertiesFile/example.properties";
+ URL configFileResource =
+ InitUsingPropertiesFile.class.getResource(resource);
+ PropertyConfigurator.configure(configFileResource);
+
+ // Add a bunch of logging statements ...
+ logger.debug("Hello, my name is Homer Simpson.");
+ logger.debug("Hello, my name is Lisa Simpson.");
+ logger.debug("Hello, my name is Marge Simpson.");
+ logger.debug("Hello, my name is Bart Simpson.");
+ logger.debug("Hello, my name is Maggie Simpson.");
+
+ logger.info("We are the Simpsons!");
+ logger.info("Mmmmmm .... Chocolate.");
+ logger.info("Homer likes chocolate");
+ logger.info("Doh!");
+ logger.info("We are the Simpsons!");
+
+ logger.warn("Bart: I am through with working! Working is for chumps!" +
+ "Homer: Son, I'm proud of you. I was twice your age before " +
+ "I figured that out.");
+ logger.warn("Mmm...forbidden donut.");
+ logger.warn("D'oh! A deer! A female deer!");
+ logger.warn("Truly, yours is a butt that won't quit." +
+ "- Bart, writing as Woodrow to Ms. Krabappel.");
+
+ logger.error("Dear Baby, Welcome to Dumpsville. Population: you.");
+ logger.error("Dear Baby, Welcome to Dumpsville. Population: you.",
+ new IOException("Dumpsville, USA"));
+ logger.error("Mr. Hutz, are you aware you're not wearing pants?");
+ logger.error("Mr. Hutz, are you aware you're not wearing pants?",
+ new IllegalStateException("Error !!"));
+
+
+ logger.fatal("Eep.");
+ logger.fatal("Mmm...forbidden donut.",
+ new SecurityException("Fatal Exception"));
+ logger.fatal("D'oh! A deer! A female deer!");
+ logger.fatal("Mmmmmm .... Chocolate.",
+ new SecurityException("Fatal Exception"));
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/examples/lf5/InitUsingPropertiesFile/example.properties b/examples/lf5/InitUsingPropertiesFile/example.properties
new file mode 100644
index 0000000..ab421d3
--- /dev/null
+++ b/examples/lf5/InitUsingPropertiesFile/example.properties
@@ -0,0 +1,17 @@
+# For the general syntax of property based configuration files see the
+# documenation of org.apache.log4j.PropertyConfigurator.
+
+# The root category uses the appender called A1. Since no priority is
+# specified, the root category assumes the default priority for root
+# which is DEBUG in log4j. The root category is the only category that
+# has a default priority. All other categories need not be assigned a
+# priority in which case they inherit their priority from the
+# hierarchy.
+
+log4j.rootCategory=, A1
+
+# A1 is set to be a LF5Appender which outputs to a swing
+# logging console.
+
+log4j.appender.A1=org.apache.log4j.lf5.LF5Appender
+log4j.appender.A1.MaxNumberOfRecords=700
diff --git a/examples/lf5/InitUsingXMLPropertiesFile/InitUsingXMLPropertiesFile.java b/examples/lf5/InitUsingXMLPropertiesFile/InitUsingXMLPropertiesFile.java
new file mode 100644
index 0000000..8b21c98
--- /dev/null
+++ b/examples/lf5/InitUsingXMLPropertiesFile/InitUsingXMLPropertiesFile.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software
+ * License version 1.1, a copy of which has been included with this
+ * distribution in the LICENSE.txt file.
+ */
+package examples.lf5.InitUsingXMLPropertiesFile;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.xml.DOMConfigurator;
+
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * This is another simple example of how to use the LogFactor5
+ * logging console.
+ *
+ * To make this example work, ensure that the lf5.jar, lf5-license.jar
+ * and example.xml files are in your classpath. Once your classpath has
+ * been set up, you can run the example from the command line.
+ *
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class InitUsingXMLPropertiesFile {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ private static Logger logger =
+ Logger.getLogger(InitUsingXMLPropertiesFile.class);
+
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public static void main(String argv[]) {
+ // Use a PropertyConfigurator to initialize from a property file.
+ String resource =
+ "/examples/lf5/InitUsingXMLPropertiesFile/example.xml";
+ URL configFileResource =
+ InitUsingXMLPropertiesFile.class.getResource(resource);
+ DOMConfigurator.configure(configFileResource.getFile());
+
+ // Add a bunch of logging statements ...
+ logger.debug("Hello, my name is Homer Simpson.");
+ logger.debug("Hello, my name is Lisa Simpson.");
+ logger.debug("Hello, my name is Marge Simpson.");
+ logger.debug("Hello, my name is Bart Simpson.");
+ logger.debug("Hello, my name is Maggie Simpson.");
+
+ logger.info("We are the Simpsons!");
+ logger.info("Mmmmmm .... Chocolate.");
+ logger.info("Homer likes chocolate");
+ logger.info("Doh!");
+ logger.info("We are the Simpsons!");
+
+ logger.warn("Bart: I am through with working! Working is for chumps!" +
+ "Homer: Son, I'm proud of you. I was twice your age before " +
+ "I figured that out.");
+ logger.warn("Mmm...forbidden donut.");
+ logger.warn("D'oh! A deer! A female deer!");
+ logger.warn("Truly, yours is a butt that won't quit." +
+ "- Bart, writing as Woodrow to Ms. Krabappel.");
+
+ logger.error("Dear Baby, Welcome to Dumpsville. Population: you.");
+ logger.error("Dear Baby, Welcome to Dumpsville. Population: you.",
+ new IOException("Dumpsville, USA"));
+ logger.error("Mr. Hutz, are you aware you're not wearing pants?");
+ logger.error("Mr. Hutz, are you aware you're not wearing pants?",
+ new IllegalStateException("Error !!"));
+
+
+ logger.fatal("Eep.");
+ logger.fatal("Mmm...forbidden donut.",
+ new SecurityException("Fatal Exception"));
+ logger.fatal("D'oh! A deer! A female deer!");
+ logger.fatal("Mmmmmm .... Chocolate.",
+ new SecurityException("Fatal Exception"));
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/examples/lf5/InitUsingXMLPropertiesFile/example.xml b/examples/lf5/InitUsingXMLPropertiesFile/example.xml
new file mode 100644
index 0000000..d167c5f
--- /dev/null
+++ b/examples/lf5/InitUsingXMLPropertiesFile/example.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration>
+
+ <appender name="LF5Appender" class="org.apache.log4j.lf5.LF5Appender">
+ <param name="MaxNumberOfRecords" value="1000"/>
+ </appender>
+
+ <root>
+ <priority value ="debug" />
+ <appender-ref ref="LF5Appender"/>
+ </root>
+
+</log4j:configuration>
\ No newline at end of file
diff --git a/examples/lf5/OpeningLogFiles/sample.log b/examples/lf5/OpeningLogFiles/sample.log
new file mode 100644
index 0000000..1adbea5
--- /dev/null
+++ b/examples/lf5/OpeningLogFiles/sample.log
@@ -0,0 +1,184 @@
+[slf5s.start]26 Jul 2001 15:54:44,673[slf5s.DATE]
+DEBUG[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:102)[slf5s.LOCATION]
+Hello, my name is Homer Simpson.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,743[slf5s.DATE]
+DEBUG[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:103)[slf5s.LOCATION]
+Hello, my name is Lisa Simpson.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,743[slf5s.DATE]
+DEBUG[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:104)[slf5s.LOCATION]
+Hello, my name is Marge Simpson.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,753[slf5s.DATE]
+DEBUG[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:105)[slf5s.LOCATION]
+Hello, my name is Bart Simpson.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,793[slf5s.DATE]
+DEBUG[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:106)[slf5s.LOCATION]
+Hello, my name is Maggie Simpson.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,793[slf5s.DATE]
+INFO[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:108)[slf5s.LOCATION]
+We are the Simpsons![slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,803[slf5s.DATE]
+INFO[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:109)[slf5s.LOCATION]
+Mmmmmm .... Chocolate.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,803[slf5s.DATE]
+INFO[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:110)[slf5s.LOCATION]
+Homer likes chocolate[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,803[slf5s.DATE]
+INFO[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:111)[slf5s.LOCATION]
+Doh![slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,803[slf5s.DATE]
+INFO[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:112)[slf5s.LOCATION]
+We are the Simpsons![slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,803[slf5s.DATE]
+WARN[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:114)[slf5s.LOCATION]
+Bart: I am through with working! Working is for chumps!Homer: Son, I'm proud of you. I was twice your age before I figured that out.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,803[slf5s.DATE]
+WARN[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:117)[slf5s.LOCATION]
+Mmm...forbidden donut.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,803[slf5s.DATE]
+WARN[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:118)[slf5s.LOCATION]
+D'oh! A deer! A female deer![slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,803[slf5s.DATE]
+WARN[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:119)[slf5s.LOCATION]
+Truly, yours is a butt that won't quit.- Bart, writing as Woodrow to Ms. Krabappel.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,803[slf5s.DATE]
+ERROR[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:122)[slf5s.LOCATION]
+Dear Baby, Welcome to Dumpsville. Population: you.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,903[slf5s.DATE]
+ERROR[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:123)[slf5s.LOCATION]
+Dear Baby, Welcome to Dumpsville. Population: you.[slf5s.MESSAGE]
+
+java.io.IOException: Dumpsville, USA
+ at examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:123)
+[slf5s.start]26 Jul 2001 15:54:44,903[slf5s.DATE]
+ERROR[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:125)[slf5s.LOCATION]
+Mr. Hutz, are you aware you're not wearing pants?[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:44,903[slf5s.DATE]
+ERROR[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:126)[slf5s.LOCATION]
+Mr. Hutz, are you aware you're not wearing pants?[slf5s.MESSAGE]
+
+java.lang.IllegalStateException: Error !!
+ at examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:126)
+[slf5s.start]26 Jul 2001 15:54:44,903[slf5s.DATE]
+FATAL[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:130)[slf5s.LOCATION]
+Eep.[slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:45,063[slf5s.DATE]
+FATAL[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:131)[slf5s.LOCATION]
+Mmm...forbidden donut.[slf5s.MESSAGE]
+
+java.lang.SecurityException: Fatal Exception
+ at examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:131)
+[slf5s.start]26 Jul 2001 15:54:45,063[slf5s.DATE]
+FATAL[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:133)[slf5s.LOCATION]
+D'oh! A deer! A female deer![slf5s.MESSAGE]
+
+[slf5s.start]26 Jul 2001 15:54:45,063[slf5s.DATE]
+FATAL[slf5s.PRIORITY]
+[slf5s.NDC]
+main[slf5s.THREAD]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders[slf5s.CATEGORY]
+examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:134)[slf5s.LOCATION]
+Mmmmmm .... Chocolate.[slf5s.MESSAGE]
+
+java.lang.SecurityException: Fatal Exception
+ at examples.InitUsingMultipleAppenders.InitUsingMultipleAppenders.main(InitUsingMultipleAppenders.java:134)
diff --git a/examples/lf5/UsingLogMonitorAdapter/CustomizedLogLevels.java b/examples/lf5/UsingLogMonitorAdapter/CustomizedLogLevels.java
new file mode 100644
index 0000000..832ed95
--- /dev/null
+++ b/examples/lf5/UsingLogMonitorAdapter/CustomizedLogLevels.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software
+ * License version 1.1, a copy of which has been included with this
+ * distribution in the LICENSE.txt file.
+ */
+
+package examples.lf5.UsingLogMonitorAdapter;
+
+import org.apache.log4j.lf5.LogLevel;
+import org.apache.log4j.lf5.util.LogMonitorAdapter;
+
+/**
+ * This class is a simple example of how use the LogMonitorAdapter to
+ * bypass the Log4JAppender and post LogRecords directly to the LogMonitor
+ * using customized LogLevels
+ *
+ * To make this example work, ensure that the lf5.jar and lf5-license.jar
+ * files are in your classpath, and then run the example at the command line.
+ *
+ * @author Richard Hurst
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class CustomizedLogLevels {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+ public final static LogLevel LEVEL_ONE = new LogLevel("LEVEL 1", 1);
+ public final static LogLevel LEVEL_TWO = new LogLevel("LEVEL 2", 2);
+ public final static LogLevel LEVEL_THREE = new LogLevel("LEVEL 3", 3);
+ public final static LogLevel LEVEL_FOUR = new LogLevel("LEVEL 4", 4);
+ public final static LogLevel DEFAULT = new LogLevel("DEFAULT", 0);
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private static LogMonitorAdapter _adapter;
+
+ static {
+ // The first LogLevel in the Array will be used as the default LogLevel.
+ _adapter = LogMonitorAdapter.newInstance(new LogLevel[]{DEFAULT, LEVEL_ONE,
+ LEVEL_TWO, LEVEL_THREE, LEVEL_FOUR, LogLevel.FATAL});
+ // if a different log level is to be used it can be specified as such
+ // _adapter.setDefaultLevel(LEVEL_THREE);
+ }
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public static void main(String[] args) {
+ CustomizedLogLevels test = new CustomizedLogLevels();
+ test.doMyBidding();
+ }
+
+ public void doMyBidding() {
+ // tell the LogMonitorAdapter which LogLevel is the severe Level if necessary
+ _adapter.setSevereLevel(LEVEL_ONE);
+
+ String levels = this.getClass().getName();
+
+ // will used the default Level
+ _adapter.log(levels, "Using the customized LogLevels");
+
+ _adapter.log(levels, LEVEL_FOUR, "This is a test");
+ _adapter.log(levels, LEVEL_THREE, "Hmmm fobidden doughnut");
+ _adapter.log(levels, LEVEL_ONE, "Danger Danger Will Robinson",
+ new RuntimeException("DANGER"), "32");
+ _adapter.log(levels, LEVEL_TWO, "Exit stage right->");
+ _adapter.log(levels, LEVEL_FOUR, "What's up Doc?",
+ new NullPointerException("Unfortunate exception"));
+
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+}
+
+
+
+
+
diff --git a/examples/lf5/UsingLogMonitorAdapter/UsingLogMonitorAdapter.java b/examples/lf5/UsingLogMonitorAdapter/UsingLogMonitorAdapter.java
new file mode 100644
index 0000000..0484859
--- /dev/null
+++ b/examples/lf5/UsingLogMonitorAdapter/UsingLogMonitorAdapter.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software
+ * License version 1.1, a copy of which has been included with this
+ * distribution in the LICENSE.txt file.
+ */
+package examples.lf5.UsingLogMonitorAdapter;
+
+import org.apache.log4j.lf5.LogLevel;
+import org.apache.log4j.lf5.util.AdapterLogRecord;
+import org.apache.log4j.lf5.util.LogMonitorAdapter;
+
+/**
+ * This class is a simple example of how use the LogMonitorAdapter to
+ * bypass the Log4JAppender and post LogRecords directly to the LogMonitor
+ *
+ * To make this example work, ensure that the lf5.jar and lf5-license.jar
+ * files are in your classpath, and then run the example at the command line.
+ *
+ * @author Richard Hurst
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class UsingLogMonitorAdapter {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+ private static LogMonitorAdapter _adapter;
+
+ static {
+ _adapter = LogMonitorAdapter.newInstance(LogMonitorAdapter.LOG4J_LOG_LEVELS);
+ }
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public static void main(String[] args) {
+ UsingLogMonitorAdapter test = new UsingLogMonitorAdapter();
+ test.doMyBidding();
+ }
+
+ public void doMyBidding() {
+ String logger = this.getClass().getName();
+
+ // will default to debug log level
+ _adapter.log(logger, "Doh this is a debugging");
+
+ _adapter.log(logger, LogLevel.INFO, "Hmmm fobidden doughnut");
+ _adapter.log(logger, LogLevel.WARN, "Danger Danger Will Robinson",
+ new RuntimeException("DANGER"), "32");
+ _adapter.log(logger, LogLevel.ERROR, "Exit stage right->");
+ _adapter.log(logger, LogLevel.FATAL, "What's up Doc?",
+ new NullPointerException("Unfortunate exception"));
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+}
+
+
+
+
+
diff --git a/examples/lf5/UsingSocketAppenders/UsingSocketAppenders.java b/examples/lf5/UsingSocketAppenders/UsingSocketAppenders.java
new file mode 100644
index 0000000..4274890
--- /dev/null
+++ b/examples/lf5/UsingSocketAppenders/UsingSocketAppenders.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software
+ * License version 1.1, a copy of which has been included with this
+ * distribution in the LICENSE.txt file.
+ */
+
+package examples.lf5.UsingSocketAppenders;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * This is another simple example of how to use the LogFactor5
+ * logging console.
+ *
+ * The LF5Appender is the primary class that enables logging to the
+ * LogFactor5 logging window. If the following line is added to a properties
+ * file, the LF5Appender will be appended to the root category when
+ * the properties file is loaded:
+ *
+ * log4j.appender.A1=org.apache.log4j.lf5.LF5Appender
+ *
+ * To make this example work, you must ensure that the example.properties file
+ * is in your classpath.You can then run the example at the command line.
+ *
+ * @author Brent Sprecher
+ */
+
+// Contributed by ThoughtWorks Inc.
+
+public class UsingSocketAppenders {
+ //--------------------------------------------------------------------------
+ // Constants:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Protected Variables:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Variables:
+ //--------------------------------------------------------------------------
+
+ private static Logger logger1 =
+ Logger.getLogger(UsingSocketAppenders.class);
+ private static Logger logger2 =
+ Logger.getLogger("TestClass.Subclass");
+ private static Logger logger3 =
+ Logger.getLogger("TestClass.Subclass.Subclass");
+ //--------------------------------------------------------------------------
+ // Constructors:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Public Methods:
+ //--------------------------------------------------------------------------
+
+ public static void main(String argv[]) {
+ // Use a PropertyConfigurator to initialize from a property file.
+ String resource =
+ "/examples/lf5/UsingSocketAppenders/socketclient.properties";
+ URL configFileResource =
+ UsingSocketAppenders.class.getResource(resource);
+ PropertyConfigurator.configure(configFileResource);
+
+ // Add a bunch of logging statements ...
+ logger1.debug("Hello, my name is Homer Simpson.");
+ logger1.debug("Hello, my name is Lisa Simpson.");
+ logger2.debug("Hello, my name is Marge Simpson.");
+ logger2.debug("Hello, my name is Bart Simpson.");
+ logger3.debug("Hello, my name is Maggie Simpson.");
+
+ logger2.info("We are the Simpsons!");
+ logger2.info("Mmmmmm .... Chocolate.");
+ logger3.info("Homer likes chocolate");
+ logger3.info("Doh!");
+ logger3.info("We are the Simpsons!");
+
+ logger1.warn("Bart: I am through with working! Working is for chumps!" +
+ "Homer: Son, I'm proud of you. I was twice your age before " +
+ "I figured that out.");
+ logger1.warn("Mmm...forbidden donut.");
+ logger1.warn("D'oh! A deer! A female deer!");
+ logger1.warn("Truly, yours is a butt that won't quit." +
+ "- Bart, writing as Woodrow to Ms. Krabappel.");
+
+ logger2.error("Dear Baby, Welcome to Dumpsville. Population: you.");
+ logger2.error("Dear Baby, Welcome to Dumpsville. Population: you.",
+ new IOException("Dumpsville, USA"));
+ logger3.error("Mr. Hutz, are you aware you're not wearing pants?");
+ logger3.error("Mr. Hutz, are you aware you're not wearing pants?",
+ new IllegalStateException("Error !!"));
+
+
+ logger3.fatal("Eep.");
+
+ logger3.fatal("Mmm...forbidden donut.",
+ new SecurityException("Fatal Exception ... "));
+
+ logger3.fatal("D'oh! A deer! A female deer!");
+ logger2.fatal("Mmmmmm .... Chocolate.",
+ new SecurityException("Fatal Exception"));
+
+ // Put the main thread is put to sleep for 5 seconds to allow the
+ // SocketServer to process all incoming messages before the Socket is
+ // closed. This is done to overcome some basic limitations with the
+ // way the SocketServer and SocketAppender classes manage sockets.
+ try {
+ Thread.currentThread().sleep(5000);
+ } catch (InterruptedException ie) {
+ }
+
+ }
+
+ //--------------------------------------------------------------------------
+ // Protected Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Private Methods:
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Nested Top-Level Classes or Interfaces:
+ //--------------------------------------------------------------------------
+
+}
diff --git a/examples/lf5/UsingSocketAppenders/socketclient.properties b/examples/lf5/UsingSocketAppenders/socketclient.properties
new file mode 100644
index 0000000..b051365
--- /dev/null
+++ b/examples/lf5/UsingSocketAppenders/socketclient.properties
@@ -0,0 +1,18 @@
+# For the general syntax of property based configuration files see the
+# documenation of org.apache.log4j.PropertyConfigurator.
+
+# The root category uses the appender called A1. Since no priority is
+# specified, the root category assumes the default priority for root
+# which is DEBUG in log4j. The root category is the only category that
+# has a default priority. All other categories need not be assigned a
+# priority in which case they inherit their priority from the
+# hierarchy.
+
+log4j.rootCategory=, A1
+
+# A1 is set to be a LF5Appender which outputs to a swing
+# logging console.
+
+log4j.appender.A1=org.apache.log4j.net.SocketAppender
+log4j.appender.A1.RemoteHost=localhost
+log4j.appender.A1.Port=8887
diff --git a/examples/lf5/UsingSocketAppenders/socketserver.properties b/examples/lf5/UsingSocketAppenders/socketserver.properties
new file mode 100644
index 0000000..da14ac0
--- /dev/null
+++ b/examples/lf5/UsingSocketAppenders/socketserver.properties
@@ -0,0 +1,19 @@
+# For the general syntax of property based configuration files see the
+# documenation of org.apache.log4j.PropertyConfigurator.
+
+# The root category uses the appender called A1. Since no priority is
+# specified, the root category assumes the default priority for root
+# which is DEBUG in log4j. The root category is the only category that
+# has a default priority. All other categories need not be assigned a
+# priority in which case they inherit their priority from the
+# hierarchy.
+
+#log4j.rootCategory=DEBUG, A1
+log4j.rootCategory=, A1
+
+# A1 is set to be a LF5Appender which outputs to a swing
+# logging console.
+
+#log4j.category.org.apache.log4j.net.SocketNode=DEBUG
+log4j.appender.A1=org.apache.log4j.lf5.LF5Appender
+log4j.appender.A1.MaxNumberOfRecords=700
\ No newline at end of file
diff --git a/examples/lf5/index.html b/examples/lf5/index.html
new file mode 100644
index 0000000..9a39752
--- /dev/null
+++ b/examples/lf5/index.html
@@ -0,0 +1,11 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+ <head>
+ </head>
+ <body bgcolor="#FFFFFF" text="#000000">
+
+ <p>See <a href="../../docs/lf5/examples.html">Examples</a>
+ section in the LogFactor5 user guide.
+ </p>
+ </body>
+</html>
diff --git a/examples/mycat.bad b/examples/mycat.bad
index 86ef942..fcfdc61 100644
--- a/examples/mycat.bad
+++ b/examples/mycat.bad
@@ -1,16 +1,18 @@
# The usual stuff. Note that A1 is configured in root not in "some.cat"
-log4j.rootCategory=DEBUG, A1
+log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%5p [%t] %c - %m%n
# Set the priority of "some.cat" to TRACE (defined in
-# org.apache.log4j.xml.examples.XPriority). This will actually have
-# the side effect of instanciating a category object having the name
-# "some.cat" this will cause a ClassCastException if the category
-# object is cast as a MyCategory object.
+# examples.customLevel.XLevel). This will actually have the side
+# effect of instanciating a logger object having the name "some.cat"
+# this will cause a ClassCastException if the logger object is cast
+# as a MyLogger object.
+
+log4j.logger.some.cat=TRACE#examples.customLevel.XLevel
+
-log4j.category.some.cat=TRACE#org.apache.log4j.xml.examples.XPriority
diff --git a/examples/mycat.good b/examples/mycat.good
index 6d08136..c2e02ee 100644
--- a/examples/mycat.good
+++ b/examples/mycat.good
@@ -1,13 +1,13 @@
-# Setting the category factory to MyCategoryFactory solves the
+# Setting the logger factory to MyLoggerFactory solves the
# ClassCastException problem encountered with the "mycat.bad"
# configuration file.
-log4j.categoryFactory=org.apache.log4j.examples.MyCategoryFactory
+log4j.loggerFactory=examples.subclass.MyLoggerFactory
# The usual stuff. Note that A1 is configured in root not in "some.cat"
-log4j.rootCategory=DEBUG, A1
+log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
@@ -15,10 +15,10 @@ log4j.appender.A1.layout.ConversionPattern=%5p [%t] %c - %m%n
# Set the priority of "some.cat" to TRACE (defined in
-# org.apache.log4j.xml.examples.XPriority). Since we specified
-# MyCategoryFactory as the category factory, the following line willl
-# also have the side effect of instanciating a MyCategory object
-# having the name "some.cat".
+# examples.customLevel.XLevel). Since we specified MyLoggerFactory as
+# the logger factory, the following line willl also have the side
+# effect of instanciating a MyLogger object having the name
+# "some.cat".
-log4j.category.some.cat=TRACE#org.apache.log4j.xml.examples.XPriority
+log4j.logger.some.cat=TRACE#examples.customLevel.XLevel
diff --git a/examples/subclass/MyLogger.java b/examples/subclass/MyLogger.java
index e91c46f..521dea5 100644
--- a/examples/subclass/MyLogger.java
+++ b/examples/subclass/MyLogger.java
@@ -50,16 +50,6 @@ public class MyLogger extends Logger {
}
/**
- This method overrides {@link Logger#getInstance} by supplying
- its own factory type as a parameter.
- */
- public
- static
- Category getInstance(String name) {
- return Logger.getLogger(name, myFactory);
- }
-
- /**
This method overrides {@link Logger#getLogger} by supplying
its own factory type as a parameter.
*/
diff --git a/examples/subclass/MyLoggerTest.java b/examples/subclass/MyLoggerTest.java
index 4f1ffa1..5c69dea 100644
--- a/examples/subclass/MyLoggerTest.java
+++ b/examples/subclass/MyLoggerTest.java
@@ -58,7 +58,7 @@ public class MyLoggerTest {
usage("Incorrect number of parameters.");
}
try {
- MyLogger c = (MyLogger) MyLogger.getInstance("some.cat");
+ MyLogger c = (MyLogger) MyLogger.getLogger("some.cat");
c.trace("Hello");
c.debug("Hello");
} catch(ClassCastException e) {
diff --git a/slf4j.xml b/slf4j.xml
new file mode 100644
index 0000000..c314fb5
--- /dev/null
+++ b/slf4j.xml
@@ -0,0 +1,82 @@
+<project name="slf4j" default="usage" basedir="." >
+
+ <!-- The directory where source files are stored. -->
+ <property name="java.source.dir" value="./src/java/"/>
+
+ <!-- Destination for compiled files -->
+ <property name="javac.dest" value="./classes"/>
+
+ <!-- The directory where source files are stored. -->
+ <property name="version" value="1.0alpha"/>
+
+ <!-- Deprecation warning? -->
+ <property name="deprecation" value="on"/>
+
+
+ <property name="SLF4J_STEM" value="org/slf4j"/>
+
+
+ <!-- ================================================================= -->
+ <!-- Default target -->
+ <!-- ================================================================= -->
+ <target name="usage">
+ <echo>
+ These are some of the targets supported by this ANT build scpript:
+
+ svnCheckout - get SLF4J files into src/filtered-java
+
+ refresh-slf4j - copy source files into the log4j source tree, using
+ variable substitution
+ </echo>
+ </target>
+
+ <target name="init">
+ <mkdir dir="tmp"/>
+ <mkdir dir="${java.source.dir}/${SLF4J_STEM}"/>
+ </target>
+
+ <!-- ================================================================= -->
+ <!-- Remove all generated (compiled) class files. -->
+ <!-- ================================================================= -->
+ <target name="clean" description="Delete all compiled SLF4J files.">
+ <delete dir="${javac.dest}/org/slf4j" />
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Copy SLF4J files into log4j source tree. This step is necessary for -->
+ <!-- building log4j. However, it needs to be done whenever code in SLF4J -->
+ <!-- changes, that is seldom -->
+ <!-- =================================================================== -->
+ <target name="refresh-slf4j" depends="init, svnCheckout">
+ <!-- delete any stale copy of LoggerFactory.java -->
+ <delete>
+ <fileset dir="src/java/org/slf4j"
+ includes="**/*.java"
+ excludes="impl/Log4jLoggerFA.java"/>
+ </delete>
+
+ <!-- copy a filtered version of slf4j to tmp/src -->
+ <copy todir="src/java">
+ <fileset dir="src/filtered-java">
+ <include name="**/*.java"/>
+ <exclude name="**/impl/JDK14*.java"/>
+ </fileset>
+ <filterset><filter token="IMPL" value="Log4j"/></filterset>
+ </copy>
+ </target>
+
+
+ <target name="svnCheckout">
+ <property name="repository.URL" value="http://svn.slf4j.org/repos/slf4j/trunk/src/filtered-java"/>
+ <java classname="org.tmatesoft.svn.cli.SVN" dir="src/" fork="true">
+ <arg value="co"/>
+ <arg value="${repository.URL}"/>
+ <arg value="filtered-java"/>
+ <classpath>
+ <pathelement location="lib/javasvn.jar" />
+ <pathelement location="lib/javasvn-cli.jar" />
+ </classpath>
+ </java>
+ </target>
+
+</project>
diff --git a/src/filtered-java/org/slf4j/LoggerFactory.java b/src/filtered-java/org/slf4j/LoggerFactory.java
new file mode 100644
index 0000000..e4bb471
--- /dev/null
+++ b/src/filtered-java/org/slf4j/LoggerFactory.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2004-2005 SLF4J.ORG
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+ * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ *
+ */
+
+package org.slf4j;
+
+// WARNING
+// WARNING Modifications MUST be made to the original file found at
+// WARNING $SLF4J_HOME/src/filtered-java/org/slf4j/LoggerFactory.java
+// WARNING
+
+/**
+ * The <code>LoggerFactory</code> can produce Loggers for various logging APIs,
+ * most notably for log4j, JDK 1.4 logging. Other implemenations such as
+ * {@link org.slf4j.impl.NOPLogger NOPLogger} and
+ * {@link org.slf4j.impl.SimpleLogger SimpleLogger} are also supported.
+ *
+ * @author Ceki Gülcü
+ */
+public class LoggerFactory {
+ static LoggerFactoryAdapter adapter;
+
+ //
+ // WARNING Modify the original in
+ // $SLF4J_HOME/src/filtered-java/org/slf4j/
+
+ static {
+ String adapterClassStr = "org.slf4j.impl.@IMPL@LoggerFA";
+ System.out.println("SLF4J built for "+adapterClassStr);
+ try {
+ adapter = new org.slf4j.impl.@IMPL@LoggerFA();
+ } catch (Exception e) {
+ // unless there was a problem with the build or the JVM we will never
+ // get exceptions
+ System.err.println(
+ "Could not instantiate instance of class [" + adapterClassStr + "]");
+ e.printStackTrace();
+ }
+ }
+
+ public static ULogger getLogger(String name) {
+ return adapter.getLogger(name);
+ }
+
+ public static ULogger getLogger(String domainName, String subDomainName) {
+ return adapter.getLogger(domainName, subDomainName);
+ }
+
+ public static ULogger getLogger(Class clazz) {
+ return adapter.getLogger(clazz.getName());
+ }
+
+ public static ULogger getLogger(Class clazz, String subDomainName) {
+ return adapter.getLogger(clazz.getName(), subDomainName);
+ }
+}
diff --git a/src/filtered-java/org/slf4j/LoggerFactoryAdapter.java b/src/filtered-java/org/slf4j/LoggerFactoryAdapter.java
new file mode 100644
index 0000000..55b047e
--- /dev/null
+++ b/src/filtered-java/org/slf4j/LoggerFactoryAdapter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2004-2005 SLF4J.ORG
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+ * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ *
+ */
+
+package org.slf4j;
+
+/**
+ * LoggerFactoryAdapter interface is used internally by {@link
+ * LoggerFactory}.
+ *
+ * <p>Only developers wishing to write new UGLI adapters need to worry
+ * about this interface.
+ *
+ * @author Ceki Gülcü
+ *
+ */
+public interface LoggerFactoryAdapter {
+
+ /**
+ * Return the appropriate named {@link ULogger} instance.
+ */
+ public ULogger getLogger(String name);
+
+ /**
+ * Return a {@link ULogger} instance in <code>domain</code>, <code>subDomain</code>.
+ *
+ * @param domain
+ * @param subDomain
+ * @return ULogger instance
+ */
+ public ULogger getLogger(String domain, String subDomain);
+}
diff --git a/src/filtered-java/org/slf4j/ULogger.java b/src/filtered-java/org/slf4j/ULogger.java
new file mode 100644
index 0000000..279178e
--- /dev/null
+++ b/src/filtered-java/org/slf4j/ULogger.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2004-2005 SLF4J.ORG
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+ * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ *
+ */
+
+package org.slf4j;
+
+/**
+ *
+ * The main user inteface to logging. It is expected that logging
+ * takes places through concerete implemetations of the ULogger
+ * interface.
+ *
+ * @author Ceki Gülcü
+ */
+public interface ULogger {
+
+ /**
+ * Is the logger instance enabled for the DEBUG level?
+ * @return True if this ULogger is enabled for the DEBUG level,
+ * false otherwise.
+ */
+ public boolean isDebugEnabled();
+
+ /**
+ * Log a message object with the DEBUG level.
+ * @param msg - the message object to be logged
+ */
+ public void debug(Object msg);
+
+
+ /**
+ * Log a parameterized message object at the DEBUG level.
+ *
+ * <p>This form is useful in avoiding the superflous object creation
+ * problem when invoking this method while it is disabled.
+ * </p>
+ * @param parameterizedMsg - the parameterized message object
+ * @param param1 - the parameter
+ */
+ public void debug(Object parameterizedMsg, Object param1);
+
+ /**
+ * Log a parameterized message object at the DEBUG level.
+ *
+ * <p>This form is useful in avoiding the superflous object creation
+ * problem when invoking this method while it is disabled.
+ * </p>
+ * @param parameterizedMsg - the parameterized message object
+ * @param param1 - the first parameter
+ * @param param2 - the second parameter
+ */
+ public void debug(String parameterizedMsg, Object param1, Object param2);
+ public void debug(Object msg, Throwable t);
+
+
+ public boolean isInfoEnabled();
+ public void info(Object msg);
+ public void info(Object parameterizedMsg, Object param1);
+ public void info(String parameterizedMsg, Object param1, Object param2);
+ public void info(Object msg, Throwable t);
+
+
+ public boolean isWarnEnabled();
+ public void warn(Object msg);
+ public void warn(Object parameterizedMsg, Object param1);
+ public void warn(String parameterizedMsg, Object param1, Object param2);
+ public void warn(Object msg, Throwable t);
+
+
+ public boolean isErrorEnabled();
+ public void error(Object msg);
+ public void error(Object parameterizedMsg, Object param1);
+ public void error(String parameterizedMsg, Object param1, Object param2);
+ public void error(Object msg, Throwable t);
+
+}
diff --git a/src/filtered-java/org/slf4j/impl/JDK14Logger.java b/src/filtered-java/org/slf4j/impl/JDK14Logger.java
new file mode 100644
index 0000000..9ae8506
--- /dev/null
+++ b/src/filtered-java/org/slf4j/impl/JDK14Logger.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2004-2005 SLF4J.ORG
+ * Copyright (c) 2004-2005 QOS.ch
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+ * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ *
+ */
+
+package org.slf4j.impl;
+import org.slf4j.ULogger;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * A wrapper over @{link java.utill.Logger} which conforms to the
+ * {@link ULogger} interface.
+ *
+ * @author Ceki Gülcü
+ */
+public class JDK14Logger implements ULogger {
+ final Logger logger;
+
+ // WARN: JDK14Logger constructor should have only package access so that
+ // only JDK14LoggerFA be able to create one.
+ JDK14Logger(Logger logger) {
+ this.logger = logger;
+ }
+
+ /**
+ * Is the logger instance enabled for the DEBUG level?
+ * @return
+ */
+ public boolean isDebugEnabled() {
+ return logger.isLoggable(Level.FINE);
+ }
+
+ //
+
+ /**
+ * Log a message object with the DEBUG level.
+ * @param msg - the message object to be logged
+ */
+ public void debug(Object msg) {
+ logger.fine(String.valueOf(msg));
+ }
+
+ /**
+ * Log a parameterized message object at the DEBUG level.
+ *
+ * <p>This form is useful in avoiding the superflous object creation
+ * problem when invoking this method while it is disabled.
+ * </p>
+ * @param parameterizedMsg - the parameterized message object
+ * @param param1 - the parameter
+ */
+ public void debug(Object parameterizedMsg, Object param1) {
+ if (logger.isLoggable(Level.FINE)) {
+ if (parameterizedMsg instanceof String) {
+ String msgStr = (String) parameterizedMsg;
+ msgStr = MessageFormatter.format(msgStr, param1);
+ logger.fine(msgStr);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should not happen.
+ logger.fine(parameterizedMsg.toString());
+ }
+ }
+ }
+
+ /**
+ * Log a parameterized message object at the DEBUG level.
+ *
+ * <p>This form is useful in avoiding the superflous object creation
+ * problem when invoking this method while it is disabled.
+ * </p>
+ * @param parameterizedMsg - the parameterized message object
+ * @param param1 - the first parameter
+ * @param param2 - the second parameter
+ */
+ public void debug(String parameterizedMsg, Object param1, Object param2) {
+ if (logger.isLoggable(Level.FINE)) {
+ if (parameterizedMsg instanceof String) {
+ String msgStr = (String) parameterizedMsg;
+ msgStr = MessageFormatter.format(msgStr, param1, param2);
+ logger.fine(msgStr);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should not happen.
+ logger.fine(parameterizedMsg.toString());
+ }
+ }
+ }
+
+ public void debug(Object msg, Throwable t) {
+ logger.log(Level.FINE, msg.toString(), t);
+ }
+
+ public boolean isInfoEnabled() {
+ return logger.isLoggable(Level.INFO);
+ }
+
+ public void info(Object msg) {
+ logger.info(msg.toString());
+ }
+
+ public void info(Object parameterizedMsg, Object param1) {
+ if (logger.isLoggable(Level.INFO)) {
+ if (parameterizedMsg instanceof String) {
+ String msgStr = (String) parameterizedMsg;
+ msgStr = MessageFormatter.format(msgStr, param1);
+ logger.info(msgStr);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should not happen.
+ logger.info(parameterizedMsg.toString());
+ }
+ }
+ }
+
+ public void info(String parameterizedMsg, Object param1, Object param2) {
+ if (logger.isLoggable(Level.INFO)) {
+ if (parameterizedMsg instanceof String) {
+ String msgStr = (String) parameterizedMsg;
+ msgStr = MessageFormatter.format(msgStr, param1, param2);
+ logger.info(msgStr);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should not happen.
+ logger.info(parameterizedMsg.toString());
+ }
+ }
+ }
+
+ public void info(Object msg, Throwable t) {
+ logger.log(Level.INFO, msg.toString(), t);
+ }
+
+ public boolean isWarnEnabled() {
+ return logger.isLoggable(Level.WARNING);
+ }
+
+ public void warn(Object msg) {
+ logger.warning(msg.toString());
+ }
+
+ public void warn(Object parameterizedMsg, Object param1) {
+ if (logger.isLoggable(Level.WARNING)) {
+ if (parameterizedMsg instanceof String) {
+ String msgStr = (String) parameterizedMsg;
+ msgStr = MessageFormatter.format(msgStr, param1);
+ logger.warning(msgStr);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should not happen.
+ logger.warning(parameterizedMsg.toString());
+ }
+ }
+ }
+
+ public void warn(String parameterizedMsg, Object param1, Object param2) {
+ if (logger.isLoggable(Level.WARNING)) {
+ if (parameterizedMsg instanceof String) {
+ String msgStr = (String) parameterizedMsg;
+ msgStr = MessageFormatter.format(msgStr, param1, param2);
+ logger.warning(msgStr);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should not happen.
+ logger.warning(parameterizedMsg.toString());
+ }
+ }
+ }
+
+ public void warn(Object msg, Throwable t) {
+ logger.log(Level.WARNING, msg.toString(), t);
+ }
+
+ public boolean isErrorEnabled() {
+ return logger.isLoggable(Level.SEVERE);
+ }
+
+ public void error(Object msg) {
+ logger.severe(msg.toString());
+ }
+
+ public void error(Object parameterizedMsg, Object param1) {
+ if (logger.isLoggable(Level.WARNING)) {
+ if (parameterizedMsg instanceof String) {
+ String msgStr = (String) parameterizedMsg;
+ msgStr = MessageFormatter.format(msgStr, param1);
+ logger.severe(msgStr);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should not happen.
+ logger.severe(parameterizedMsg.toString());
+ }
+ }
+ }
+
+ public void error(String parameterizedMsg, Object param1, Object param2) {
+ if (logger.isLoggable(Level.WARNING)) {
+ if (parameterizedMsg instanceof String) {
+ String msgStr = (String) parameterizedMsg;
+ msgStr = MessageFormatter.format(msgStr, param1, param2);
+ logger.severe(msgStr);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should not happen.
+ logger.severe(parameterizedMsg.toString());
+ }
+ }
+ }
+ public void error(Object msg, Throwable t) {
+ logger.log(Level.SEVERE, msg.toString(), t);
+ }
+}
diff --git a/src/filtered-java/org/slf4j/impl/JDK14LoggerFA.java b/src/filtered-java/org/slf4j/impl/JDK14LoggerFA.java
new file mode 100644
index 0000000..b90154c
--- /dev/null
+++ b/src/filtered-java/org/slf4j/impl/JDK14LoggerFA.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2004-2005 SLF4J.ORG
+ * Copyright (c) 2004-2005 QOS.ch
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+ * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ *
+ */
+
+package org.slf4j.impl;
+
+import org.slf4j.LoggerFactoryAdapter;
+import org.slf4j.ULogger;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+
+/**
+ *
+ * @author Ceki Gülcü
+ */
+public class JDK14LoggerFA implements LoggerFactoryAdapter {
+ Map map;
+
+ public JDK14LoggerFA() {
+ map = new HashMap();
+ }
+
+ /* (non-Javadoc)
+ * @see org.slf4j.LoggerFactoryAdapter#getLogger(java.lang.String)
+ */
+ public ULogger getLogger(String name) {
+ ULogger ulogger = (ULogger) map.get(name);
+ if (ulogger == null) {
+ Logger logger = Logger.getLogger(name);
+ ulogger = new JDK14Logger(logger);
+ map.put(name, ulogger);
+ }
+ return ulogger;
+ }
+
+ /* (non-Javadoc)
+ * @see org.slf4j.LoggerFactoryAdapter#getLogger(java.lang.String, java.lang.String)
+ */
+ public ULogger getLogger(String domainName, String subDomainName) {
+ return getLogger(domainName);
+ }
+}
diff --git a/src/filtered-java/org/slf4j/impl/MessageFormatter.java b/src/filtered-java/org/slf4j/impl/MessageFormatter.java
new file mode 100644
index 0000000..c650c39
--- /dev/null
+++ b/src/filtered-java/org/slf4j/impl/MessageFormatter.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2004-2005 SLF4J.ORG
+ * Copyright (c) 2004-2005 QOS.ch
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+ * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ *
+ */
+
+package org.slf4j.impl;
+
+
+/**
+ * Formats messages according to very simple rules.
+ * See {@link #format(String, Object)} and
+ * {@link #format(String, Object, Object)} for more details.
+ *
+ * @author Ceki Gülcü
+ */
+public class MessageFormatter {
+ static final char DELIM_START = '{';
+ static final char DELIM_STOP = '}';
+
+ /**
+ * Performs single argument substitution for the 'messagePattern' passed as
+ * parameter.
+ * <p>
+ * For example, <code>MessageFormatter.format("Hi {}.", "there");</code> will
+ * return the string "Hi there.".
+ * <p>
+ * The {} pair is called the formatting element. It serves to designate the
+ * location where the argument needs to be inserted within the pattern.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param argument The argument to be inserted instead of the formatting element
+ * @return The formatted message
+ */
+ public static String format(String messagePattern, Object argument) {
+ int j = messagePattern.indexOf(DELIM_START);
+ int len = messagePattern.length();
+ char escape = 'x';
+
+ // if there are no { characters or { is the last character of the messsage
+ // then we just return messagePattern
+ if (j == -1 || (j+1 == len)) {
+ return messagePattern;
+ } else {
+ if(j+1 == len) {
+ }
+
+ char delimStop = messagePattern.charAt(j + 1);
+ if (j > 0) {
+ escape = messagePattern.charAt(j - 1);
+ }
+ if ((delimStop != DELIM_STOP) || (escape == '\\')) {
+ // invalid DELIM_START/DELIM_STOP pair or espace character is
+ // present
+ return messagePattern;
+ } else {
+ StringBuffer sbuf = new StringBuffer(len + 20);
+ sbuf.append(messagePattern.substring(0, j));
+ sbuf.append(argument);
+ sbuf.append(messagePattern.substring(j + 2));
+ return sbuf.toString();
+ }
+ }
+ }
+
+ /**
+ * /**
+ * Performs a two argument substitution for the 'messagePattern' passed as
+ * parameter.
+ * <p>
+ * For example, <code>MessageFormatter.format("Hi {}. My name is {}.",
+ * "there", "David");</code> will return the string "Hi there. My name is David.".
+ * <p>
+ * The '{}' pair is called a formatting element. It serves to designate the
+ * location where the arguments need to be inserted within the message pattern.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arg1 The first argument to replace the first formatting element
+ * @param arg2 The second argument to replace the second formatting element
+ * @return The formatted message
+ */
+ public static String format(String messagePattern, Object arg1, Object arg2) {
+ int i = 0;
+ int len = messagePattern.length();
+ int j = messagePattern.indexOf(DELIM_START);
+
+ StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);
+
+ for (int L = 0; L < 2; L++) {
+ j = messagePattern.indexOf(DELIM_START, i);
+
+ if (j == -1 || (j+1 == len)) {
+ // no more variables
+ if (i == 0) { // this is a simple string
+ return messagePattern;
+ } else { // add the tail string which contains no variables and return the result.
+ sbuf.append(messagePattern.substring(i, messagePattern.length()));
+ return sbuf.toString();
+ }
+ } else {
+ char delimStop = messagePattern.charAt(j + 1);
+ if ((delimStop != DELIM_STOP)) {
+ // invalid DELIM_START/DELIM_STOP pair
+ sbuf.append(messagePattern.substring(i, messagePattern.length()));
+ return sbuf.toString();
+ }
+ sbuf.append(messagePattern.substring(i, j));
+ sbuf.append((L == 0) ? arg1 : arg2);
+ i = j + 2;
+ }
+ }
+ // append the characters following the second {} pair.
+ sbuf.append(messagePattern.substring(i, messagePattern.length()));
+ return sbuf.toString();
+ }
+}
diff --git a/src/filtered-java/org/slf4j/impl/NOPLogger.java b/src/filtered-java/org/slf4j/impl/NOPLogger.java
new file mode 100644
index 0000000..d0c4820
--- /dev/null
+++ b/src/filtered-java/org/slf4j/impl/NOPLogger.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2004-2005 SLF4J.ORG
+ * Copyright (c) 2004-2005 QOS.ch
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+ * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ *
+ */
+
+package org.slf4j.impl;
+
+import org.slf4j.ULogger;
+
+
+/**
+ * A no operation (NOP) implementation of {@link ULogger}.
+ *
+ * @author Ceki Gülcü
+ */
+public class NOPLogger implements ULogger {
+
+ /**
+ * The unique instance of NOPLogger.
+ */
+ public final static NOPLogger NOP_LOGGER = new NOPLogger();
+
+ /**
+ * There is no point in people creating multiple instances of NullLogger.
+ * Hence, the private access modifier.
+ */
+ private NOPLogger() {
+ }
+
+ /* Always returns false.
+ *
+ * @see org.slf4j.Logger#isDebugEnabled()
+ */
+ public boolean isDebugEnabled() {
+ return false;
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#debug(java.lang.Object)
+ */
+ public void debug(Object msg) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#debug(java.lang.Object, java.lang.Object)
+ */
+ public void debug(Object parameterizedMsg, Object param1) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#debug(java.lang.Object, java.lang.Object, java.lang.Object)
+ */
+ public void debug(String parameterizedMsg, Object param1, Object param2) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#debug(java.lang.Object, java.lang.Throwable)
+ */
+ public void debug(Object msg, Throwable t) {
+ // NOP
+ }
+
+ /* Always returns false.
+ * @see org.slf4j.Logger#isInfoEnabled()
+ */
+ public boolean isInfoEnabled() {
+ // NOP
+ return false;
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#info(java.lang.Object)
+ */
+ public void info(Object msg) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#info(java.lang.Object, java.lang.Object)
+ */
+ public void info(Object parameterizedMsg, Object param1) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#info(java.lang.Object, java.lang.Object, java.lang.Object)
+ */
+ public void info(String parameterizedMsg, Object param1, Object param2) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#info(java.lang.Object, java.lang.Throwable)
+ */
+ public void info(Object msg, Throwable t) {
+ // NOP
+ }
+
+ /* Always returns false.
+ * @see org.slf4j.Logger#isWarnEnabled()
+ */
+ public boolean isWarnEnabled() {
+ return false;
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#warn(java.lang.Object)
+ */
+ public void warn(Object msg) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#warn(java.lang.Object, java.lang.Object)
+ */
+ public void warn(Object parameterizedMsg, Object param1) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#warn(java.lang.Object, java.lang.Object, java.lang.Object)
+ */
+ public void warn(String parameterizedMsg, Object param1, Object param2) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#warn(java.lang.Object, java.lang.Throwable)
+ */
+ public void warn(Object msg, Throwable t) {
+ // NOP
+ }
+
+ /* Always returns false.
+ * @see org.slf4j.Logger#isErrorEnabled()
+ */
+ public boolean isErrorEnabled() {
+ return false;
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#error(java.lang.Object)
+ */
+ public void error(Object msg) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#error(java.lang.Object, java.lang.Object)
+ */
+ public void error(Object parameterizedMsg, Object param1) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#error(java.lang.Object, java.lang.Object, java.lang.Object)
+ */
+ public void error(String parameterizedMsg, Object param1, Object param2) {
+ // NOP
+ }
+
+ /* A NOP implementation.
+ * @see org.slf4j.Logger#error(java.lang.Object, java.lang.Throwable)
+ */
+ public void error(Object msg, Throwable t) {
+ // NOP
+ }
+
+}
diff --git a/src/filtered-java/org/slf4j/impl/NOPLoggerFA.java b/src/filtered-java/org/slf4j/impl/NOPLoggerFA.java
new file mode 100644
index 0000000..2d321ad
--- /dev/null
+++ b/src/filtered-java/org/slf4j/impl/NOPLoggerFA.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2004-2005 SLF4J.ORG
+ * Copyright (c) 2004-2005 QOS.ch
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+ * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ *
+ */
+
+package org.slf4j.impl;
+
+import org.slf4j.LoggerFactoryAdapter;
+import org.slf4j.ULogger;
+
+
+/**
+ * NOPLoggerFA is am implementation of {@link LoggerFactoryAdapter}
+ * which always returns the unique instance of NOPLogger.
+ *
+ * @author Ceki Gulcu
+ */
+public class NOPLoggerFA implements LoggerFactoryAdapter {
+
+ public NOPLoggerFA() {
+ // nothing to do
+ }
+
+ public ULogger getLogger(String name) {
+ return NOPLogger.NOP_LOGGER;
+ }
+ public ULogger getLogger(String domainName, String subDomainName) {
+ return NOPLogger.NOP_LOGGER;
+ }
+}
diff --git a/src/filtered-java/org/slf4j/impl/SimpleLogger.java b/src/filtered-java/org/slf4j/impl/SimpleLogger.java
new file mode 100644
index 0000000..7b8be4a
--- /dev/null
+++ b/src/filtered-java/org/slf4j/impl/SimpleLogger.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2004-2005 SLF4J.ORG
+ * Copyright (c) 2004-2005 QOS.ch
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+ * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ *
+ */
+
+package org.slf4j.impl;
+
+import org.slf4j.ULogger;
+
+
+/**
+ * A simple implementation that logs messages of level INFO or higher on
+ * the console (<code>System.out<code>).
+ * <p>
+ * The output includes the relative time in milliseconds, thread name, the level,
+ * logger name, and the message followed by the line separator for the host.
+ * In log4j terms it amounts to the "%r [%t] %level %logger - %m%n" pattern.
+ * <pre>
+176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order.
+225 [main] INFO examples.SortAlgo - Entered the sort method.
+304 [main] INFO SortAlgo.DUMP - Dump of interger array:
+317 [main] INFO SortAlgo.DUMP - Element [0] = 0
+331 [main] INFO SortAlgo.DUMP - Element [1] = 1
+343 [main] INFO examples.Sort - The next log statement should be an error message.
+346 [main] ERROR SortAlgo.DUMP - Tried to dump an uninitialized array.
+ at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
+ at org.log4j.examples.Sort.main(Sort.java:64)
+467 [main] INFO examples.Sort - Exiting main method.
+</pre>
+ *
+ * @author Ceki Gülcü
+ */
+public class SimpleLogger implements ULogger {
+
+ String loggerName;
+
+ /**
+ * Mark the time when this class gets loaded into memory.
+ */
+ static private long startTime = System.currentTimeMillis();
+
+ public static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+ static private String INFO_STR = "INFO";
+ static private String WARN_STR = "WARN";
+ static private String ERROR_STR = "ERROR";
+
+ /**
+ * Package access allows only {@link SimpleLoggerFA} to instantiate
+ * SimpleLogger instances.
+ */
+ SimpleLogger(String name) {
+ this.loggerName = name;
+ }
+
+ /**
+ * Always returns false.
+ */
+ public boolean isDebugEnabled() {
+ return false;
+ }
+
+ /**
+ * A NOP implementation.
+ */
+ public void debug(Object msg) {
+ // NOP
+ }
+
+ /**
+ * A NOP implementation.
+ */
+ public void debug(Object parameterizedMsg, Object param1) {
+ // NOP
+ }
+
+ /**
+ * A NOP implementation.
+ */
+ public void debug(String parameterizedMsg, Object param1, Object param2) {
+ // NOP
+ }
+
+ /**
+ * A NOP implementation.
+ */
+ public void debug(Object msg, Throwable t) {
+ // NOP
+ }
+
+ /**
+ * This is our internal implementation for logging regular (non-parameterized)
+ * log messages.
+ *
+ * @param level
+ * @param message
+ * @param t
+ */
+ private void log(String level, String message, Throwable t) {
+ StringBuffer buf = new StringBuffer();
+
+ long millis = System.currentTimeMillis();
+ buf.append(millis-startTime);
+
+ buf.append(" [");
+ buf.append(Thread.currentThread().getName());
+ buf.append("] ");
+
+ buf.append(level);
+ buf.append(" ");
+
+ buf.append(loggerName);
+ buf.append(" - ");
+
+ buf.append(message);
+
+ buf.append(LINE_SEPARATOR);
+
+ System.out.print(buf.toString());
+ if(t != null) {
+ t.printStackTrace(System.out);
+ }
+ System.out.flush();
+ }
+ /**
+ * For parameterized messages, first substitute parameters and then log.
+ *
+ * @param level
+ * @param parameterizedMsg
+ * @param param1
+ * @param param2
+ */
+ private void parameterizedLog(String level, Object parameterizedMsg, Object param1, Object param2) {
+ if (parameterizedMsg instanceof String) {
+ String msgStr = (String) parameterizedMsg;
+ msgStr = MessageFormatter.format(msgStr, param1, param2);
+ log(level, msgStr, null);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should not happen.
+ log(level, parameterizedMsg.toString(), null);
+ }
+ }
+
+ /**
+ * Always returns true.
+ */
+ public boolean isInfoEnabled() {
+ return true;
+ }
+
+ /**
+ * A simple implementation which always logs messages of level INFO according
+ * to the format outlined above.
+ */
+ public void info(Object msg) {
+ log(INFO_STR, msg.toString(), null);
+ }
+
+
+ /**
+ * Perform single parameter substituion before logging the message of level
+ * INFO according to the format outlined above.
+ */
+ public void info(Object parameterizedMsg, Object param1) {
+ parameterizedLog(INFO_STR, parameterizedMsg, param1, null);
+ }
+
+ /**
+ * Perform double parameter substituion before logging the message of level
+ * INFO according to the format outlined above.
+ */
+
+ public void info(String parameterizedMsg, Object param1, Object param2) {
+ parameterizedLog(INFO_STR, parameterizedMsg, param1, param2);
+ }
+
+ /**
+ * Log a message of level INFO, including an exception.
+ */
+ public void info(Object msg, Throwable t) {
+ log(INFO_STR, msg.toString(), t);
+ }
+
+ /**
+ * Always returns true.
+ */
+ public boolean isWarnEnabled() {
+ return true;
+ }
+
+ /**
+ * A simple implementation which always logs messages of level WARN according
+ * to the format outlined above.
+ */
+ public void warn(Object msg) {
+ log(WARN_STR, msg.toString(), null);
+ }
+
+ /**
+ * Perform single parameter substituion before logging the message of level
+ * WARN according to the format outlined above.
+ */
+ public void warn(Object parameterizedMsg, Object param1) {
+ parameterizedLog(WARN_STR, parameterizedMsg, param1, null);
+ }
+
+ /**
+ * Perform double parameter substituion before logging the message of level
+ * WARN according to the format outlined above.
+ */
+ public void warn(String parameterizedMsg, Object param1, Object param2) {
+ parameterizedLog(WARN_STR, parameterizedMsg, param1, param2);
+ }
+
+ /**
+ * Log a message of level WARN, including an exception.
+ */
+ public void warn(Object msg, Throwable t) {
+ log(WARN_STR, msg.toString(), t);
+ }
+
+ /**
+ * Always returns true.
+ */
+ public boolean isErrorEnabled() {
+ return true;
+ }
+
+ /**
+ * A simple implementation which always logs messages of level ERROR acoording
+ * to the format outlined above.
+ */
+ public void error(Object msg) {
+ log(ERROR_STR, msg.toString(), null);
+ }
+
+
+ /**
+ * Perform single parameter substituion before logging the message of level
+ * ERROR according to the format outlined above.
+ */
+ public void error(Object parameterizedMsg, Object param1) {
+ parameterizedLog(ERROR_STR, parameterizedMsg, param1, null);
+ }
+
+ /**
+ * Perform double parameter substituion before logging the message of level
+ * ERROR according to the format outlined above.
+ */
+ public void error(String parameterizedMsg, Object param1, Object param2) {
+ parameterizedLog(ERROR_STR, parameterizedMsg, param1, param2);
+ }
+
+ /**
+ * Log a message of level ERROR, including an exception.
+ */
+ public void error(Object msg, Throwable t) {
+ log(ERROR_STR, msg.toString(), t);
+ }
+
+}
diff --git a/src/filtered-java/org/slf4j/impl/SimpleLoggerFA.java b/src/filtered-java/org/slf4j/impl/SimpleLoggerFA.java
new file mode 100644
index 0000000..6b04340
--- /dev/null
+++ b/src/filtered-java/org/slf4j/impl/SimpleLoggerFA.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2004-2005 SLF4J.ORG
+ * Copyright (c) 2004-2005 QOS.ch
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+ * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ *
+ */
+
+package org.slf4j.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.LoggerFactoryAdapter;
+import org.slf4j.ULogger;
+
+
+/**
+ * An implementation of {@link LoggerFactoryAdapter} which always returns
+ * {@link SimpleLogger} instances.
+ *
+ * @author Ceki Gülcü
+ */
+public class SimpleLoggerFA implements LoggerFactoryAdapter {
+
+ Map map;
+
+ public SimpleLoggerFA() {
+ map = new HashMap();
+ }
+
+
+ /**
+ * Return an appropriate {@link SimpleLogger} instance by name. At this time,
+ *
+ */
+ /**
+ * Return an appropriate {@link SimpleLogger} instance.
+ * */
+ public ULogger getLogger(String name) {
+ ULogger ulogger = (ULogger) map.get(name);
+ if(ulogger == null) {
+ ulogger = new SimpleLogger(name);
+ map.put(name, ulogger);
+ }
+ return ulogger;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.slf4j.LoggerFactoryAdapter#getLogger(java.lang.String, java.lang.String)
+ */
+ public ULogger getLogger(String domainName, String subDomainName) {
+ return getLogger(domainName);
+ }
+
+
+}
diff --git a/src/java/org/apache/log4j/Appender.java b/src/java/org/apache/log4j/Appender.java
index 3642811..aa8a310 100644
--- a/src/java/org/apache/log4j/Appender.java
+++ b/src/java/org/apache/log4j/Appender.java
@@ -73,7 +73,7 @@ public interface Appender {
/**
Set the {@link ErrorHandler} for this appender.
- @ since 0.9.0
+ @since 0.9.0
*/
public
void setErrorHandler(ErrorHandler errorHandler);
diff --git a/src/java/org/apache/log4j/AppenderSkeleton.java b/src/java/org/apache/log4j/AppenderSkeleton.java
index caf95ba..d815fcd 100644
--- a/src/java/org/apache/log4j/AppenderSkeleton.java
+++ b/src/java/org/apache/log4j/AppenderSkeleton.java
@@ -17,13 +17,14 @@ import org.apache.log4j.helpers.LogLog;
/**
- Abstract superclass of the other appenders in the package.
-
- This class provides the code for common functionality, such as
- support for threshold filtering and support for general filters.
-
- @since 0.8.1
- @author Ceki Gülcü */
+ * Abstract superclass of the other appenders in the package.
+ *
+ * This class provides the code for common functionality, such as
+ * support for threshold filtering and support for general filters.
+ *
+ * @since 0.8.1
+ * @author Ceki Gülcü
+ * */
public abstract class AppenderSkeleton implements Appender, OptionHandler {
/** The layout variable does not need to be set if the appender
@@ -99,11 +100,10 @@ public abstract class AppenderSkeleton implements Appender, OptionHandler {
}
/**
- Finalize this appender by calling the imlenentation's
+ Finalize this appender by calling the derived class'
<code>close</code> method.
- @since 0.8.4
- */
+ @since 0.8.4 */
public
void finalize() {
// An appender might be closed then garbage collected. There is no
@@ -191,11 +191,10 @@ public abstract class AppenderSkeleton implements Appender, OptionHandler {
/**
- This method performs threshold checks and invokes filters before
- delegating actual logging to the subclasses specific {@link
- AppenderSkeleton#append} method.
-
- */
+ * This method performs threshold checks and invokes filters before
+ * delegating actual logging to the subclasses specific {@link
+ * AppenderSkeleton#append} method.
+ * */
public
synchronized
void doAppend(LoggingEvent event) {
@@ -204,7 +203,7 @@ public abstract class AppenderSkeleton implements Appender, OptionHandler {
return;
}
- if(!isAsSevereAsThreshold(event.level)) {
+ if(!isAsSevereAsThreshold(event.getLevel())) {
return;
}
diff --git a/src/java/org/apache/log4j/AsyncAppender.java b/src/java/org/apache/log4j/AsyncAppender.java
index e9fb7d6..33bc061 100644
--- a/src/java/org/apache/log4j/AsyncAppender.java
+++ b/src/java/org/apache/log4j/AsyncAppender.java
@@ -33,11 +33,7 @@ import java.util.Enumeration;
<p><b>Important note:</b> The <code>AsyncAppender</code> can only
be script configured using the {@link
- org.apache.log4j.xml.DOMConfigurator}. Refer to example configuration
- files <a href="xml/examples/doc-files/sample4.xml">sample4.xml</a>
- and <a href="xml/examples/doc-files/sample5.xml">sample5.xml</a>.
-
-
+ org.apache.log4j.xml.DOMConfigurator}.
@author Ceki Gülcü
@since 0.9.1 */
@@ -57,8 +53,7 @@ public class AsyncAppender extends AppenderSkeleton
boolean interruptedWarningMessage = false;
- public
- AsyncAppender() {
+ public AsyncAppender() {
// Note: The dispatcher code assumes that the aai is set once and
// for all.
aai = new AppenderAttachableImpl();
@@ -67,15 +62,13 @@ public class AsyncAppender extends AppenderSkeleton
}
- public
- void addAppender(Appender newAppender) {
+ public void addAppender(Appender newAppender) {
synchronized(aai) {
aai.addAppender(newAppender);
}
}
- public
- void append(LoggingEvent event) {
+ public void append(LoggingEvent event) {
// Set the NDC and thread name for the calling thread as these
// LoggingEvent fields were not set at event creation time.
event.getNDC();
@@ -114,8 +107,7 @@ public class AsyncAppender extends AppenderSkeleton
dispatcher thread which will process all pending events before
exiting.
*/
- public
- void close() {
+ public void close() {
synchronized(this) {
// avoid multiple close, otherwise one gets NullPointerException
if(closed) {
@@ -139,15 +131,13 @@ public class AsyncAppender extends AppenderSkeleton
bf = null;
}
- public
- Enumeration getAllAppenders() {
+ public Enumeration getAllAppenders() {
synchronized(aai) {
return aai.getAllAppenders();
}
}
- public
- Appender getAppender(String name) {
+ public Appender getAppender(String name) {
synchronized(aai) {
return aai.getAppender(name);
}
@@ -156,89 +146,80 @@ public class AsyncAppender extends AppenderSkeleton
/**
Returns the current value of the <b>LocationInfo</b> option.
*/
- public
- boolean getLocationInfo() {
+ public boolean getLocationInfo() {
return locationInfo;
}
/**
Is the appender passed as parameter attached to this category?
*/
- public
- boolean isAttached(Appender appender) {
+ public boolean isAttached(Appender appender) {
return aai.isAttached(appender);
}
/**
The <code>AsyncAppender</code> does not require a layout. Hence,
- this method always returns <code>false</code>. */
- public
- boolean requiresLayout() {
+ this method always returns <code>false</code>.
+ */
+ public boolean requiresLayout() {
return false;
}
- public
- void removeAllAppenders() {
+ public void removeAllAppenders() {
synchronized(aai) {
aai.removeAllAppenders();
}
}
- public
- void removeAppender(Appender appender) {
+ public void removeAppender(Appender appender) {
synchronized(aai) {
aai.removeAppender(appender);
}
}
- public
- void removeAppender(String name) {
+ public void removeAppender(String name) {
synchronized(aai) {
aai.removeAppender(name);
}
}
/**
- The <b>LocationInfo</b> option takes a boolean value. By
- default, it is set to false which means there will be no effort
- to extract the location information related to the event. As a
- result, the event that will be ultimately logged will likely to
- contain the wrong location information (if present in the log
- format).
-
- <p>Location information extraction is comparatively very slow and
- should be avoided unless performance is not a concern.
- */
- public
- void setLocationInfo(boolean flag) {
+ * The <b>LocationInfo</b> option takes a boolean value. By default,
+ * it is set to false which means there will be no effort to extract
+ * the location information related to the event. As a result, the
+ * event that will be ultimately logged will likely to contain the
+ * wrong location information (if present in the log format).
+ *
+ * <p>Location information extraction is comparatively very slow and
+ * should be avoided unless performance is not a concern.
+ * */
+ public void setLocationInfo(boolean flag) {
locationInfo = flag;
}
/**
- The <b>BufferSize</b> option takes a non-negative integer
- value. This integer value determines the maximum size of the
- bounded buffer. Increasing the size of the buffer is always
- safe. However, if an existing buffer holds unwritten elements,
- then <em>decreasing the buffer size will result in event
- loss.</em> Nevertheless, while script configuring the
- AsyncAppender, it is safe to set a buffer size smaller than the
- {@link #DEFAULT_BUFFER_SIZE default buffer size} because
- configurators guarantee that an appender cannot be used before
- being completely configured.
- */
- public
- void setBufferSize(int size) {
+ * The <b>BufferSize</b> option takes a non-negative integer value.
+ * This integer value determines the maximum size of the bounded
+ * buffer. Increasing the size of the buffer is always
+ * safe. However, if an existing buffer holds unwritten elements,
+ * then <em>decreasing the buffer size will result in event
+ * loss.</em> Nevertheless, while script configuring the
+ * AsyncAppender, it is safe to set a buffer size smaller than the
+ * {@link #DEFAULT_BUFFER_SIZE default buffer size} because
+ * configurators guarantee that an appender cannot be used before
+ * being completely configured.
+ * */
+ public void setBufferSize(int size) {
bf.resize(size);
}
/**
Returns the current value of the <b>BufferSize</b> option.
*/
- public
- int getBufferSize() {
+ public int getBufferSize() {
return bf.getMaxSize();
}
@@ -256,10 +237,14 @@ class Dispatcher extends Thread {
Dispatcher(BoundedFIFO bf, AsyncAppender container) {
this.bf = bf;
this.container = container;
- this.aai = container.aai;
+ this.aai = container.aai;
+ // It is the user's responsibility to close appenders before
+ // exiting.
+ this.setDaemon(true);
// set the dispatcher priority to lowest possible value
this.setPriority(Thread.MIN_PRIORITY);
this.setName("Dispatcher-"+getName());
+
// set the dispatcher priority to MIN_PRIORITY plus or minus 2
// depending on the direction of MIN to MAX_PRIORITY.
//+ (Thread.MAX_PRIORITY > Thread.MIN_PRIORITY ? 1 : -1)*2);
@@ -289,8 +274,7 @@ class Dispatcher extends Thread {
<p>Other approaches might yield better results.
*/
- public
- void run() {
+ public void run() {
//Category cat = Category.getInstance(Dispatcher.class.getName());
@@ -302,7 +286,7 @@ class Dispatcher extends Thread {
// Exit loop if interrupted but only if the the buffer is empty.
if(interrupted) {
//cat.info("Exiting.");
- return;
+ break;
}
try {
//LogLog.debug("Waiting for new event to dispatch.");
@@ -327,5 +311,8 @@ class Dispatcher extends Thread {
}
}
} // while
+
+ // close and remove all appenders
+ aai.removeAllAppenders();
}
}
diff --git a/src/java/org/apache/log4j/Category.java b/src/java/org/apache/log4j/Category.java
index 110b86d..f8dfdf4 100644
--- a/src/java/org/apache/log4j/Category.java
+++ b/src/java/org/apache/log4j/Category.java
@@ -31,42 +31,50 @@ import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
+import org.slf4j.impl.MessageFormatter;
/**
- <font color="#AA2222"><b>This class has been deprecated and
- replaced by the {@link Logger} <em>subclass</em>.</b></font> It
- will be kept around to preserve backward compatibility until mid
- 2003.
-
- <p><code>Logger</code> is a subclass of Category, i.e. it extends
- Category. In other words, a logger <em>is</em> a category. Thus,
- all operations that can be performed on a category can be performed
- on a logger. Whenever log4j is asked to produce a Category object,
- it will instead produce a Logger object. However, methods that
- previously accepted category objects still continue to accept
- category objects.
-
- <p>For example, the following are all legal and will work as expected.
-
+ * <font color="#AA2222"><b>This class has been deprecated and
+ * replaced by the {@link Logger} <em>subclass</em></b></font>. It
+ * will be kept around to preserve backward compatibility until mid
+ * 2003.
+ *
+ * <p><code>Logger</code> is a subclass of Category, i.e. it extends
+ * Category. In other words, a logger <em>is</em> a category. Thus,
+ * all operations that can be performed on a category can be
+ * performed on a logger. Internally, whenever log4j is asked to
+ * produce a Category object, it will instead produce a Logger
+ * object. Log4j 1.2 will <em>never</em> produce Category objects but
+ * only <code>Logger</code> instances. In order to preserve backward
+ * compatibility, methods that previously accepted category objects
+ * still continue to accept category objects.
+ *
+ * <p>For example, the following are all legal and will work as
+ * expected.
+ *
<pre>
- // Deprecated form:
- Category cat = Category.getInstance("foo.bar")
-
- // Preferred form for retrieving loggers:
- Logger logger = Logger.getLogger("foo.bar")
+ // Deprecated form:
+ Category cat = Category.getInstance("foo.bar")
+
+ // Preferred form for retrieving loggers:
+ Logger logger = Logger.getLogger("foo.bar")
</pre>
-
- <p>The first form is deprecated and should be avoided.
-
- <p><b>There is absolutely no need for new client code to use or
- refer to the <code>Category</code> class.</b> Whenever possible,
- please avoid referring to it or using it.
-
- <p>See the <a href="../../../../manual.html">short manual</a> for an
- introduction on this class.
-
- @author Ceki Gülcü
- @author Anders Kristensen */
+
+ * <p>The first form is deprecated and should be avoided.
+ *
+ * <p><b>There is absolutely no need for new client code to use or
+ * refer to the <code>Category</code> class.</b> Whenever possible,
+ * please avoid referring to it or using it.
+ *
+ * <p>See the <a href="../../../../manual.html">short manual</a> for an
+ * introduction on this class.
+ * <p>
+ * See the document entitled <a href="http://www.qos.ch/logging/preparingFor13.html">preparing
+ * for log4j 1.3</a> for a more detailed discussion.
+ *
+ * @author Ceki Gülcü
+ * @author Anders Kristensen
+ */
public class Category implements AppenderAttachable {
/**
@@ -77,9 +85,6 @@ public class Category implements AppenderAttachable {
//final Hierarchy defaultHierarchy = new Hierarchy(new
// RootCategory(Level.DEBUG));
-
- static int nooptimize;
-
/**
The name of this category.
*/
@@ -207,10 +212,10 @@ public class Category implements AppenderAttachable {
*/
synchronized
void closeNestedAppenders() {
- Enumeration enum = this.getAllAppenders();
- if(enum != null) {
- while(enum.hasMoreElements()) {
- Appender a = (Appender) enum.nextElement();
+ Enumeration enumeration = this.getAllAppenders();
+ if(enumeration != null) {
+ while(enumeration.hasMoreElements()) {
+ Appender a = (Appender) enumeration.nextElement();
if(a instanceof AppenderAttachable) {
a.close();
}
@@ -245,6 +250,60 @@ public class Category implements AppenderAttachable {
}
}
+ /**
+ * Log a message with the <code>DEBUG</code> level with message formatting
+ * done according to the value of <code>messagePattern</code> and
+ * <code>arg</code> parameters.
+ * <p>
+ * This form avoids superflous parameter construction. Whenever possible,
+ * you should use this form instead of constructing the message parameter
+ * using string concatenation.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arg The argument to replace the formatting element, i,e,
+ * the '{}' pair within <code>messagePattern</code>.
+ * @since 1.2.10
+ */
+ public void debug(Object messagePattern, Object arg) {
+ if (repository.isDisabled(Level.DEBUG_INT)) {
+ return;
+ }
+
+ if (Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {
+ if (messagePattern instanceof String){
+ String msgStr = (String) messagePattern;
+ msgStr = MessageFormatter.format(msgStr, arg);
+ forcedLog(FQCN, Level.DEBUG, msgStr, null);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should never happen.
+ forcedLog(FQCN, Level.DEBUG, messagePattern, null);
+ }
+ }
+ }
+
+ /**
+ * Log a message with the <code>DEBUG</code> level with message formatting
+ * done according to the messagePattern and the arguments arg1 and arg2.
+ * <p>
+ * This form avoids superflous parameter construction. Whenever possible,
+ * you should use this form instead of constructing the message parameter
+ * using string concatenation.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arg1 The first argument to replace the first formatting element
+ * @param arg2 The second argument to replace the second formatting element
+ * @since 1.2.10
+ */
+ public void debug(String messagePattern, Object arg1, Object arg2) {
+ if (repository.isDisabled(Level.DEBUG_INT)) {
+ return;
+ }
+ if (Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {
+ messagePattern = MessageFormatter.format(messagePattern, arg1, arg2);
+ forcedLog(FQCN, Level.DEBUG, messagePattern, null);
+ }
+ }
/**
Log a message object with the <code>DEBUG</code> level including
@@ -289,6 +348,62 @@ public class Category implements AppenderAttachable {
forcedLog(FQCN, Level.ERROR, message, null);
}
+
+/**
+ * Log a message with the <code>ERROR</code> level with message formatting
+ * done according to the value of <code>messagePattern</code> and
+ * <code>arg</code> parameters.
+ * <p>
+ * This form avoids superflous parameter construction. Whenever possible,
+ * you should use this form instead of constructing the message parameter
+ * using string concatenation.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arg The argument to replace the formatting element, i,e,
+ * the '{}' pair within <code>messagePattern</code>.
+ * @since 1.2.10
+ */
+ public void error(Object messagePattern, Object arg) {
+ if (repository.isDisabled(Level.ERROR_INT)) {
+ return;
+ }
+
+ if (Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel())) {
+ if (messagePattern instanceof String){
+ String msgStr = (String) messagePattern;
+ msgStr = MessageFormatter.format(msgStr, arg);
+ forcedLog(FQCN, Level.ERROR, msgStr, null);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should never happen.
+ forcedLog(FQCN, Level.ERROR, messagePattern, null);
+ }
+ }
+ }
+
+ /**
+ * Log a message with the <code>ERROR</code> level with message formatting
+ * done according to the messagePattern and the arguments arg1 and arg2.
+ * <p>
+ * This form avoids superflous parameter construction. Whenever possible,
+ * you should use this form instead of constructing the message parameter
+ * using string concatenation.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arg1 The first argument to replace the first formatting element
+ * @param arg2 The second argument to replace the second formatting element
+ * @since 1.2.10
+ */
+ public void error(String messagePattern, Object arg1, Object arg2) {
+ if (repository.isDisabled(Level.ERROR_INT)) {
+ return;
+ }
+ if (Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel())) {
+ messagePattern = MessageFormatter.format(messagePattern, arg1, arg2);
+ forcedLog(FQCN, Level.ERROR, messagePattern, null);
+ }
+ }
+
/**
Log a message object with the <code>ERROR</code> level including
the stack trace of the {@link Throwable} <code>t</code> passed as
@@ -315,7 +430,7 @@ public class Category implements AppenderAttachable {
@deprecated Please use {@link LogManager#exists} instead.
- @version 0.8.5 */
+ @since 0.8.5 */
public
static
Logger exists(String name) {
@@ -431,9 +546,10 @@ public class Category implements AppenderAttachable {
}
/**
-
- @deprecated Has been replaced by the {@link #getEffectiveLevel}
- method. */
+ *
+ * @deprecated Please use the the {@link #getEffectiveLevel} method
+ * instead.
+ * */
public
Priority getChainedPriority() {
for(Category c = this; c != null; c=c.parent) {
@@ -497,40 +613,20 @@ public class Category implements AppenderAttachable {
/**
- Retrieve a category with named as the <code>name</code>
- parameter. If the named category already exists, then the
- existing instance will be reutrned. Otherwise, a new instance is
- created.
-
- By default, categories do not have a set level but inherit
- it from the hierarchy. This is one of the central features of
- log4j.
-
- <b>Deprecated</b> Please use {@link Logger#getLogger(String)}
- instead.
-
- @param name The name of the category to retrieve. */
+ * @deprecated Make sure to use {@link Logger#getLogger(String)} instead.
+ */
public
static
Category getInstance(String name) {
- nooptimize++;
return LogManager.getLogger(name);
}
/**
- Shorthand for <code>getInstance(clazz.getName())</code>.
-
- @param clazz The name of <code>clazz</code> will be used as the
- name of the category to retrieve. See {@link
- #getInstance(String)} for more detailed information.
-
- <b>Deprecated</b> Please use {@link Logger#getLogger(Class)} instead.
-
- @since 1.0 */
+ * @deprecated Please make sure to use {@link Logger#getLogger(Class)} instead.
+ */
public
static
Category getInstance(Class clazz) {
- nooptimize++;
return LogManager.getLogger(clazz);
}
@@ -581,16 +677,7 @@ public class Category implements AppenderAttachable {
/**
- Return the root of the default category hierrachy.
-
- <p>The root category is always instantiated and available. It's
- name is "root".
-
- <p>Nevertheless, calling {@link #getInstance
- Category.getInstance("root")} does not retrieve the root category
- but a category just under root named "root".
-
- <b>Deprecated</b> Use {@link Logger#getRootLogger()} instead.
+ * @deprecated Please use {@link Logger#getRootLogger()} instead.
*/
final
public
@@ -679,6 +766,60 @@ public class Category implements AppenderAttachable {
}
/**
+ * Log a message with the <code>INFO</code> level with message formatting
+ * done according to the value of <code>messagePattern</code> and
+ * <code>arg</code> parameters.
+ * <p>
+ * This form avoids superflous parameter construction. Whenever possible,
+ * you should use this form instead of constructing the message parameter
+ * using string concatenation.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arg The argument to replace the formatting element, i,e,
+ * the '{}' pair within <code>messagePattern</code>.
+ * @since 1.2.10
+ */
+ public void info(Object messagePattern, Object arg) {
+ if (repository.isDisabled(Level.INFO_INT)) {
+ return;
+ }
+
+ if (Level.INFO.isGreaterOrEqual(this.getEffectiveLevel())) {
+ if (messagePattern instanceof String){
+ String msgStr = (String) messagePattern;
+ msgStr = MessageFormatter.format(msgStr, arg);
+ forcedLog(FQCN, Level.INFO, msgStr, null);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should never happen.
+ forcedLog(FQCN, Level.INFO, messagePattern, null);
+ }
+ }
+ }
+
+ /**
+ * Log a message with the <code>INFO</code> level with message formatting
+ * done according to the messagePattern and the arguments arg1 and arg2.
+ * <p>
+ * This form avoids superflous parameter construction. Whenever possible,
+ * you should use this form instead of constructing the message parameter
+ * using string concatenation.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arg1 The first argument to replace the first formatting element
+ * @param arg2 The second argument to replace the second formatting element
+ * @since 1.2.10
+ */
+ public void info(String messagePattern, Object arg1, Object arg2) {
+ if (repository.isDisabled(Level.INFO_INT)) {
+ return;
+ }
+ if (Level.INFO.isGreaterOrEqual(this.getEffectiveLevel())) {
+ messagePattern = MessageFormatter.format(messagePattern, arg1, arg2);
+ forcedLog(FQCN, Level.INFO, messagePattern, null);
+ }
+ }
+ /**
Log a message object with the <code>INFO</code> level including
the stack trace of the {@link Throwable} <code>t</code> passed as
parameter.
@@ -777,6 +918,33 @@ public class Category implements AppenderAttachable {
return Level.INFO.isGreaterOrEqual(this.getEffectiveLevel());
}
+ /**
+ Check whether this category is enabled for the info Level.
+ See also {@link #isDebugEnabled}.
+
+ @return boolean - <code>true</code> if this category is enabled
+ for level WARN, <code>false</code> otherwise.
+ @since 1.2.10
+ */
+ public boolean isWarnEnabled() {
+ if(repository.isDisabled(Level.WARN_INT))
+ return false;
+ return Level.WARN.isGreaterOrEqual(this.getEffectiveLevel());
+ }
+
+ /**
+ Check whether this category is enabled for the info Level.
+ See also {@link #isDebugEnabled}.
+
+ @return boolean - <code>true</code> if this category is enabled
+ for level ERROR, <code>false</code> otherwise.
+ @since 1.2.10
+ */
+ public boolean isErrorEnabled() {
+ if(repository.isDisabled(Level.ERROR_INT))
+ return false;
+ return Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel());
+ }
/**
Log a localized message. The user supplied parameter
@@ -1023,6 +1191,60 @@ public class Category implements AppenderAttachable {
forcedLog(FQCN, Level.WARN, message, null);
}
+ /**
+ * Log a message with the <code>WARN</code> level with message formatting
+ * done according to the value of <code>messagePattern</code> and
+ * <code>arg</code> parameters.
+ * <p>
+ * This form avoids superflous parameter construction. Whenever possible,
+ * you should use this form instead of constructing the message parameter
+ * using string concatenation.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arg The argument to replace the formatting element, i,e,
+ * the '{}' pair within <code>messagePattern</code>.
+ * @since 1.2.10
+ */
+ public void warn(Object messagePattern, Object arg) {
+ if (repository.isDisabled(Level.WARN_INT)) {
+ return;
+ }
+
+ if (Level.WARN.isGreaterOrEqual(this.getEffectiveLevel())) {
+ if (messagePattern instanceof String){
+ String msgStr = (String) messagePattern;
+ msgStr = MessageFormatter.format(msgStr, arg);
+ forcedLog(FQCN, Level.WARN, msgStr, null);
+ } else {
+ // To be failsafe, we handle the case where 'messagePattern' is not
+ // a String. Unless the user makes a mistake, this should never happen.
+ forcedLog(FQCN, Level.WARN, messagePattern, null);
+ }
+ }
+ }
+ /**
+ * Log a message with the <code>WARN</code> level with message formatting
+ * done according to the messagePattern and the arguments arg1 and arg2.
+ * <p>
+ * This form avoids superflous parameter construction. Whenever possible,
+ * you should use this form instead of constructing the message parameter
+ * using string concatenation.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arg1 The first argument to replace the first formatting element
+ * @param arg2 The second argument to replace the second formatting element
+ * @since 1.2.10
+ */
+ public void warn(String messagePattern, Object arg1, Object arg2) {
+ if (repository.isDisabled(Level.WARN_INT)) {
+ return;
+ }
+ if (Level.WARN.isGreaterOrEqual(this.getEffectiveLevel())) {
+ messagePattern = MessageFormatter.format(messagePattern, arg1, arg2);
+ forcedLog(FQCN, Level.WARN, messagePattern, null);
+ }
+ }
+
/**
Log a message with the <code>WARN</code> level including the
stack trace of the {@link Throwable} <code>t</code> passed as
diff --git a/src/java/org/apache/log4j/ConsoleAppender.java b/src/java/org/apache/log4j/ConsoleAppender.java
index fc14474..bd43ede 100644
--- a/src/java/org/apache/log4j/ConsoleAppender.java
+++ b/src/java/org/apache/log4j/ConsoleAppender.java
@@ -11,12 +11,12 @@ import java.io.OutputStreamWriter;
import org.apache.log4j.helpers.LogLog;
/**
- ConsoleAppender appends log events to <code>System.out</code> or
- <code>System.err</code> using a layout specified by the
- user. The default target is <code>System.out</code>.
-
- @author Ceki Gülcü
- @since 1.1 */
+ * ConsoleAppender appends log events to <code>System.out</code> or
+ * <code>System.err</code> using a layout specified by the user. The
+ * default target is <code>System.out</code>.
+ *
+ * @author Ceki Gülcü
+ * @since 1.1 */
public class ConsoleAppender extends WriterAppender {
public static final String SYSTEM_OUT = "System.out";
@@ -47,9 +47,10 @@ public class ConsoleAppender extends WriterAppender {
}
/**
- Sets the value of the <b>Target</b> option. Recognized values are
- "System.out" and "System.err". Any other value will be ignored.
- */
+ * Sets the value of the <b>Target</b> option. Recognized values
+ * are "System.out" and "System.err". Any other value will be
+ * ignored.
+ * */
public
void setTarget(String value) {
String v = value.trim();
@@ -64,12 +65,11 @@ public class ConsoleAppender extends WriterAppender {
}
/**
- Returns the current value of the <b>Target</b> property. The default
- value of the option is "System.out".
-
- See also {@link #setTarget}.
-
- */
+ * Returns the current value of the <b>Target</b> property. The
+ * default value of the option is "System.out".
+ *
+ * See also {@link #setTarget}.
+ * */
public
String getTarget() {
return target;
@@ -77,7 +77,7 @@ public class ConsoleAppender extends WriterAppender {
void targetWarn(String val) {
LogLog.warn("["+val+"] should be System.out or System.err.");
- LogLog.warn("Using System.out (default).");
+ LogLog.warn("Using previously set target, System.out by default.");
}
public
@@ -90,8 +90,10 @@ public class ConsoleAppender extends WriterAppender {
}
/**
- Override the parent method to do nothing.
- */
+ * This method overrides the parent {@link
+ * WriterAppender#closeWriter} implementation to do nothing because
+ * the console stream is not ours to close.
+ * */
protected
final
void closeWriter() {
diff --git a/src/java/org/apache/log4j/DailyRollingFileAppender.java b/src/java/org/apache/log4j/DailyRollingFileAppender.java
index c90a209..50d1e9e 100644
--- a/src/java/org/apache/log4j/DailyRollingFileAppender.java
+++ b/src/java/org/apache/log4j/DailyRollingFileAppender.java
@@ -52,11 +52,10 @@ import org.apache.log4j.spi.LoggingEvent;
<td><code>'.'yyyy-MM</code>
<td>Rollover at the beginning of each month</td>
- <td>Assuming the first day of the week is Sunday, at Sunday 00:00,
- March 25th, 2001, <code>/foo/bar.log</code> will be copied to
- <code>/foo/bar.log.2001-03</code>. Logging for the month of April
- will be output to <code>/foo/bar.log</code> until it rolls over
- at the beginning of May.
+ <td>At midnight of May 31st, 2002 <code>/foo/bar.log</code> will be
+ copied to <code>/foo/bar.log.2002-05</code>. Logging for the month
+ of June will be output to <code>/foo/bar.log</code> until it is
+ also rolled over the next month.
<tr>
<td><code>'.'yyyy-ww</code>
@@ -64,18 +63,19 @@ import org.apache.log4j.spi.LoggingEvent;
<td>Rollover at the first day of each week. The first day of the
week depends on the locale.</td>
- <td>At midnight, on March 31st, 2001, <code>/foo/bar.log</code>
- will be copied to <code>/foo/bar.log.2001-08</code>. Logging for
- the 9th week of 2001 will be output to <code>/foo/bar.log</code>
- until it is rolled over the next week.
+ <td>Assuming the first day of the week is Sunday, on Saturday
+ midnight, June 9th 2002, the file <i>/foo/bar.log</i> will be
+ copied to <i>/foo/bar.log.2002-23</i>. Logging for the 24th week
+ of 2002 will be output to <code>/foo/bar.log</code> until it is
+ rolled over the next week.
<tr>
<td><code>'.'yyyy-MM-dd</code>
<td>Rollover at midnight each day.</td>
- <td>At midnight, on March 9th, 2001, <code>/foo/bar.log</code> will
- be copied to <code>/foo/bar.log.2001-03-08</code>. Logging for the
+ <td>At midnight, on March 8th, 2002, <code>/foo/bar.log</code> will
+ be copied to <code>/foo/bar.log.2002-03-08</code>. Logging for the
9th day of March will be output to <code>/foo/bar.log</code> until
it is rolled over the next day.
@@ -84,19 +84,19 @@ import org.apache.log4j.spi.LoggingEvent;
<td>Rollover at midnight and midday of each day.</td>
- <td>At noon, on March 9th, 2001, <code>/foo/bar.log</code> will be
- copied to <code>/foo/bar.log.2001-03-09-AM</code>. Logging for the
+ <td>At noon, on March 9th, 2002, <code>/foo/bar.log</code> will be
+ copied to <code>/foo/bar.log.2002-03-09-AM</code>. Logging for the
afternoon of the 9th will be output to <code>/foo/bar.log</code>
- until it is rolled over the next morning, i.e at midnight 00:00.
+ until it is rolled over at midnight.
<tr>
<td><code>'.'yyyy-MM-dd-HH</code>
<td>Rollover at the top of every hour.</td>
- <td>At approximately 11:00,000, on March 9th, 2001,
+ <td>At approximately 11:00.000 o'clock on March 9th, 2002,
<code>/foo/bar.log</code> will be copied to
- <code>/foo/bar.log.2001-03-09-10</code>. Logging for the 11th hour
+ <code>/foo/bar.log.2002-03-09-10</code>. Logging for the 11th hour
of the 9th of March will be output to <code>/foo/bar.log</code>
until it is rolled over at the beginning of the next hour.
@@ -143,13 +143,19 @@ public class DailyRollingFileAppender extends FileAppender {
private String datePattern = "'.'yyyy-MM-dd";
/**
- The actual formatted filename that is currently being written to.
+ The log file will be renamed to the value of the
+ scheduledFilename variable when the next interval is entered. For
+ example, if the rollover period is one hour, the log file will be
+ renamed to the value of "scheduledFilename" at the beginning of
+ the next hour.
+
+ The precise time when a rollover occurs depends on logging
+ activity.
*/
private String scheduledFilename;
/**
- The timestamp when we shall next recompute the filename.
- */
+ The next time we estimate a rollover should occur. */
private long nextCheck = System.currentTimeMillis () - 1;
Date now = new Date();
@@ -160,14 +166,13 @@ public class DailyRollingFileAppender extends FileAppender {
int checkPeriod = TOP_OF_TROUBLE;
-
+ // The gmtTimeZone is used only in computeCheckPeriod() method.
static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
/**
The default constructor does nothing. */
- public
- DailyRollingFileAppender() {
+ public DailyRollingFileAppender() {
}
/**
@@ -188,19 +193,16 @@ public class DailyRollingFileAppender extends FileAppender {
expected by {@link SimpleDateFormat}. This options determines the
rollover schedule.
*/
- public
- void setDatePattern(String pattern) {
+ public void setDatePattern(String pattern) {
datePattern = pattern;
}
/** Returns the value of the <b>DatePattern</b> option. */
- public
- String getDatePattern() {
+ public String getDatePattern() {
return datePattern;
}
- public
- void activateOptions() {
+ public void activateOptions() {
super.activateOptions();
if(datePattern != null && fileName != null) {
now.setTime(System.currentTimeMillis());
@@ -212,8 +214,8 @@ public class DailyRollingFileAppender extends FileAppender {
scheduledFilename = fileName+sdf.format(new Date(file.lastModified()));
} else {
- LogLog.error("Either Filename or DatePattern options are not set for ["+
- name+"].");
+ LogLog.error("Either File or DatePattern options are not set for appender ["
+ +name+"].");
}
}
@@ -290,6 +292,9 @@ public class DailyRollingFileAppender extends FileAppender {
}
String datedFilename = fileName+sdf.format(now);
+ // It is too early to roll over because we are still within the
+ // bounds of the current interval. Rollover will occur once the
+ // next interval is reached.
if (scheduledFilename.equals(datedFilename)) {
return;
}
@@ -303,8 +308,12 @@ public class DailyRollingFileAppender extends FileAppender {
}
File file = new File(fileName);
- file.renameTo(target);
- LogLog.debug(fileName +" -> "+ scheduledFilename);
+ boolean result = file.renameTo(target);
+ if(result) {
+ LogLog.debug(fileName +" -> "+ scheduledFilename);
+ } else {
+ LogLog.error("Failed to rename ["+fileName+"] to ["+scheduledFilename+"].");
+ }
try {
// This will also close the file. This is OK since multiple
@@ -318,17 +327,14 @@ public class DailyRollingFileAppender extends FileAppender {
}
/**
- This method differentiates DailyRollingFileAppender from its
- super class.
-
- <p>Before actually logging, this method will check whether it is
- time to do a rollover. If it is, it will schedule the next
- rollover time and then rollover.
-
-
- */
- protected
- void subAppend(LoggingEvent event) {
+ * This method differentiates DailyRollingFileAppender from its
+ * super class.
+ *
+ * <p>Before actually logging, this method will check whether it is
+ * time to do a rollover. If it is, it will schedule the next
+ * rollover time and then rollover.
+ * */
+ protected void subAppend(LoggingEvent event) {
long n = System.currentTimeMillis();
if (n >= nextCheck) {
now.setTime(n);
@@ -345,16 +351,10 @@ public class DailyRollingFileAppender extends FileAppender {
}
/**
- RollingCalendar is a helper class to
- DailyRollingFileAppender. Using this class, it is easy to compute
- and access the next Millis().
-
- It subclasses the standard {@link GregorianCalendar}-object, to
- allow access to the protected function getTimeInMillis(), which it
- then exports.
-
- @author <a HREF="mailto:eirik.lygre@evita.no">Eirik Lygre</a> */
-
+ * RollingCalendar is a helper class to DailyRollingFileAppender.
+ * Given a periodicity type and the current time, it computes the
+ * start of the next interval.
+ * */
class RollingCalendar extends GregorianCalendar {
int type = DailyRollingFileAppender.TOP_OF_TROUBLE;
@@ -371,13 +371,11 @@ class RollingCalendar extends GregorianCalendar {
this.type = type;
}
- public
- long getNextCheckMillis(Date now) {
+ public long getNextCheckMillis(Date now) {
return getNextCheckDate(now).getTime();
}
- public
- Date getNextCheckDate(Date now) {
+ public Date getNextCheckDate(Date now) {
this.setTime(now);
switch(type) {
diff --git a/src/java/org/apache/log4j/FileAppender.java b/src/java/org/apache/log4j/FileAppender.java
index e3b212e..c1de794 100644
--- a/src/java/org/apache/log4j/FileAppender.java
+++ b/src/java/org/apache/log4j/FileAppender.java
@@ -20,24 +20,24 @@ import org.apache.log4j.helpers.LogLog;
// Ben Sandee
/**
- FileAppender appends log events to a file.
-
- <p>Support for <code>java.io.Writer</code> and console appending
- has been deprecated and then removed. See the replacement
- solutions: {@link WriterAppender} and {@link ConsoleAppender}.
-
-
- @author Ceki Gülcü */
+ * FileAppender appends log events to a file.
+ *
+ * <p>Support for <code>java.io.Writer</code> and console appending
+ * has been deprecated and then removed. See the replacement
+ * solutions: {@link WriterAppender} and {@link ConsoleAppender}.
+ *
+ * @author Ceki Gülcü
+ * */
public class FileAppender extends WriterAppender {
- /** Append to or truncate the file? The default value for this
- variable is <code>true</code>, meaning that by default a
- <code>FileAppender</code> will append to an existing file and
- not truncate it.
-
- <p>This option is meaningful only if the FileAppender opens the
- file.
- */
+ /** Controls file truncatation. The default value for this variable
+ * is <code>true</code>, meaning that by default a
+ * <code>FileAppender</code> will append to an existing file and not
+ * truncate it.
+ *
+ * <p>This option is meaningful only if the FileAppender opens the
+ * file.
+ */
protected boolean fileAppend = true;
/**
@@ -49,7 +49,8 @@ public class FileAppender extends WriterAppender {
protected boolean bufferedIO = false;
/**
- How big should the IO buffer be? Default is 8K. */
+ * Determines the size of IO buffer be. Default is 8K.
+ */
protected int bufferSize = 8*1024;
diff --git a/src/java/org/apache/log4j/HTMLLayout.java b/src/java/org/apache/log4j/HTMLLayout.java
index 013b7c5..961c301 100644
--- a/src/java/org/apache/log4j/HTMLLayout.java
+++ b/src/java/org/apache/log4j/HTMLLayout.java
@@ -130,22 +130,22 @@ public class HTMLLayout extends Layout {
sbuf.append("</td>" + Layout.LINE_SEP);
sbuf.append("<td title=\"Level\">");
- if (event.level.equals(Level.DEBUG)) {
+ if (event.getLevel().equals(Level.DEBUG)) {
sbuf.append("<font color=\"#339933\">");
- sbuf.append(event.level);
+ sbuf.append(event.getLevel());
sbuf.append("</font>");
}
- else if(event.level.isGreaterOrEqual(Level.WARN)) {
+ else if(event.getLevel().isGreaterOrEqual(Level.WARN)) {
sbuf.append("<font color=\"#993300\"><strong>");
- sbuf.append(event.level);
+ sbuf.append(event.getLevel());
sbuf.append("</strong></font>");
} else {
- sbuf.append(event.level);
+ sbuf.append(event.getLevel());
}
sbuf.append("</td>" + Layout.LINE_SEP);
- sbuf.append("<td title=\"" + event.categoryName + " category\">");
- sbuf.append(Transform.escapeTags(event.categoryName));
+ sbuf.append("<td title=\"" + event.getLoggerName() + " category\">");
+ sbuf.append(Transform.escapeTags(event.getLoggerName()));
sbuf.append("</td>" + Layout.LINE_SEP);
if(locationInfo) {
diff --git a/src/java/org/apache/log4j/LogManager.java b/src/java/org/apache/log4j/LogManager.java
index 0189b8a..d01b99e 100644
--- a/src/java/org/apache/log4j/LogManager.java
+++ b/src/java/org/apache/log4j/LogManager.java
@@ -11,7 +11,7 @@ import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggerFactory;
import org.apache.log4j.spi.RepositorySelector;
import org.apache.log4j.spi.DefaultRepositorySelector;
-import org.apache.log4j.spi.RootCategory;
+import org.apache.log4j.spi.RootLogger;
import org.apache.log4j.helpers.Loader;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.helpers.LogLog;
@@ -23,84 +23,40 @@ import java.net.MalformedURLException;
import java.util.Enumeration;
/**
- Use the <code>LogManager</code> to retreive instances of {@link Logger}.
-
- @author Ceki Gülcü
-*/
+ * Use the <code>LogManager</code> class to retreive {@link Logger}
+ * instances or to operate on the current {@link
+ * LoggerRepository}. When the <code>LogManager</code> class is loaded
+ * into memory the default initalzation procedure is inititated. The
+ * default intialization procedure</a> is described in the <a
+ * href="../../../../manual.html#defaultInit">short log4j manual</a>.
+ *
+ * @author Ceki Gülcü */
public class LogManager {
/**
- This string constant is set to <b>log4j.properties</b> the name
- of the file that will be searched by default in classpath. If the
- file can be found, then it is fed to the {@link
- PropertyConfigurator}.
-
- See also {@link #DEFAULT_CONFIGURATION_KEY} for a more general
- alternative.
-
- <p>See also the full description of <a
- href="../../../../manual.html#defaultInit">default
- intialization</a> procedure.
-
- @since 0.8.5 */
- static public final String DEFAULT_CONFIGURATION_FILE = "log4j.properties";
-
- /**
- This string constant is set to <b>log4j.configuration</b>.
-
- <p>It corresponds to name of a system property that, if set,
- specifies the name of the resource containing the properties file
- or {@link URL} with which log4j should configure itself. See
- {@link OptionConverter#selectAndConfigure} for more detailed
- information on the processing of this option.
-
- <p>Setting the <b>log4j.configuration</b> system property
- overrides the default search for the file <b>log4j.properties</b>.
-
- <p>Note that all property keys are case sensitive.
-
- <p>See also the full description of <a
- href="../../../../manual.html#defaultInit">default
- intialization</a> procedure.
-
- @since 1.0 */
- static final public String DEFAULT_CONFIGURATION_KEY="log4j.configuration";
-
- /**
- This string constant is set to <b>log4j.configuratorClass</b>.
-
- <p>It corresponds to name of a system property that, if set,
- specifies the class name to use to automatically configure
- log4j. See {@link OptionConverter#selectAndConfigure} for more
- detailed information on the processing of this option.
-
- <p>Setting the <b>log4j.configuration</b> system property
- overrides the default search for the file <b>log4j.properties</b>.
-
- <p>Note that all property keys are case sensitive.
-
- <p>See also the full description of <a
- href="../../../../manual.html#defaultInit">default
- intialization</a> procedure.
+ * @deprecated This variable is for internal use only. It will
+ * become package protected in future versions.
+ * */
+ static public final String DEFAULT_CONFIGURATION_FILE = "log4j.properties";
+
+ static final String DEFAULT_XML_CONFIGURATION_FILE = "log4j.xml";
- @since 1.2 */
- static final public String CONFIGURATOR_CLASS_KEY="log4j.configuratorClass";
-
/**
- Setting the system property <b>log4j.defaultInitOverride</b> to
- "true" or any other value than "false" will skip default
- configuration process.
-
- <p>The current value of the DEFAULT_INIT_OVERRIDE_KEY string
- constant is <b>log4j.defaultInitOverride</b>.
-
- <p>See also the full description of <a
- href="../../../../manual.html#defaultInit">default
- intialization</a> procedure.
+ * @deprecated This variable is for internal use only. It will
+ * become private in future versions.
+ * */
+ static final public String DEFAULT_CONFIGURATION_KEY="log4j.configuration";
- <p>Note that all property keys are case sensitive.
+ /**
+ * @deprecated This variable is for internal use only. It will
+ * become private in future versions.
+ * */
+ static final public String CONFIGURATOR_CLASS_KEY="log4j.configuratorClass";
- @since 0.8.5 */
+ /**
+ * @deprecated This variable is for internal use only. It will
+ * become private in future versions.
+ */
public static final String DEFAULT_INIT_OVERRIDE_KEY =
"log4j.defaultInitOverride";
@@ -110,42 +66,54 @@ public class LogManager {
static {
// By default we use a DefaultRepositorySelector which always returns 'h'.
- Hierarchy h = new Hierarchy(new RootCategory((Level) Level.DEBUG));
+ Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG));
repositorySelector = new DefaultRepositorySelector(h);
/** Search for the properties file log4j.properties in the CLASSPATH. */
String override =OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY,
null);
- // if there is no default init override, them get the resource
+ // if there is no default init override, then get the resource
// specified by the user or the default config file.
if(override == null || "false".equalsIgnoreCase(override)) {
- String resource = OptionConverter.getSystemProperty(
- DEFAULT_CONFIGURATION_KEY,
- DEFAULT_CONFIGURATION_FILE);
+
+ String configurationOptionStr = OptionConverter.getSystemProperty(
+ DEFAULT_CONFIGURATION_KEY,
+ null);
String configuratorClassName = OptionConverter.getSystemProperty(
CONFIGURATOR_CLASS_KEY,
null);
URL url = null;
- try {
- // so, resource is not a URL:
- // attempt to get the resource from the class path
- url = new URL(resource);
- } catch (MalformedURLException ex) {
- url = Loader.getResource(resource);
- }
+
+ // if the user has not specified the log4j.configuration
+ // property, we search first for the file "log4j.xml" and then
+ // "log4j.properties"
+ if(configurationOptionStr == null) {
+ url = Loader.getResource(DEFAULT_XML_CONFIGURATION_FILE);
+ if(url == null) {
+ url = Loader.getResource(DEFAULT_CONFIGURATION_FILE);
+ }
+ } else {
+ try {
+ url = new URL(configurationOptionStr);
+ } catch (MalformedURLException ex) {
+ // so, resource is not a URL:
+ // attempt to get the resource from the class path
+ url = Loader.getResource(configurationOptionStr);
+ }
+ }
// If we have a non-null url, then delegate the rest of the
// configuration to the OptionConverter.selectAndConfigure
// method.
if(url != null) {
- LogLog.debug("Using URL ["+url+"] for automatic log4j configuration.");
+ LogLog.debug("Using URL ["+url+"] for automatic log4j configuration.");
OptionConverter.selectAndConfigure(url, configuratorClassName,
LogManager.getLoggerRepository());
} else {
- LogLog.debug("Could not find resource: ["+resource+"].");
+ LogLog.debug("Could not find resource: ["+configurationOptionStr+"].");
}
}
}
diff --git a/src/java/org/apache/log4j/Logger.java b/src/java/org/apache/log4j/Logger.java
index aab789d..369d952 100644
--- a/src/java/org/apache/log4j/Logger.java
+++ b/src/java/org/apache/log4j/Logger.java
@@ -8,6 +8,7 @@
package org.apache.log4j;
import org.apache.log4j.spi.LoggerFactory;
+import org.slf4j.ULogger;
/**
@@ -17,7 +18,7 @@ import org.apache.log4j.spi.LoggerFactory;
@since log4j 1.2
@author Ceki Gülcü */
-public class Logger extends Category {
+public class Logger extends Category implements ULogger {
/**
The fully qualified name of the Level class. See also the
@@ -77,7 +78,16 @@ public class Logger extends Category {
//}
/**
- Retrieve a logger by name.
+ * Retrieve a logger named according to the value of the
+ * <code>name</code> parameter. If the named logger already exists,
+ * then the existing instance will be returned. Otherwise, a new
+ * instance is created.
+ *
+ * <p>By default, loggers do not have a set level but inherit it
+ * from their neareast ancestor with a set level. This is one of the
+ * central features of log4j.
+ *
+ * @param name The name of the logger to retrieve.
*/
static
public
@@ -86,7 +96,11 @@ public class Logger extends Category {
}
/**
- Same as calling <code>getLogger(clazz.getName())</code>.
+ * Shorthand for <code>getLogger(clazz.getName())</code>.
+ *
+ * @param clazz The name of <code>clazz</code> will be used as the
+ * name of the logger to retrieve. See {@link #getLogger(String)}
+ * for more detailed information.
*/
static
public
@@ -96,7 +110,15 @@ public class Logger extends Category {
/**
- Retrieve the root logger.
+ * Return the root logger for the current logger repository.
+ * <p>
+ * The {@link #getName Logger.getName()} method for the root logger always returns
+ * stirng value: "root". However, calling
+ * <code>Logger.getLogger("root")</code> does not retrieve the root
+ * logger but a logger just under root named "root".
+ * <p>
+ * In other words, calling this method is the only way to retrieve the
+ * root logger.
*/
public
static
diff --git a/src/java/org/apache/log4j/MDC.java b/src/java/org/apache/log4j/MDC.java
index 002b399..9fd93ff 100644
--- a/src/java/org/apache/log4j/MDC.java
+++ b/src/java/org/apache/log4j/MDC.java
@@ -88,11 +88,10 @@ public class MDC {
/**
- Get the current thread's MDC as a hashtable.
- */
- public
- static
- Hashtable getContext() {
+ * Get the current thread's MDC as a hashtable. This method is
+ * intended to be used internally.
+ * */
+ public static Hashtable getContext() {
return mdc.getContext0();
}
@@ -104,8 +103,8 @@ public class MDC {
} else {
Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
if(ht == null) {
- ht = new Hashtable(HT_SIZE);
- ((ThreadLocalMap)tlm).set(ht);
+ ht = new Hashtable(HT_SIZE);
+ ((ThreadLocalMap)tlm).set(ht);
}
ht.put(key, o);
}
@@ -117,10 +116,10 @@ public class MDC {
return null;
} else {
Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
- if(ht != null) {
- return ht.get(key);
+ if(ht != null && key != null) {
+ return ht.get(key);
} else {
- return null;
+ return null;
}
}
}
@@ -130,7 +129,7 @@ public class MDC {
if(!java1) {
Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
if(ht != null) {
- ht.remove(key);
+ ht.remove(key);
}
}
}
diff --git a/src/java/org/apache/log4j/NDC.java b/src/java/org/apache/log4j/NDC.java
index aa44615..ee34b21 100644
--- a/src/java/org/apache/log4j/NDC.java
+++ b/src/java/org/apache/log4j/NDC.java
@@ -192,7 +192,8 @@ public class NDC {
/**
- Used when printing the diagnostic context.
+ <font color="#FF4040"><b>Never use this method directly, use the {@link
+ org.apache.log4j.spi.LoggingEvent#getNDC} method instead</b></font>.
*/
static
public
@@ -205,10 +206,10 @@ public class NDC {
}
/**
- Get the current nesting depth of this diagnostic context.
-
- @see #setMaxDepth
- @since 0.7.5
+ * Get the current nesting depth of this diagnostic context.
+ *
+ * @see #setMaxDepth
+ * @since 0.7.5
*/
public
static
@@ -239,13 +240,13 @@ public class NDC {
int misses = 0;
v = new Vector();
- Enumeration enum = ht.keys();
+ Enumeration enumeration = ht.keys();
// We give up after 4 straigt missses. That is 4 consecutive
// inspected threads in 'ht' that turn out to be alive.
// The higher the proportion on dead threads in ht, the higher the
// chances of removal.
- while(enum.hasMoreElements() && (misses <= 4)) {
- Thread t = (Thread) enum.nextElement();
+ while(enumeration.hasMoreElements() && (misses <= 4)) {
+ Thread t = (Thread) enumeration.nextElement();
if(t.isAlive()) {
misses++;
} else {
diff --git a/src/java/org/apache/log4j/Priority.java b/src/java/org/apache/log4j/Priority.java
index fd2fe98..61e82a4 100644
--- a/src/java/org/apache/log4j/Priority.java
+++ b/src/java/org/apache/log4j/Priority.java
@@ -9,10 +9,10 @@
// Contributors: Kitching Simon <Si...@orange.ch>
package org.apache.log4j;
-
+
/**
<font color="#AA4444">Refrain from using this class directly, use
- the {@link Level} class instead.</font>
+ the {@link Level} class instead</font>.
@author Ceki Gülcü */
public class Priority {
@@ -31,31 +31,28 @@ public class Priority {
public final static int ALL_INT = Integer.MIN_VALUE;
/**
- The <code>FATAL</code> level designates very severe error
- events that will presumably lead the application to abort.
+ * @deprecated Use {@link Level#FATAL} instead.
*/
final static public Priority FATAL = new Level(FATAL_INT, "FATAL", 0);
/**
- The <code>ERROR</code> level designates error events that
- might still allow the application to continue running. */
+ * @deprecated Use {@link Level#ERROR} instead.
+ */
final static public Priority ERROR = new Level(ERROR_INT, "ERROR", 3);
/**
- The <code>WARN</code> level designates potentially harmful situations.
- */
+ * @deprecated Use {@link Level#WARN} instead.
+ */
final static public Priority WARN = new Level(WARN_INT, "WARN", 4);
/**
- The <code>INFO</code> level designates informational messages
- that highlight the progress of the application at coarse-grained
- level. */
+ * @deprecated Use {@link Level#INFO} instead.
+ */
final static public Priority INFO = new Level(INFO_INT, "INFO", 6);
/**
- The <code>DEBUG</code> priority designates fine-grained
- informational events that are most useful to debug an
- application. */
+ * @deprecated Use {@link Level#DEBUG} instead.
+ */
final static public Priority DEBUG = new Level(DEBUG_INT, "DEBUG", 7);
@@ -141,12 +138,7 @@ public class Priority {
}
/**
- Convert the string passed as argument to a priority. If the
- conversion fails, then this method returns {@link #DEBUG}.
-
- @deprecated Please use the {@link Level#toLevel(String)} method instead.}
-
-
+ * @deprecated Please use the {@link Level#toLevel(String)} method instead.
*/
public
static
@@ -155,10 +147,8 @@ public class Priority {
}
/**
- Convert an integer passed as argument to a priority. If the
- conversion fails, then this method returns {@link #DEBUG}.
-
- */
+ * @deprecated Please use the {@link Level#toLevel(int)} method instead.
+ */
public
static
Priority toPriority(int val) {
@@ -166,8 +156,7 @@ public class Priority {
}
/**
- Convert an integer passed as argument to a priority. If the
- conversion fails, then this method returns the specified default.
+ * @deprecated Please use the {@link Level#toLevel(int, Level)} method instead.
*/
public
static
@@ -176,10 +165,8 @@ public class Priority {
}
/**
- Convert the string passed as argument to a priority. If the
- conversion fails, then this method returns the value of
- <code>defaultPriority</code>.
- */
+ * @deprecated Please use the {@link Level#toLevel(String, Level)} method instead.
+ */
public
static
Priority toPriority(String sArg, Priority defaultPriority) {
diff --git a/src/java/org/apache/log4j/PropertyConfigurator.java b/src/java/org/apache/log4j/PropertyConfigurator.java
index c15d438..b6b99b6 100644
--- a/src/java/org/apache/log4j/PropertyConfigurator.java
+++ b/src/java/org/apache/log4j/PropertyConfigurator.java
@@ -33,8 +33,8 @@ import java.util.StringTokenizer;
import java.util.Hashtable;
/**
- Extends {@link BasicConfigurator} to provide configuration from an
- external file. See <b>{@link #doConfigure(String, LoggerRepository)}</b> for the
+ Allows the configuration of log4j from an external file. See
+ <b>{@link #doConfigure(String, LoggerRepository)}</b> for the
expected format.
<p>It is sometimes useful to see how log4j is reading configuration
@@ -100,7 +100,7 @@ public class PropertyConfigurator implements Configurator {
/**
Read configuration from a file. <b>The existing configuration is
not cleared nor reset.</b> If you require a different behavior,
- then call {@link BasicConfigurator#resetConfiguration
+ then call {@link LogManager#resetConfiguration
resetConfiguration} method before calling
<code>doConfigure</code>.
@@ -118,7 +118,7 @@ public class PropertyConfigurator implements Configurator {
</pre>
<p>The level value can consist of the string values OFF, FATAL,
- ERROR, WARN, INFO, DEBUG, ALL or a <em>custom level</e> value. A
+ ERROR, WARN, INFO, DEBUG, ALL or a <em>custom level</em> value. A
custom level value can be specified in the form
level#classname. By default the repository-wide threshold is set
to the lowest possible value, namely the level <code>ALL</code>.
@@ -175,7 +175,7 @@ public class PropertyConfigurator implements Configurator {
<p>For non-root categories the syntax is almost the same:
<pre>
- log4j.logger.logger_name=[level|INHERITED], appenderName, appenderName, ...
+ log4j.logger.logger_name=[level|INHERITED|NULL], appenderName, appenderName, ...
</pre>
<p>The meaning of the optional level value is discussed above
@@ -187,9 +187,10 @@ public class PropertyConfigurator implements Configurator {
named logger remains untouched.
<p>By default categories inherit their level from the
- hierarchy. However, if you set the level of a logger and
- later decide that that logger should inherit its level, then
- you should specify INHERITED as the value for the level value.
+ hierarchy. However, if you set the level of a logger and later
+ decide that that logger should inherit its level, then you should
+ specify INHERITED as the value for the level value. NULL is a
+ synonym for INHERITED.
<p>Similar to the root logger syntax, each <i>appenderName</i>
(separated by commas) will be attached to the named logger.
@@ -507,9 +508,9 @@ public class PropertyConfigurator implements Configurator {
*/
protected
void parseCatsAndRenderers(Properties props, LoggerRepository hierarchy) {
- Enumeration enum = props.propertyNames();
- while(enum.hasMoreElements()) {
- String key = (String) enum.nextElement();
+ Enumeration enumeration = props.propertyNames();
+ while(enumeration.hasMoreElements()) {
+ String key = (String) enumeration.nextElement();
if(key.startsWith(CATEGORY_PREFIX) || key.startsWith(LOGGER_PREFIX)) {
String loggerName = null;
if(key.startsWith(CATEGORY_PREFIX)) {
@@ -576,9 +577,13 @@ public class PropertyConfigurator implements Configurator {
// If the level value is inherited, set category level value to
// null. We also check that the user has not specified inherited for the
// root category.
- if(levelStr.equalsIgnoreCase(INHERITED) &&
- !loggerName.equals(INTERNAL_ROOT_NAME)) {
- logger.setLevel(null);
+ if(INHERITED.equalsIgnoreCase(levelStr) ||
+ NULL.equalsIgnoreCase(levelStr)) {
+ if(loggerName.equals(INTERNAL_ROOT_NAME)) {
+ LogLog.warn("The root logger cannot be set to null.");
+ } else {
+ logger.setLevel(null);
+ }
} else {
logger.setLevel(OptionConverter.toLevel(levelStr, (Level) Level.DEBUG));
}
diff --git a/src/java/org/apache/log4j/SimpleLayout.java b/src/java/org/apache/log4j/SimpleLayout.java
index 565ca54..8c58eeb 100644
--- a/src/java/org/apache/log4j/SimpleLayout.java
+++ b/src/java/org/apache/log4j/SimpleLayout.java
@@ -49,7 +49,7 @@ public class SimpleLayout extends Layout {
String format(LoggingEvent event) {
sbuf.setLength(0);
- sbuf.append(event.level.toString());
+ sbuf.append(event.getLevel().toString());
sbuf.append(" - ");
sbuf.append(event.getRenderedMessage());
sbuf.append(LINE_SEP);
diff --git a/src/java/org/apache/log4j/TTCCLayout.java b/src/java/org/apache/log4j/TTCCLayout.java
index 5ce94e6..ceb526a 100644
--- a/src/java/org/apache/log4j/TTCCLayout.java
+++ b/src/java/org/apache/log4j/TTCCLayout.java
@@ -157,9 +157,7 @@ public class TTCCLayout extends DateLayout {
<p>Time, thread, category and diagnostic context are printed
depending on options.
- @param category
- @param level
- @param message
+ @param event The event to format
*/
public
@@ -175,11 +173,11 @@ public class TTCCLayout extends DateLayout {
buf.append(event.getThreadName());
buf.append("] ");
}
- buf.append(event.level.toString());
+ buf.append(event.getLevel().toString());
buf.append(' ');
if(this.categoryPrefixing) {
- buf.append(event.categoryName);
+ buf.append(event.getLoggerName());
buf.append(' ');
}
diff --git a/src/java/org/apache/log4j/WriterAppender.java b/src/java/org/apache/log4j/WriterAppender.java
index 50b33f4..456d35b 100644
--- a/src/java/org/apache/log4j/WriterAppender.java
+++ b/src/java/org/apache/log4j/WriterAppender.java
@@ -194,17 +194,18 @@ public class WriterAppender extends AppenderSkeleton {
writeFooter();
reset();
}
+
/**
- Close the underlying {@link java.io.Writer}.
- */
- protected
- void closeWriter() {
+ * Close the underlying {@link java.io.Writer}.
+ * */
+ protected void closeWriter() {
if(qw != null) {
try {
qw.close();
} catch(IOException e) {
- LogLog.error("Could not close " + qw, e); // do need to invoke an error handler
- // at this late stage
+ // There is do need to invoke an error handler at this late
+ // stage.
+ LogLog.error("Could not close " + qw, e);
}
}
}
@@ -234,13 +235,11 @@ public class WriterAppender extends AppenderSkeleton {
return retval;
}
- public
- String getEncoding() {
+ public String getEncoding() {
return encoding;
}
- public
- void setEncoding(String value) {
+ public void setEncoding(String value) {
encoding = value;
}
@@ -250,9 +249,7 @@ public class WriterAppender extends AppenderSkeleton {
/**
Set the {@link ErrorHandler} for this WriterAppender and also the
underlying {@link QuietWriter} if any. */
- public
- synchronized
- void setErrorHandler(ErrorHandler eh) {
+ public synchronized void setErrorHandler(ErrorHandler eh) {
if(eh == null) {
LogLog.warn("You have tried to set a null error-handler.");
} else {
@@ -275,9 +272,7 @@ public class WriterAppender extends AppenderSkeleton {
<p><b>WARNING:</b> Logging to an unopened Writer will fail.
<p>
@param writer An already opened Writer. */
- public
- synchronized
- void setWriter(Writer writer) {
+ public synchronized void setWriter(Writer writer) {
reset();
this.qw = new QuietWriter(writer, errorHandler);
//this.tp = new TracerPrintWriter(qw);
diff --git a/src/java/org/apache/log4j/chainsaw/ControlPanel.java b/src/java/org/apache/log4j/chainsaw/ControlPanel.java
index 741edec..d9169e7 100644
--- a/src/java/org/apache/log4j/chainsaw/ControlPanel.java
+++ b/src/java/org/apache/log4j/chainsaw/ControlPanel.java
@@ -18,7 +18,7 @@ import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
-import org.apache.log4j.Category;
+import org.apache.log4j.Logger;
import org.apache.log4j.Priority;
/**
@@ -28,8 +28,8 @@ import org.apache.log4j.Priority;
*/
class ControlPanel extends JPanel {
/** use the log messages **/
- private static final Category LOG =
- Category.getInstance(ControlPanel.class);
+ private static final Logger LOG =
+ Logger.getLogger(ControlPanel.class);
/**
* Creates a new <code>ControlPanel</code> instance.
@@ -61,7 +61,7 @@ class ControlPanel extends JPanel {
add(label);
c.gridy++;
- label = new JLabel("Filter Category:");
+ label = new JLabel("Filter Logger:");
gridbag.setConstraints(label, c);
add(label);
diff --git a/src/java/org/apache/log4j/chainsaw/DetailPanel.java b/src/java/org/apache/log4j/chainsaw/DetailPanel.java
index c051987..9b28748 100644
--- a/src/java/org/apache/log4j/chainsaw/DetailPanel.java
+++ b/src/java/org/apache/log4j/chainsaw/DetailPanel.java
@@ -17,7 +17,7 @@ import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
-import org.apache.log4j.Category;
+import org.apache.log4j.Logger;
/**
* A panel for showing a stack trace.
@@ -29,8 +29,8 @@ class DetailPanel
implements ListSelectionListener
{
/** used to log events **/
- private static final Category LOG =
- Category.getInstance(DetailPanel.class);
+ private static final Logger LOG =
+ Logger.getLogger(DetailPanel.class);
/** used to format the logging event **/
private static final MessageFormat FORMATTER = new MessageFormat(
@@ -38,7 +38,7 @@ class DetailPanel
" <b>Priority:</b> <code>{1}</code>" +
" <b>Thread:</b> <code>{2}</code>" +
" <b>NDC:</b> <code>{3}</code>" +
- "<br><b>Category:</b> <code>{4}</code>" +
+ "<br><b>Logger:</b> <code>{4}</code>" +
"<br><b>Location:</b> <code>{5}</code>" +
"<br><b>Message:</b>" +
"<pre>{6}</pre>" +
diff --git a/src/java/org/apache/log4j/chainsaw/EventDetails.java b/src/java/org/apache/log4j/chainsaw/EventDetails.java
index 12ddc51..a0538e6 100644
--- a/src/java/org/apache/log4j/chainsaw/EventDetails.java
+++ b/src/java/org/apache/log4j/chainsaw/EventDetails.java
@@ -73,8 +73,8 @@ class EventDetails {
EventDetails(LoggingEvent aEvent) {
this(aEvent.timeStamp,
- aEvent.level,
- aEvent.categoryName,
+ aEvent.getLevel(),
+ aEvent.getLoggerName(),
aEvent.getNDC(),
aEvent.getThreadName(),
aEvent.getRenderedMessage(),
diff --git a/src/java/org/apache/log4j/chainsaw/ExitAction.java b/src/java/org/apache/log4j/chainsaw/ExitAction.java
index 8fb0ce8..c8eda2a 100644
--- a/src/java/org/apache/log4j/chainsaw/ExitAction.java
+++ b/src/java/org/apache/log4j/chainsaw/ExitAction.java
@@ -8,7 +8,7 @@ package org.apache.log4j.chainsaw;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
-import org.apache.log4j.Category;
+import org.apache.log4j.Logger;
/**
* Encapsulates the action to exit.
@@ -20,7 +20,7 @@ class ExitAction
extends AbstractAction
{
/** use to log messages **/
- private static final Category LOG = Category.getInstance(ExitAction.class);
+ private static final Logger LOG = Logger.getLogger(ExitAction.class);
/** The instance to share **/
public static final ExitAction INSTANCE = new ExitAction();
diff --git a/src/java/org/apache/log4j/chainsaw/LoadXMLAction.java b/src/java/org/apache/log4j/chainsaw/LoadXMLAction.java
index 9912e7d..cc91139 100644
--- a/src/java/org/apache/log4j/chainsaw/LoadXMLAction.java
+++ b/src/java/org/apache/log4j/chainsaw/LoadXMLAction.java
@@ -16,7 +16,7 @@ import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
-import org.apache.log4j.Category;
+import org.apache.log4j.Logger;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
@@ -31,8 +31,7 @@ class LoadXMLAction
extends AbstractAction
{
/** use to log messages **/
- private static final Category LOG =
- Category.getInstance(LoadXMLAction.class);
+ private static final Logger LOG = Logger.getLogger(LoadXMLAction.class);
/** the parent frame **/
private final JFrame mParent;
diff --git a/src/java/org/apache/log4j/chainsaw/LoggingReceiver.java b/src/java/org/apache/log4j/chainsaw/LoggingReceiver.java
index c69b3de..3cd3455 100644
--- a/src/java/org/apache/log4j/chainsaw/LoggingReceiver.java
+++ b/src/java/org/apache/log4j/chainsaw/LoggingReceiver.java
@@ -23,7 +23,7 @@ import org.apache.log4j.spi.LoggingEvent;
*/
class LoggingReceiver extends Thread {
/** used to log messages **/
- private static final Logger logger = Logger.getLogger(LoggingReceiver.class);
+ private static final Logger LOG = Logger.getLogger(LoggingReceiver.class);
/**
* Helper that actually processes a client connection. It receives events
@@ -46,7 +46,7 @@ class LoggingReceiver extends Thread {
/** loops getting the events **/
public void run() {
- logger.debug("Starting to get data");
+ LOG.debug("Starting to get data");
try {
final ObjectInputStream ois =
new ObjectInputStream(mClient.getInputStream());
@@ -55,19 +55,19 @@ class LoggingReceiver extends Thread {
mModel.addEvent(new EventDetails(event));
}
} catch (EOFException e) {
- logger.info("Reached EOF, closing connection");
+ LOG.info("Reached EOF, closing connection");
} catch (SocketException e) {
- logger.info("Caught SocketException, closing connection");
+ LOG.info("Caught SocketException, closing connection");
} catch (IOException e) {
- logger.warn("Got IOException, closing connection", e);
+ LOG.warn("Got IOException, closing connection", e);
} catch (ClassNotFoundException e) {
- logger.warn("Got ClassNotFoundException, closing connection", e);
+ LOG.warn("Got ClassNotFoundException, closing connection", e);
}
try {
mClient.close();
} catch (IOException e) {
- logger.warn("Error closing connection", e);
+ LOG.warn("Error closing connection", e);
}
}
}
@@ -93,19 +93,19 @@ class LoggingReceiver extends Thread {
/** Listens for client connections **/
public void run() {
- logger.info("Thread started");
+ LOG.info("Thread started");
try {
while (true) {
- logger.debug("Waiting for a connection");
+ LOG.debug("Waiting for a connection");
final Socket client = mSvrSock.accept();
- logger.debug("Got a connection from " +
+ LOG.debug("Got a connection from " +
client.getInetAddress().getHostName());
final Thread t = new Thread(new Slurper(client));
t.setDaemon(true);
t.start();
}
} catch (IOException e) {
- logger.error("Error in accepting connections, stopping.", e);
+ LOG.error("Error in accepting connections, stopping.", e);
}
}
}
diff --git a/src/java/org/apache/log4j/chainsaw/Main.java b/src/java/org/apache/log4j/chainsaw/Main.java
index b67a9ae..9dacd28 100644
--- a/src/java/org/apache/log4j/chainsaw/Main.java
+++ b/src/java/org/apache/log4j/chainsaw/Main.java
@@ -23,7 +23,7 @@ import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
-import org.apache.log4j.Category;
+import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
/**
@@ -41,7 +41,7 @@ public class Main
public static final String PORT_PROP_NAME = "chainsaw.port";
/** use to log messages **/
- private static final Category LOG = Category.getInstance(Main.class);
+ private static final Logger LOG = Logger.getLogger(Main.class);
/**
@@ -162,7 +162,7 @@ public class Main
/** initialise log4j **/
private static void initLog4J() {
final Properties props = new Properties();
- props.setProperty("log4j.rootCategory", "DEBUG, A1");
+ props.setProperty("log4j.rootLogger", "DEBUG, A1");
props.setProperty("log4j.appender.A1",
"org.apache.log4j.ConsoleAppender");
props.setProperty("log4j.appender.A1.layout",
diff --git a/src/java/org/apache/log4j/chainsaw/MyTableModel.java b/src/java/org/apache/log4j/chainsaw/MyTableModel.java
index d1af076..b0d8898 100644
--- a/src/java/org/apache/log4j/chainsaw/MyTableModel.java
+++ b/src/java/org/apache/log4j/chainsaw/MyTableModel.java
@@ -16,7 +16,7 @@ import java.util.SortedSet;
import java.util.TreeSet;
import javax.swing.table.AbstractTableModel;
import org.apache.log4j.Priority;
-import org.apache.log4j.Category;
+import org.apache.log4j.Logger;
/**
* Represents a list of <code>EventDetails</code> objects that are sorted on
@@ -29,8 +29,7 @@ class MyTableModel
{
/** used to log messages **/
- private static final Category LOG =
- Category.getInstance(MyTableModel.class);
+ private static final Logger LOG = Logger.getLogger(MyTableModel.class);
/** use the compare logging events **/
private static final Comparator MY_COMP = new Comparator()
diff --git a/src/java/org/apache/log4j/chainsaw/XMLFileHandler.java b/src/java/org/apache/log4j/chainsaw/XMLFileHandler.java
index 5ce82d0..5944da3 100644
--- a/src/java/org/apache/log4j/chainsaw/XMLFileHandler.java
+++ b/src/java/org/apache/log4j/chainsaw/XMLFileHandler.java
@@ -7,7 +7,7 @@
package org.apache.log4j.chainsaw;
import java.util.StringTokenizer;
-import org.apache.log4j.Priority;
+import org.apache.log4j.Level;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
... 11160 lines suppressed ...